diff --git a/Source/Scene/BillboardCollection.js b/Source/Scene/BillboardCollection.js index e25f71b87f46..dae5d958ccee 100644 --- a/Source/Scene/BillboardCollection.js +++ b/Source/Scene/BillboardCollection.js @@ -27,8 +27,8 @@ define([ '../Shaders/BillboardCollectionFS', '../Shaders/BillboardCollectionVS', './Billboard', - './BillboardRenderTechnique', './BlendingState', + './BlendOption', './HeightReference', './HorizontalOrigin', './SceneMode', @@ -62,8 +62,8 @@ define([ BillboardCollectionFS, BillboardCollectionVS, Billboard, - BillboardRenderTechnique, BlendingState, + BlendOption, HeightReference, HorizontalOrigin, SceneMode, @@ -135,9 +135,9 @@ define([ * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms each billboard from model to world coordinates. * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. * @param {Scene} [options.scene] Must be passed in for billboards that use the height reference property or will be depth tested against the globe. - * @param {BillboardRenderTechnique} [options.renderTechnique=BillboardRenderTechnique.OPAQUE_AND_TRANSLUCENT] The billboard rendering technique. The default + * @param {BlendOption} [options.blendOption=BlendOption.OPAQUE_AND_TRANSLUCENT] The billboard blending option. The default * is used for rendering both opaque and translucent billboards. However, if either all of the billboards are completely opaque or all are completely translucent, - * setting the technique to BillboardRenderTechnique.OPAQUE or BillboardRenderTechnique.TRANSLUCENT can improve performance by 2x. + * setting the technique to BillboardRenderTechnique.OPAQUE or BillboardRenderTechnique.TRANSLUCENT can improve performance by up to 2x. * * @performance For best performance, prefer a few collections, each with many billboards, to * many collections with only a few billboards each. Organize collections so that billboards @@ -276,14 +276,15 @@ define([ this.debugShowBoundingVolume = defaultValue(options.debugShowBoundingVolume, false); /** - * The billboard rendering technique. The default is used for rendering both opaque and translucent billboards. + * The billboard blending option. The default is used for rendering both opaque and translucent billboards. * However, if either all of the billboards are completely opaque or all are completely translucent, - * setting the technique to BillboardRenderTechnique.OPAQUE or BillboardRenderTechnique.TRANSLUCENT can improve performance by 2x. - * @type {BillboardRenderTechnique} - * @default BillboardRenderTechnique.OPAQUE_AND_TRANSLUCENT + * setting the technique to BillboardRenderTechnique.OPAQUE or BillboardRenderTechnique.TRANSLUCENT can improve + * performance by up to 2x. + * @type {BlendOption} + * @default BlendOption.OPAQUE_AND_TRANSLUCENT */ - this.renderTechnique = defaultValue(options.renderTechnique, BillboardRenderTechnique.OPAQUE_AND_TRANSLUCENT); - this._renderTechnique = undefined; + this.blendOption = defaultValue(options.blendOption, BlendOption.OPAQUE_AND_TRANSLUCENT); + this._blendOption = undefined; this._mode = SceneMode.SCENE3D; @@ -1444,10 +1445,10 @@ define([ } updateBoundingVolume(this, frameState, boundingVolume); - var techniqueChanged = this._renderTechnique !== this.renderTechnique; - this._renderTechnique = this.renderTechnique; + var blendOptionChanged = this._blendOption !== this.blendOption; + this._blendOption = this.blendOption; - if (techniqueChanged) { + if (blendOptionChanged) { this._rsOpaque = RenderState.fromCache({ depthTest : { enabled : true, @@ -1456,7 +1457,7 @@ define([ depthMask : true }); - if (this._renderTechnique === BillboardRenderTechnique.TRANSLUCENT || this._renderTechnique === BillboardRenderTechnique.OPAQUE_AND_TRANSLUCENT) { + if (this._blendOption === BlendOption.TRANSLUCENT || this._blendOption === BlendOption.OPAQUE_AND_TRANSLUCENT) { this._rsTranslucent = RenderState.fromCache({ depthTest : { enabled : true, @@ -1470,7 +1471,7 @@ define([ } } - if (techniqueChanged || + if (blendOptionChanged || (this._shaderRotation !== this._compiledShaderRotation) || (this._shaderAlignedAxis !== this._compiledShaderAlignedAxis) || (this._shaderScaleByDistance !== this._compiledShaderScaleByDistance) || @@ -1503,7 +1504,7 @@ define([ vs.defines.push('DISTANCE_DISPLAY_CONDITION'); } - if (this._renderTechnique === BillboardRenderTechnique.OPAQUE || this._renderTechnique === BillboardRenderTechnique.OPAQUE_AND_TRANSLUCENT) { + if (this._blendOption === BlendOption.OPAQUE || this._blendOption === BlendOption.OPAQUE_AND_TRANSLUCENT) { fs = new ShaderSource({ defines : ['OPAQUE'], sources : [BillboardCollectionFS] @@ -1520,7 +1521,7 @@ define([ this._sp = undefined; } - if (this._renderTechnique === BillboardRenderTechnique.TRANSLUCENT || this._renderTechnique === BillboardRenderTechnique.OPAQUE_AND_TRANSLUCENT) { + if (this._blendOption === BlendOption.TRANSLUCENT || this._blendOption === BlendOption.OPAQUE_AND_TRANSLUCENT) { fs = new ShaderSource({ defines : ['TRANSLUCENT'], sources : [BillboardCollectionFS] @@ -1612,8 +1613,8 @@ define([ if (pass.render) { var colorList = this._colorCommands; - var opaque = this._renderTechnique === BillboardRenderTechnique.OPAQUE; - var opaqueAndTranslucent = this._renderTechnique === BillboardRenderTechnique.OPAQUE_AND_TRANSLUCENT; + var opaque = this._blendOption === BlendOption.OPAQUE; + var opaqueAndTranslucent = this._blendOption === BlendOption.OPAQUE_AND_TRANSLUCENT; va = this._vaf.va; vaLength = va.length; diff --git a/Source/Scene/BillboardRenderTechnique.js b/Source/Scene/BlendOption.js similarity index 54% rename from Source/Scene/BillboardRenderTechnique.js rename to Source/Scene/BlendOption.js index 45c1b9b4d447..957ac696dbf5 100644 --- a/Source/Scene/BillboardRenderTechnique.js +++ b/Source/Scene/BlendOption.js @@ -6,32 +6,32 @@ define([ 'use strict'; /** - * Determines how billboards and points are rendered. + * Determines how billboards, points, and labels are rendered. * * @exports BillboardRenderTechnique */ - var BillboardRenderTechnique = { + var BlendOption = { /** - * The billboards in the collection are completely opaque. + * The billboards, points, or labels in the collection are completely opaque. * @type {Number} * @constant */ OPAQUE : 0, /** - * The billboards in the collection are completely translucent. + * The billboards, points, or labels in the collection are completely translucent. * @type {Number} * @constant */ TRANSLUCENT : 1, /** - * The billboards in the collection are both opaque and translucent. + * The billboards, points, or labels in the collection are both opaque and translucent. * @type {Number} * @constant */ OPAQUE_AND_TRANSLUCENT : 2 }; - return freezeObject(BillboardRenderTechnique); + return freezeObject(BlendOption); }); diff --git a/Source/Scene/LabelCollection.js b/Source/Scene/LabelCollection.js index f7416ffc40d7..af953981629f 100644 --- a/Source/Scene/LabelCollection.js +++ b/Source/Scene/LabelCollection.js @@ -11,6 +11,7 @@ define([ '../Core/Matrix4', '../Core/writeTextToCanvas', './BillboardCollection', + './BlendOption', './HorizontalOrigin', './Label', './LabelStyle', @@ -28,6 +29,7 @@ define([ Matrix4, writeTextToCanvas, BillboardCollection, + BlendOption, HorizontalOrigin, Label, LabelStyle, @@ -440,6 +442,9 @@ define([ * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms each label from model to world coordinates. * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. * @param {Scene} [options.scene] Must be passed in for labels that use the height reference property or will be depth tested against the globe. + * @param {BlendOption} [options.blendOption=BlendOption.OPAQUE_AND_TRANSLUCENT] The label blending option. The default + * is used for rendering both opaque and translucent labels. However, if either all of the labels are completely opaque or all are completely translucent, + * setting the technique to BillboardRenderTechnique.OPAQUE or BillboardRenderTechnique.TRANSLUCENT can improve performance by up to 2x. * * @performance For best performance, prefer a few collections, each with many labels, to * many collections with only a few labels each. Avoid having collections where some @@ -533,6 +538,16 @@ define([ * @default false */ this.debugShowBoundingVolume = defaultValue(options.debugShowBoundingVolume, false); + + /** + * The label blending option. The default is used for rendering both opaque and translucent labels. + * However, if either all of the labels are completely opaque or all are completely translucent, + * setting the technique to BillboardRenderTechnique.OPAQUE or BillboardRenderTechnique.TRANSLUCENT can improve + * performance by up to 2x. + * @type {BlendOption} + * @default BlendOption.OPAQUE_AND_TRANSLUCENT + */ + this.blendOption = defaultValue(options.blendOption, BlendOption.OPAQUE_AND_TRANSLUCENT); } defineProperties(LabelCollection.prototype, { @@ -732,8 +747,10 @@ define([ billboardCollection.modelMatrix = this.modelMatrix; billboardCollection.debugShowBoundingVolume = this.debugShowBoundingVolume; + billboardCollection.blendOption = this.blendOption; backgroundBillboardCollection.modelMatrix = this.modelMatrix; backgroundBillboardCollection.debugShowBoundingVolume = this.debugShowBoundingVolume; + backgroundBillboardCollection.blendOption = this.blendOption; var context = frameState.context; diff --git a/Source/Scene/PointPrimitiveCollection.js b/Source/Scene/PointPrimitiveCollection.js index c0fe507b7cb4..ca1e50129ce4 100644 --- a/Source/Scene/PointPrimitiveCollection.js +++ b/Source/Scene/PointPrimitiveCollection.js @@ -23,8 +23,8 @@ define([ '../Renderer/VertexArrayFacade', '../Shaders/PointPrimitiveCollectionFS', '../Shaders/PointPrimitiveCollectionVS', - './BillboardRenderTechnique', './BlendingState', + './BlendOption', './PointPrimitive', './SceneMode' ], function( @@ -51,8 +51,8 @@ define([ VertexArrayFacade, PointPrimitiveCollectionFS, PointPrimitiveCollectionVS, - BillboardRenderTechnique, BlendingState, + BlendOption, PointPrimitive, SceneMode) { 'use strict'; @@ -89,9 +89,9 @@ define([ * @param {Object} [options] Object with the following properties: * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms each point from model to world coordinates. * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. - * @param {BillboardRenderTechnique} [options.renderTechnique=BillboardRenderTechnique.OPAQUE_AND_TRANSLUCENT] The billboard rendering technique. The default + * @param {BlendOption} [options.blendOption=BlendOption.OPAQUE_AND_TRANSLUCENT] The point blending option. The default * is used for rendering both opaque and translucent points. However, if either all of the points are completely opaque or all are completely translucent, - * setting the technique to BillboardRenderTechnique.OPAQUE or BillboardRenderTechnique.TRANSLUCENT can improve performance by 2x. + * setting the technique to BillboardRenderTechnique.OPAQUE or BillboardRenderTechnique.TRANSLUCENT can improve performance by up to 2x. * * @performance For best performance, prefer a few collections, each with many points, to * many collections with only a few points each. Organize collections so that points @@ -205,14 +205,15 @@ define([ this.debugShowBoundingVolume = defaultValue(options.debugShowBoundingVolume, false); /** - * The billboard rendering technique. The default is used for rendering both opaque and translucent points. + * The point blending option. The default is used for rendering both opaque and translucent points. * However, if either all of the points are completely opaque or all are completely translucent, - * setting the technique to BillboardRenderTechnique.OPAQUE or BillboardRenderTechnique.TRANSLUCENT can improve performance by 2x. - * @type {BillboardRenderTechnique} - * @default BillboardRenderTechnique.OPAQUE_AND_TRANSLUCENT + * setting the technique to BillboardRenderTechnique.OPAQUE or BillboardRenderTechnique.TRANSLUCENT can improve + * performance by up to 2x. + * @type {BlendOption} + * @default BlendOption.OPAQUE_AND_TRANSLUCENT */ - this.renderTechnique = defaultValue(options.renderTechnique, BillboardRenderTechnique.OPAQUE_AND_TRANSLUCENT); - this._renderTechnique = undefined; + this.blendOption = defaultValue(options.blendOption, BlendOption.OPAQUE_AND_TRANSLUCENT); + this._blendOption = undefined; this._mode = SceneMode.SCENE3D; this._maxTotalPointSize = 1; @@ -852,10 +853,10 @@ define([ } updateBoundingVolume(this, frameState, boundingVolume); - var techniqueChanged = this._renderTechnique !== this.renderTechnique; - this._renderTechnique = this.renderTechnique; + var blendOptionChanged = this._blendOption !== this.blendOption; + this._blendOption = this.blendOption; - if (techniqueChanged) { + if (blendOptionChanged) { this._rsOpaque = RenderState.fromCache({ depthTest : { enabled : true, @@ -864,7 +865,7 @@ define([ depthMask : true }); - if (this._renderTechnique === BillboardRenderTechnique.TRANSLUCENT || this._renderTechnique === BillboardRenderTechnique.OPAQUE_AND_TRANSLUCENT) { + if (this._blendOption === BlendOption.TRANSLUCENT || this._blendOption === BlendOption.OPAQUE_AND_TRANSLUCENT) { this._rsTranslucent = RenderState.fromCache({ depthTest : { enabled : true, @@ -878,7 +879,7 @@ define([ } } - if (techniqueChanged || + if (blendOptionChanged || (this._shaderScaleByDistance && !this._compiledShaderScaleByDistance) || (this._shaderTranslucencyByDistance && !this._compiledShaderTranslucencyByDistance) || (this._shaderDistanceDisplayCondition && !this._compiledShaderDistanceDisplayCondition)) { @@ -896,7 +897,7 @@ define([ vs.defines.push('DISTANCE_DISPLAY_CONDITION'); } - if (this._renderTechnique === BillboardRenderTechnique.OPAQUE || this._renderTechnique === BillboardRenderTechnique.OPAQUE_AND_TRANSLUCENT) { + if (this._blendOption === BlendOption.OPAQUE || this._blendOption === BlendOption.OPAQUE_AND_TRANSLUCENT) { fs = new ShaderSource({ defines : ['OPAQUE'], sources : [PointPrimitiveCollectionFS] @@ -913,7 +914,7 @@ define([ this._sp = undefined; } - if (this._renderTechnique === BillboardRenderTechnique.TRANSLUCENT || this._renderTechnique === BillboardRenderTechnique.OPAQUE_AND_TRANSLUCENT) { + if (this._blendOption === BlendOption.TRANSLUCENT || this._blendOption === BlendOption.OPAQUE_AND_TRANSLUCENT) { fs = new ShaderSource({ defines : ['TRANSLUCENT'], sources : [PointPrimitiveCollectionFS] @@ -985,8 +986,8 @@ define([ if (pass.render) { var colorList = this._colorCommands; - var opaque = this._renderTechnique === BillboardRenderTechnique.OPAQUE; - var opaqueAndTranslucent = this._renderTechnique === BillboardRenderTechnique.OPAQUE_AND_TRANSLUCENT; + var opaque = this._blendOption === BlendOption.OPAQUE; + var opaqueAndTranslucent = this._blendOption === BlendOption.OPAQUE_AND_TRANSLUCENT; va = this._vaf.va; vaLength = va.length; diff --git a/Specs/Scene/BillboardCollectionSpec.js b/Specs/Scene/BillboardCollectionSpec.js index 2db1adb1b4f4..205b0ed70656 100644 --- a/Specs/Scene/BillboardCollectionSpec.js +++ b/Specs/Scene/BillboardCollectionSpec.js @@ -13,7 +13,7 @@ defineSuite([ 'Core/NearFarScalar', 'Core/Rectangle', 'Scene/Billboard', - 'Scene/BillboardRenderTechnique', + 'Scene/BlendOption', 'Scene/HeightReference', 'Scene/HorizontalOrigin', 'Scene/OrthographicFrustum', @@ -37,7 +37,7 @@ defineSuite([ NearFarScalar, Rectangle, Billboard, - BillboardRenderTechnique, + BlendOption, HeightReference, HorizontalOrigin, OrthographicFrustum, @@ -241,17 +241,17 @@ defineSuite([ var frameState = scene.frameState; frameState.commandList.length = 0; - billboards.renderTechnique = BillboardRenderTechnique.OPAQUE_AND_TRANSLUCENT; + billboards.blendOption = BlendOption.OPAQUE_AND_TRANSLUCENT; billboards.update(frameState); expect(frameState.commandList.length).toEqual(2); frameState.commandList.length = 0; - billboards.renderTechnique = BillboardRenderTechnique.OPAQUE; + billboards.blendOption = BlendOption.OPAQUE; billboards.update(frameState); expect(frameState.commandList.length).toEqual(1); frameState.commandList.length = 0; - billboards.renderTechnique = BillboardRenderTechnique.TRANSLUCENT; + billboards.blendOption = BlendOption.TRANSLUCENT; billboards.update(frameState); expect(frameState.commandList.length).toEqual(1); }); diff --git a/Specs/Scene/LabelCollectionSpec.js b/Specs/Scene/LabelCollectionSpec.js index a83fb94b3f52..50abe11e756e 100644 --- a/Specs/Scene/LabelCollectionSpec.js +++ b/Specs/Scene/LabelCollectionSpec.js @@ -11,6 +11,7 @@ defineSuite([ 'Core/Math', 'Core/NearFarScalar', 'Core/Rectangle', + 'Scene/BlendOption', 'Scene/Globe', 'Scene/HeightReference', 'Scene/HorizontalOrigin', @@ -31,6 +32,7 @@ defineSuite([ CesiumMath, NearFarScalar, Rectangle, + BlendOption, Globe, HeightReference, HorizontalOrigin, @@ -343,6 +345,32 @@ defineSuite([ expect(scene.renderForSpecs()[0]).toBeGreaterThan(10); }); + it('renders in multiple passes', function() { + labels.add({ + position : Cartesian3.ZERO, + text : 'x', + horizontalOrigin : HorizontalOrigin.CENTER, + verticalOrigin : VerticalOrigin.CENTER + }); + camera.position = new Cartesian3(2.0, 0.0, 0.0); + + var frameState = scene.frameState; + frameState.commandList.length = 0; + labels.blendOption = BlendOption.OPAQUE_AND_TRANSLUCENT; + labels.update(frameState); + expect(frameState.commandList.length).toEqual(2); + + frameState.commandList.length = 0; + labels.blendOption = BlendOption.OPAQUE; + labels.update(frameState); + expect(frameState.commandList.length).toEqual(1); + + frameState.commandList.length = 0; + labels.blendOption = BlendOption.TRANSLUCENT; + labels.update(frameState); + expect(frameState.commandList.length).toEqual(1); + }); + it('can render after adding a label', function() { labels.add({ position : Cartesian3.ZERO, diff --git a/Specs/Scene/PointPrimitiveCollectionSpec.js b/Specs/Scene/PointPrimitiveCollectionSpec.js index 58b1373ffc6e..978a1ced9842 100644 --- a/Specs/Scene/PointPrimitiveCollectionSpec.js +++ b/Specs/Scene/PointPrimitiveCollectionSpec.js @@ -10,7 +10,7 @@ defineSuite([ 'Core/Math', 'Core/NearFarScalar', 'Core/Rectangle', - 'Scene/BillboardRenderTechnique', + 'Scene/BlendOption', 'Scene/PointPrimitive', 'Specs/createScene' ], function( @@ -24,7 +24,7 @@ defineSuite([ CesiumMath, NearFarScalar, Rectangle, - BillboardRenderTechnique, + BlendOption, PointPrimitive, createScene) { 'use strict'; @@ -166,17 +166,17 @@ defineSuite([ var frameState = scene.frameState; frameState.commandList.length = 0; - pointPrimitives.renderTechnique = BillboardRenderTechnique.OPAQUE_AND_TRANSLUCENT; + pointPrimitives.blendOption = BlendOption.OPAQUE_AND_TRANSLUCENT; pointPrimitives.update(frameState); expect(frameState.commandList.length).toEqual(2); frameState.commandList.length = 0; - pointPrimitives.renderTechnique = BillboardRenderTechnique.OPAQUE; + pointPrimitives.blendOption = BlendOption.OPAQUE; pointPrimitives.update(frameState); expect(frameState.commandList.length).toEqual(1); frameState.commandList.length = 0; - pointPrimitives.renderTechnique = BillboardRenderTechnique.TRANSLUCENT; + pointPrimitives.blendOption = BlendOption.TRANSLUCENT; pointPrimitives.update(frameState); expect(frameState.commandList.length).toEqual(1); });