diff --git a/Apps/Sandcastle/gallery/Billboards.html b/Apps/Sandcastle/gallery/Billboards.html index 2a2f623f8704..366e2b7c740b 100644 --- a/Apps/Sandcastle/gallery/Billboards.html +++ b/Apps/Sandcastle/gallery/Billboards.html @@ -79,7 +79,7 @@ function sizeBillboardInMeters() { Sandcastle.declare(sizeBillboardInMeters); - + var entity = viewer.entities.add({ position : Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883), billboard : { @@ -87,7 +87,7 @@ sizeInMeters : true } }); - + viewer.zoomTo(entity); } @@ -221,6 +221,29 @@ }); } +var terrainProvider; +function disableDepthTest() { + Sandcastle.declare(disableDepthTest); + + terrainProvider = viewer.terrainProvider; + viewer.terrainProvider = new Cesium.CesiumTerrainProvider({ + url : 'https://assets.agi.com/stk-terrain/world', + requestWaterMask : true, + requestVertexNormals : true + }); + viewer.scene.globe.depthTestAgainstTerrain = true; + + viewer.entities.add({ + position : Cesium.Cartesian3.fromDegrees(-122.1958, 46.1915), + billboard : { + image : '../images/facility.gif', + heightReference : Cesium.HeightReference.CLAMP_TO_GROUND, + disableDepthTestDistance : Number.POSITIVE_INFINITY + } + }); + viewer.zoomTo(viewer.entities); +} + Sandcastle.addToolbarMenu([{ text : 'Add billboard', onselect : function() { @@ -275,11 +298,23 @@ addMarkerBillboards(); Sandcastle.highlight(addMarkerBillboards); } +}, { + text : 'Disable the depth test when clamped to ground', + onselect : function() { + disableDepthTest(); + Sandcastle.highlight(disableDepthTest); + } }]); Sandcastle.reset = function () { viewer.camera.flyHome(0); viewer.entities.removeAll(); + + if (Cesium.defined(terrainProvider)) { + viewer.terrainProvider = terrainProvider; + terrainProvider = undefined; + viewer.scene.globe.depthTestAgainstTerrain = false; + } }; //Sandcastle_End Sandcastle.finishedLoading(); diff --git a/CHANGES.md b/CHANGES.md index 77bb0d8949f4..145981237412 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,10 @@ Change Log ========== +### 1.33 - 2017-05-01 + +* Added `disableDepthTestDistance` to billboards, points and labels. This sets the distance to the camera where the depth test will be disabled. Setting it to zero (the default) will alwasy enable the depth test. Setting it to `Number.POSITVE_INFINITY` will never enabled the depth test. Also added `scene.minimumDisableDepthTestDistance` to change the default value from zero. [#5166](https://github.com/AnalyticalGraphicsInc/cesium/pull/5166) + ### 1.32 - 2017-04-03 * Deprecated diff --git a/Source/DataSources/BillboardGraphics.js b/Source/DataSources/BillboardGraphics.js index 628768b00007..27e33c9f1728 100644 --- a/Source/DataSources/BillboardGraphics.js +++ b/Source/DataSources/BillboardGraphics.js @@ -89,6 +89,8 @@ define([ this._sizeInMetersSubscription = undefined; this._distanceDisplayCondition = undefined; this._distanceDisplayConditionSubscription = undefined; + this._disableDepthTestDistance = undefined; + this._disableDepthTestDistanceSubscription = undefined; this._definitionChanged = new Event(); this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); @@ -316,7 +318,15 @@ define([ * @memberof BillboardGraphics.prototype * @type {Property} */ - distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition') + distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition'), + + /** + * Gets or sets the distance from the camera at which to disable the depth test to, for example, prevent clipping against terrain. + * When set to zero, the depth test is always applied. When set to Number.POSITIVE_INFINITY, the depth test is never applied. + * @memberof BillboardGraphics.prototype + * @type {Property} + */ + disableDepthTestDistance : createPropertyDescriptor('disableDepthTestDistance') }); /** @@ -348,6 +358,7 @@ define([ result.pixelOffsetScaleByDistance = this._pixelOffsetScaleByDistance; result.sizeInMeters = this._sizeInMeters; result.distanceDisplayCondition = this._distanceDisplayCondition; + result.disableDepthTestDistance = this._disableDepthTestDistance; return result; }; @@ -383,6 +394,7 @@ define([ this.pixelOffsetScaleByDistance = defaultValue(this._pixelOffsetScaleByDistance, source.pixelOffsetScaleByDistance); this.sizeInMeters = defaultValue(this._sizeInMeters, source.sizeInMeters); this.distanceDisplayCondition = defaultValue(this._distanceDisplayCondition, source.distanceDisplayCondition); + this.disableDepthTestDistance = defaultValue(this._disableDepthTestDistance, source.disableDepthTestDistance); }; return BillboardGraphics; diff --git a/Source/DataSources/BillboardVisualizer.js b/Source/DataSources/BillboardVisualizer.js index b1595fd5dca5..fd64b9db3000 100644 --- a/Source/DataSources/BillboardVisualizer.js +++ b/Source/DataSources/BillboardVisualizer.js @@ -43,6 +43,7 @@ define([ var defaultHorizontalOrigin = HorizontalOrigin.CENTER; var defaultVerticalOrigin = VerticalOrigin.CENTER; var defaultSizeInMeters = false; + var defaultDisableDepthTestDistance = 0.0; var position = new Cartesian3(); var color = new Color(); @@ -154,8 +155,9 @@ define([ billboard.scaleByDistance = Property.getValueOrUndefined(billboardGraphics._scaleByDistance, time, scaleByDistance); billboard.translucencyByDistance = Property.getValueOrUndefined(billboardGraphics._translucencyByDistance, time, translucencyByDistance); billboard.pixelOffsetScaleByDistance = Property.getValueOrUndefined(billboardGraphics._pixelOffsetScaleByDistance, time, pixelOffsetScaleByDistance); - billboard.sizeInMeters = Property.getValueOrDefault(billboardGraphics._sizeInMeters, defaultSizeInMeters); + billboard.sizeInMeters = Property.getValueOrDefault(billboardGraphics._sizeInMeters, time, defaultSizeInMeters); billboard.distanceDisplayCondition = Property.getValueOrUndefined(billboardGraphics._distanceDisplayCondition, time, distanceDisplayCondition); + billboard.disableDepthTestDistance = Property.getValueOrDefault(billboardGraphics._disableDepthTestDistance, time, defaultDisableDepthTestDistance); var subRegion = Property.getValueOrUndefined(billboardGraphics._imageSubRegion, time, boundingRectangle); if (defined(subRegion)) { diff --git a/Source/DataSources/LabelGraphics.js b/Source/DataSources/LabelGraphics.js index bb7b8b004444..026fa778b3b5 100644 --- a/Source/DataSources/LabelGraphics.js +++ b/Source/DataSources/LabelGraphics.js @@ -92,6 +92,8 @@ define([ this._scaleByDistanceSubscription = undefined; this._distanceDisplayCondition = undefined; this._distanceDisplayConditionSubscription = undefined; + this._disableDepthTestDistance = undefined; + this._disableDepthTestDistanceSubscription = undefined; this._definitionChanged = new Event(); this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); @@ -309,7 +311,15 @@ define([ * @memberof LabelGraphics.prototype * @type {Property} */ - distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition') + distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition'), + + /** + * Gets or sets the distance from the camera at which to disable the depth test to, for example, prevent clipping against terrain. + * When set to zero, the depth test is always applied. When set to Number.POSITIVE_INFINITY, the depth test is never applied. + * @memberof LabelGraphics.prototype + * @type {Property} + */ + disableDepthTestDistance : createPropertyDescriptor('disableDepthTestDistance') }); /** @@ -342,6 +352,7 @@ define([ result.pixelOffsetScaleByDistance = this.pixelOffsetScaleByDistance; result.scaleByDistance = this.scaleByDistance; result.distanceDisplayCondition = this.distanceDisplayCondition; + result.disableDepthTestDistance = this.disableDepthTestDistance; return result; }; @@ -374,10 +385,11 @@ define([ this.eyeOffset = defaultValue(this.eyeOffset, source.eyeOffset); this.heightReference = defaultValue(this.heightReference, source.heightReference); this.pixelOffset = defaultValue(this.pixelOffset, source.pixelOffset); - this.translucencyByDistance = defaultValue(this._translucencyByDistance, source.translucencyByDistance); - this.pixelOffsetScaleByDistance = defaultValue(this._pixelOffsetScaleByDistance, source.pixelOffsetScaleByDistance); - this.scaleByDistance = defaultValue(this._scaleByDistance, source.scaleByDistance); + this.translucencyByDistance = defaultValue(this.translucencyByDistance, source.translucencyByDistance); + this.pixelOffsetScaleByDistance = defaultValue(this.pixelOffsetScaleByDistance, source.pixelOffsetScaleByDistance); + this.scaleByDistance = defaultValue(this.scaleByDistance, source.scaleByDistance); this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); + this.disableDepthTestDistance = defaultValue(this.disableDepthTestDistance, source.disableDepthTestDistance); }; return LabelGraphics; diff --git a/Source/DataSources/LabelVisualizer.js b/Source/DataSources/LabelVisualizer.js index 3ec353a13fc9..0407205174d0 100644 --- a/Source/DataSources/LabelVisualizer.js +++ b/Source/DataSources/LabelVisualizer.js @@ -49,6 +49,7 @@ define([ var defaultHeightReference = HeightReference.NONE; var defaultHorizontalOrigin = HorizontalOrigin.CENTER; var defaultVerticalOrigin = VerticalOrigin.CENTER; + var defaultDisableDepthTestDistance = 0.0; var position = new Cartesian3(); var fillColor = new Color(); @@ -164,6 +165,7 @@ define([ label.pixelOffsetScaleByDistance = Property.getValueOrUndefined(labelGraphics._pixelOffsetScaleByDistance, time, pixelOffsetScaleByDistance); label.scaleByDistance = Property.getValueOrUndefined(labelGraphics._scaleByDistance, time, scaleByDistance); label.distanceDisplayCondition = Property.getValueOrUndefined(labelGraphics._distanceDisplayCondition, time, distanceDisplayCondition); + label.disableDepthTestDistance = Property.getValueOrDefault(labelGraphics._disableDepthTestDistance, time, defaultDisableDepthTestDistance); } return true; }; diff --git a/Source/DataSources/PointGraphics.js b/Source/DataSources/PointGraphics.js index af7633d7a8e6..4688b5100e59 100644 --- a/Source/DataSources/PointGraphics.js +++ b/Source/DataSources/PointGraphics.js @@ -51,6 +51,8 @@ define([ this._heightReferenceSubscription = undefined; this._distanceDisplayCondition = undefined; this._distanceDisplayConditionSubscription = undefined; + this._disableDepthTestDistance = undefined; + this._disableDepthTestDistanceSubscription = undefined; this._definitionChanged = new Event(); this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT)); @@ -142,7 +144,15 @@ define([ * @memberof PointGraphics.prototype * @type {Property} */ - distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition') + distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition'), + + /** + * Gets or sets the distance from the camera at which to disable the depth test to, for example, prevent clipping against terrain. + * When set to zero, the depth test is always applied. When set to Number.POSITIVE_INFINITY, the depth test is never applied. + * @memberof PointGraphics.prototype + * @type {Property} + */ + disableDepthTestDistance : createPropertyDescriptor('disableDepthTestDistance') }); /** @@ -164,6 +174,7 @@ define([ result.translucencyByDistance = this._translucencyByDistance; result.heightReference = this.heightReference; result.distanceDisplayCondition = this.distanceDisplayCondition; + result.disableDepthTestDistance = this.disableDepthTestDistance; return result; }; @@ -189,6 +200,7 @@ define([ this.translucencyByDistance = defaultValue(this._translucencyByDistance, source.translucencyByDistance); this.heightReference = defaultValue(this.heightReference, source.heightReference); this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); + this.disableDepthTestDistance = defaultValue(this.disableDepthTestDistance, source.disableDepthTestDistance); }; return PointGraphics; diff --git a/Source/DataSources/PointVisualizer.js b/Source/DataSources/PointVisualizer.js index f287439389dc..16878334b8b5 100644 --- a/Source/DataSources/PointVisualizer.js +++ b/Source/DataSources/PointVisualizer.js @@ -29,6 +29,7 @@ define([ var defaultOutlineColor = Color.BLACK; var defaultOutlineWidth = 0.0; var defaultPixelSize = 1.0; + var defaultDisableDepthTestDistance = 0.0; var color = new Color(); var position = new Cartesian3(); @@ -143,12 +144,14 @@ define([ pointPrimitive.outlineWidth = Property.getValueOrDefault(pointGraphics._outlineWidth, time, defaultOutlineWidth); pointPrimitive.pixelSize = Property.getValueOrDefault(pointGraphics._pixelSize, time, defaultPixelSize); pointPrimitive.distanceDisplayCondition = Property.getValueOrUndefined(pointGraphics._distanceDisplayCondition, time, distanceDisplayCondition); + pointPrimitive.disableDepthTestDistance = Property.getValueOrDefault(pointGraphics._disableDepthTestDistance, time, defaultDisableDepthTestDistance); } else { // billboard billboard.show = true; billboard.position = position; billboard.scaleByDistance = Property.getValueOrUndefined(pointGraphics._scaleByDistance, time, scaleByDistance); billboard.translucencyByDistance = Property.getValueOrUndefined(pointGraphics._translucencyByDistance, time, translucencyByDistance); billboard.distanceDisplayCondition = Property.getValueOrUndefined(pointGraphics._distanceDisplayCondition, time, distanceDisplayCondition); + billboard.disableDepthTestDistance = Property.getValueOrDefault(pointGraphics._disableDepthTestDistance, time, defaultDisableDepthTestDistance); billboard.heightReference = heightReference; var newColor = Property.getValueOrDefault(pointGraphics._color, time, defaultColor, color); diff --git a/Source/Renderer/AutomaticUniforms.js b/Source/Renderer/AutomaticUniforms.js index b5aee136402e..b202f464fce4 100644 --- a/Source/Renderer/AutomaticUniforms.js +++ b/Source/Renderer/AutomaticUniforms.js @@ -1523,11 +1523,27 @@ define([ * @glslUniform */ czm_geometricToleranceOverMeter : new AutomaticUniform({ - size: 1, - datatype: WebGLConstants.FLOAT, - getValue: function(uniformState) { + size : 1, + datatype : WebGLConstants.FLOAT, + getValue : function(uniformState) { return uniformState.geometricToleranceOverMeter; } + }), + + /** + * An automatic GLSL uniform representing the distance from the camera at which to disable the depth test of billboards, labels and points + * to, for example, prevent clipping against terrain. When set to zero, the depth test should always be applied. When less than zero, + * the depth test should never be applied. + * + * @alias czm_minimumDisableDepthTestDistance + * @glslUniform + */ + czm_minimumDisableDepthTestDistance : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT, + getValue : function(uniformState) { + return uniformState.minimumDisableDepthTestDistance; + } }) }; diff --git a/Source/Renderer/UniformState.js b/Source/Renderer/UniformState.js index a882d42fd1bd..3abe699ca767 100644 --- a/Source/Renderer/UniformState.js +++ b/Source/Renderer/UniformState.js @@ -156,6 +156,8 @@ define([ this._imagerySplitPosition = 0.0; this._pixelSizePerMeter = undefined; this._geometricToleranceOverMeter = undefined; + + this._minimumDisableDepthTestDistance = undefined; } defineProperties(UniformState.prototype, { @@ -803,6 +805,20 @@ define([ get : function() { return this._imagerySplitPosition; } + }, + + /** + * The distance from the camera at which to disable the depth test of billboards, labels and points + * to, for example, prevent clipping against terrain. When set to zero, the depth test should always + * be applied. When less than zero, the depth test should never be applied. + * + * @memberof UniformState.prototype + * @type {Number} + */ + minimumDisableDepthTestDistance : { + get : function() { + return this._minimumDisableDepthTestDistance; + } } }); @@ -978,6 +994,12 @@ define([ this._geometricToleranceOverMeter = pixelSizePerMeter * frameState.maximumScreenSpaceError; Color.clone(frameState.backgroundColor, this._backgroundColor); + + this._minimumDisableDepthTestDistance = frameState.minimumDisableDepthTestDistance; + this._minimumDisableDepthTestDistance *= this._minimumDisableDepthTestDistance; + if (this._minimumDisableDepthTestDistance === Number.POSITIVE_INFINITY) { + this._minimumDisableDepthTestDistance = -1.0; + } }; function cleanViewport(uniformState) { diff --git a/Source/Scene/Billboard.js b/Source/Scene/Billboard.js index 08aa929bdcb7..56cb731478cc 100644 --- a/Source/Scene/Billboard.js +++ b/Source/Scene/Billboard.js @@ -89,6 +89,9 @@ define([ if (defined(options.distanceDisplayCondition) && options.distanceDisplayCondition.far <= options.distanceDisplayCondition.near) { throw new DeveloperError('distanceDisplayCondition.far must be greater than distanceDisplayCondition.near'); } + if (defined(options.disableDepthTestDistance) && options.disableDepthTestDistance < 0.0) { + throw new DeveloperError('disableDepthTestDistance must be greater than or equal to 0.0.'); + } //>>includeEnd('debug'); this._show = defaultValue(options.show, true); @@ -111,6 +114,7 @@ define([ this._pixelOffsetScaleByDistance = options.pixelOffsetScaleByDistance; this._sizeInMeters = defaultValue(options.sizeInMeters, false); this._distanceDisplayCondition = options.distanceDisplayCondition; + this._disableDepthTestDistance = defaultValue(options.disableDepthTestDistance, 0.0); this._id = options.id; this._collection = defaultValue(options.collection, billboardCollection); @@ -178,7 +182,8 @@ define([ var TRANSLUCENCY_BY_DISTANCE_INDEX = Billboard.TRANSLUCENCY_BY_DISTANCE_INDEX = 12; var PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX = Billboard.PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX = 13; var DISTANCE_DISPLAY_CONDITION = Billboard.DISTANCE_DISPLAY_CONDITION = 14; - Billboard.NUMBER_OF_PROPERTIES = 15; + var DISABLE_DEPTH_DISTANCE = Billboard.DISABLE_DEPTH_DISTANCE = 15; + Billboard.NUMBER_OF_PROPERTIES = 16; function makeDirty(billboard, propertyChanged) { var billboardCollection = billboard._billboardCollection; @@ -748,6 +753,30 @@ define([ } }, + /** + * Gets or sets the distance from the camera at which to disable the depth test to, for example, prevent clipping against terrain. + * When set to zero, the depth test is always applied. When set to Number.POSITIVE_INFINITY, the depth test is never applied. + * @memberof Billboard.prototype + * @type {Number} + * @default 0.0 + */ + disableDepthTestDistance : { + get : function() { + return this._disableDepthTestDistance; + }, + set : function(value) { + if (this._disableDepthTestDistance !== value) { + //>>includeStart('debug', pragmas.debug); + if (!defined(value) || value < 0.0) { + throw new DeveloperError('disableDepthTestDistance must be greater than or equal to 0.0.'); + } + //>>includeEnd('debug'); + this._disableDepthTestDistance = value; + makeDirty(this, DISABLE_DEPTH_DISTANCE); + } + } + }, + /** * Gets or sets the user-defined object returned when the billboard is picked. * @memberof Billboard.prototype @@ -1278,7 +1307,8 @@ define([ NearFarScalar.equals(this._scaleByDistance, other._scaleByDistance) && NearFarScalar.equals(this._translucencyByDistance, other._translucencyByDistance) && NearFarScalar.equals(this._pixelOffsetScaleByDistance, other._pixelOffsetScaleByDistance) && - DistanceDisplayCondition.equals(this._distanceDisplayCondition, other._distanceDisplayCondition); + DistanceDisplayCondition.equals(this._distanceDisplayCondition, other._distanceDisplayCondition) && + this._disableDepthTestDistance === other._disableDepthTestDistance; }; Billboard.prototype._destroy = function() { diff --git a/Source/Scene/BillboardCollection.js b/Source/Scene/BillboardCollection.js index 5ce469cbbbec..7cd3e39fdc92 100644 --- a/Source/Scene/BillboardCollection.js +++ b/Source/Scene/BillboardCollection.js @@ -86,6 +86,7 @@ define([ var TRANSLUCENCY_BY_DISTANCE_INDEX = Billboard.TRANSLUCENCY_BY_DISTANCE_INDEX; var PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX = Billboard.PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX; var DISTANCE_DISPLAY_CONDITION_INDEX = Billboard.DISTANCE_DISPLAY_CONDITION_INDEX; + var DISABLE_DEPTH_DISTANCE = Billboard.DISABLE_DEPTH_DISTANCE; var NUMBER_OF_PROPERTIES = Billboard.NUMBER_OF_PROPERTIES; var attributeLocations; @@ -99,7 +100,7 @@ define([ eyeOffset : 5, // 4 bytes free scaleByDistance : 6, pixelOffsetScaleByDistance : 7, - distanceDisplayCondition : 8 + distanceDisplayConditionAndDisableDepth : 8 }; var attributeLocationsInstanced = { @@ -112,7 +113,7 @@ define([ eyeOffset : 6, // texture range in w scaleByDistance : 7, pixelOffsetScaleByDistance : 8, - distanceDisplayCondition : 9 + distanceDisplayConditionAndDisableDepth : 9 }; /** @@ -209,6 +210,10 @@ define([ this._compiledShaderDistanceDisplayCondition = false; this._compiledShaderDistanceDisplayConditionPick = false; + this._shaderDisableDepthDistance = false; + this._compiledShaderDisableDepthDistance = false; + this._compiledShaderDisableDepthDistancePick = false; + this._propertiesChanged = new Uint32Array(NUMBER_OF_PROPERTIES); this._maxSize = 0.0; @@ -729,8 +734,8 @@ define([ componentDatatype : ComponentDatatype.FLOAT, usage : buffersUsage[PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX] }, { - index : attributeLocations.distanceDisplayCondition, - componentsPerAttribute : 2, + index : attributeLocations.distanceDisplayConditionAndDisableDepth, + componentsPerAttribute : 3, componentDatatype : ComponentDatatype.FLOAT, usage : buffersUsage[DISTANCE_DISPLAY_CONDITION_INDEX] }]; @@ -1146,9 +1151,9 @@ define([ } } - function writeDistanceDisplayCondition(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard) { + function writeDistanceDisplayConditionAndDepthDisable(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard) { var i; - var writer = vafWriters[attributeLocations.distanceDisplayCondition]; + var writer = vafWriters[attributeLocations.distanceDisplayConditionAndDisableDepth]; var near = 0.0; var far = Number.MAX_VALUE; @@ -1157,18 +1162,30 @@ define([ near = distanceDisplayCondition.near; far = distanceDisplayCondition.far; + near *= near; + far *= far; + billboardCollection._shaderDistanceDisplayCondition = true; } + var disableDepthTestDistance = billboard.disableDepthTestDistance; + disableDepthTestDistance *= disableDepthTestDistance; + if (disableDepthTestDistance > 0.0) { + billboardCollection._shaderDisableDepthDistance = true; + if (disableDepthTestDistance === Number.POSITIVE_INFINITY) { + disableDepthTestDistance = -1.0; + } + } + if (billboardCollection._instanced) { i = billboard._index; - writer(i, near, far); + writer(i, near, far, disableDepthTestDistance); } else { i = billboard._index * 4; - writer(i + 0, near, far); - writer(i + 1, near, far); - writer(i + 2, near, far); - writer(i + 3, near, far); + writer(i + 0, near, far, disableDepthTestDistance); + writer(i + 1, near, far, disableDepthTestDistance); + writer(i + 2, near, far, disableDepthTestDistance); + writer(i + 3, near, far, disableDepthTestDistance); } } @@ -1180,7 +1197,7 @@ define([ writeEyeOffset(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard); writeScaleByDistance(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard); writePixelOffsetScaleByDistance(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard); - writeDistanceDisplayCondition(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard); + writeDistanceDisplayConditionAndDepthDisable(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard); } function recomputeActualPositions(billboardCollection, billboards, length, frameState, modelMatrix, recomputeBoundingVolume) { @@ -1376,8 +1393,8 @@ define([ writers.push(writePixelOffsetScaleByDistance); } - if (properties[DISTANCE_DISPLAY_CONDITION_INDEX]) { - writers.push(writeDistanceDisplayCondition); + if (properties[DISTANCE_DISPLAY_CONDITION_INDEX] || properties[DISABLE_DEPTH_DISTANCE]) { + writers.push(writeDistanceDisplayConditionAndDepthDisable); } var numWriters = writers.length; @@ -1481,13 +1498,16 @@ define([ } } + this._shaderDisableDepthDistance = this._shaderDisableDepthDistance || frameState.minimumDisableDepthTestDistance !== 0.0; + if (blendOptionChanged || (this._shaderRotation !== this._compiledShaderRotation) || (this._shaderAlignedAxis !== this._compiledShaderAlignedAxis) || (this._shaderScaleByDistance !== this._compiledShaderScaleByDistance) || (this._shaderTranslucencyByDistance !== this._compiledShaderTranslucencyByDistance) || (this._shaderPixelOffsetScaleByDistance !== this._compiledShaderPixelOffsetScaleByDistance) || - (this._shaderDistanceDisplayCondition !== this._compiledShaderDistanceDisplayCondition)) { + (this._shaderDistanceDisplayCondition !== this._compiledShaderDistanceDisplayCondition) || + (this._shaderDisableDepthDistance !== this._compiledShaderDisableDepthDistance)) { vs = new ShaderSource({ sources : [BillboardCollectionVS] @@ -1513,6 +1533,9 @@ define([ if (this._shaderDistanceDisplayCondition) { vs.defines.push('DISTANCE_DISPLAY_CONDITION'); } + if (this._shaderDisableDepthDistance) { + vs.defines.push('DISABLE_DEPTH_DISTANCE'); + } if (this._blendOption === BlendOption.OPAQUE_AND_TRANSLUCENT) { fs = new ShaderSource({ @@ -1572,6 +1595,7 @@ define([ this._compiledShaderTranslucencyByDistance = this._shaderTranslucencyByDistance; this._compiledShaderPixelOffsetScaleByDistance = this._shaderPixelOffsetScaleByDistance; this._compiledShaderDistanceDisplayCondition = this._shaderDistanceDisplayCondition; + this._compiledShaderDisableDepthDistance = this._shaderDisableDepthDistance; } if (!defined(this._spPick) || @@ -1580,7 +1604,8 @@ define([ (this._shaderScaleByDistance !== this._compiledShaderScaleByDistancePick) || (this._shaderTranslucencyByDistance !== this._compiledShaderTranslucencyByDistancePick) || (this._shaderPixelOffsetScaleByDistance !== this._compiledShaderPixelOffsetScaleByDistancePick) || - (this._shaderDistanceDisplayCondition !== this._compiledShaderDistanceDisplayConditionPick)) { + (this._shaderDistanceDisplayCondition !== this._compiledShaderDistanceDisplayConditionPick) || + (this._shaderDisableDepthDistance !== this._compiledShaderDisableDepthDistancePick)) { vs = new ShaderSource({ defines : ['RENDER_FOR_PICK'], @@ -1608,6 +1633,9 @@ define([ if (this._shaderDistanceDisplayCondition) { vs.defines.push('DISTANCE_DISPLAY_CONDITION'); } + if (this._shaderDisableDepthDistance) { + vs.defines.push('DISABLE_DEPTH_DISTANCE'); + } fs = new ShaderSource({ defines : ['RENDER_FOR_PICK'], @@ -1627,6 +1655,7 @@ define([ this._compiledShaderTranslucencyByDistancePick = this._shaderTranslucencyByDistance; this._compiledShaderPixelOffsetScaleByDistancePick = this._shaderPixelOffsetScaleByDistance; this._compiledShaderDistanceDisplayConditionPick = this._shaderDistanceDisplayCondition; + this._compiledShaderDisableDepthDistancePick = this._shaderDisableDepthDistance; } var va; diff --git a/Source/Scene/FrameState.js b/Source/Scene/FrameState.js index d852e14c1bfc..6cd842411391 100644 --- a/Source/Scene/FrameState.js +++ b/Source/Scene/FrameState.js @@ -256,6 +256,14 @@ define([ * @type {Color} */ this.backgroundColor = undefined; + + /** + * The distance from the camera at which to disable the depth test of billboards, labels and points + * to, for example, prevent clipping against terrain. When set to zero, the depth test should always + * be applied. When less than zero, the depth test should never be applied. + * @type {Number} + */ + this.minimumDisableDepthTestDistance = undefined; } /** diff --git a/Source/Scene/Label.js b/Source/Scene/Label.js index 3fe84a1b5057..1d3b4803684a 100644 --- a/Source/Scene/Label.js +++ b/Source/Scene/Label.js @@ -81,6 +81,9 @@ define([ if (defined(options.distanceDisplayCondition) && options.distanceDisplayCondition.far <= options.distanceDisplayCondition.near) { throw new DeveloperError('distanceDisplayCondition.far must be greater than distanceDisplayCondition.near'); } + if (defined(options.disableDepthTestDistance) && options.disableDepthTestDistance < 0.0) { + throw new DeveloperError('disableDepthTestDistance must be greater than 0.0.'); + } //>>includeEnd('debug'); this._text = defaultValue(options.text, ''); @@ -105,6 +108,7 @@ define([ this._scaleByDistance = options.scaleByDistance; this._heightReference = defaultValue(options.heightReference, HeightReference.NONE); this._distanceDisplayCondition = options.distanceDisplayCondition; + this._disableDepthTestDistance = defaultValue(options.disableDepthTestDistance, 0.0); this._labelCollection = labelCollection; this._glyphs = []; @@ -884,6 +888,41 @@ define([ } }, + /** + * Gets or sets the distance from the camera at which to disable the depth test to, for example, prevent clipping against terrain. + * When set to zero, the depth test is always applied. When set to Number.POSITIVE_INFINITY, the depth test is never applied. + * @memberof Label.prototype + * @type {Number} + * @default 0.0 + */ + disableDepthTestDistance : { + get : function() { + return this._disableDepthTestDistance; + }, + set : function(value) { + if (this._disableDepthTestDistance !== value) { + //>>includeStart('debug', pragmas.debug); + if (!defined(value) || value < 0.0) { + throw new DeveloperError('disableDepthTestDistance must be greater than 0.0.'); + } + //>>includeEnd('debug'); + this._disableDepthTestDistance = value; + + var glyphs = this._glyphs; + for (var i = 0, len = glyphs.length; i < len; i++) { + var glyph = glyphs[i]; + if (defined(glyph.billboard)) { + glyph.billboard.disableDepthTestDistance = value; + } + } + var backgroundBillboard = this._backgroundBillboard; + if (defined(backgroundBillboard)) { + backgroundBillboard.disableDepthTestDistance = value; + } + } + } + }, + /** * Gets or sets the user-defined object returned when the label is picked. * @memberof Label.prototype @@ -1124,6 +1163,7 @@ define([ NearFarScalar.equals(this._pixelOffsetScaleByDistance, other._pixelOffsetScaleByDistance) && NearFarScalar.equals(this._scaleByDistance, other._scaleByDistance) && DistanceDisplayCondition.equals(this._distanceDisplayCondition, other._distanceDisplayCondition) && + this._disableDepthTestDistance === other._disableDepthTestDistance && this._id === other._id; }; diff --git a/Source/Scene/LabelCollection.js b/Source/Scene/LabelCollection.js index 9f3763f94586..817306b0974c 100644 --- a/Source/Scene/LabelCollection.js +++ b/Source/Scene/LabelCollection.js @@ -171,6 +171,7 @@ define([ backgroundBillboard.pixelOffsetScaleByDistance = label._pixelOffsetScaleByDistance; backgroundBillboard.scaleByDistance = label._scaleByDistance; backgroundBillboard.distanceDisplayCondition = label._distanceDisplayCondition; + backgroundBillboard.disableDepthTestDistance = label._disableDepthTestDistance; } var glyphTextureCache = labelCollection._glyphTextureCache; @@ -264,6 +265,7 @@ define([ billboard.pixelOffsetScaleByDistance = label._pixelOffsetScaleByDistance; billboard.scaleByDistance = label._scaleByDistance; billboard.distanceDisplayCondition = label._distanceDisplayCondition; + billboard.disableDepthTestDistance = label._disableDepthTestDistance; } } diff --git a/Source/Scene/PointPrimitive.js b/Source/Scene/PointPrimitive.js index cf2ca7323b17..a6be423d2071 100644 --- a/Source/Scene/PointPrimitive.js +++ b/Source/Scene/PointPrimitive.js @@ -69,6 +69,9 @@ define([ if (defined(options.distanceDisplayCondition) && options.distanceDisplayCondition.far <= options.distanceDisplayCondition.near) { throw new DeveloperError('distanceDisplayCondition.far must be greater than distanceDisplayCondition.near'); } + if (defined(options.disableDepthTestDistance) && options.disableDepthTestDistance < 0.0) { + throw new DeveloperError('disableDepthTestDistance must be greater than or equal to 0.0.'); + } //>>includeEnd('debug'); this._show = defaultValue(options.show, true); @@ -81,6 +84,7 @@ define([ this._scaleByDistance = options.scaleByDistance; this._translucencyByDistance = options.translucencyByDistance; this._distanceDisplayCondition = options.distanceDisplayCondition; + this._disableDepthTestDistance = defaultValue(options.disableDepthTestDistance, 0.0); this._id = options.id; this._collection = defaultValue(options.collection, pointPrimitiveCollection); @@ -100,8 +104,9 @@ define([ var PIXEL_SIZE_INDEX = PointPrimitive.PIXEL_SIZE_INDEX = 5; var SCALE_BY_DISTANCE_INDEX = PointPrimitive.SCALE_BY_DISTANCE_INDEX = 6; var TRANSLUCENCY_BY_DISTANCE_INDEX = PointPrimitive.TRANSLUCENCY_BY_DISTANCE_INDEX = 7; - var DISTANCE_DISPLAY_CONDITION_INDEX = PointPrimitive.DISTANCE_DISPLAY_CONDITION = 8; - PointPrimitive.NUMBER_OF_PROPERTIES = 9; + var DISTANCE_DISPLAY_CONDITION_INDEX = PointPrimitive.DISTANCE_DISPLAY_CONDITION_INDEX = 8; + var DISABLE_DEPTH_DISTANCE_INDEX = PointPrimitive.DISABLE_DEPTH_DISTANCE_INDEX = 9; + PointPrimitive.NUMBER_OF_PROPERTIES = 10; function makeDirty(pointPrimitive, propertyChanged) { var pointPrimitiveCollection = pointPrimitive._pointPrimitiveCollection; @@ -374,6 +379,30 @@ define([ } }, + /** + * Gets or sets the distance from the camera at which to disable the depth test to, for example, prevent clipping against terrain. + * When set to zero, the depth test is always applied. When set to Number.POSITIVE_INFINITY, the depth test is never applied. + * @memberof PointPrimitive.prototype + * @type {Number} + * @default 0.0 + */ + disableDepthTestDistance : { + get : function() { + return this._disableDepthTestDistance; + }, + set : function(value) { + if (this._disableDepthTestDistance !== value) { + //>>includeStart('debug', pragmas.debug); + if (!defined(value) || value < 0.0) { + throw new DeveloperError('disableDepthTestDistance must be greater than or equal to 0.0.'); + } + //>>includeEnd('debug'); + this._disableDepthTestDistance = value; + makeDirty(this, DISABLE_DEPTH_DISTANCE_INDEX); + } + } + }, + /** * Gets or sets the user-defined object returned when the point is picked. * @memberof PointPrimitive.prototype @@ -539,7 +568,8 @@ define([ Color.equals(this._outlineColor, other._outlineColor) && NearFarScalar.equals(this._scaleByDistance, other._scaleByDistance) && NearFarScalar.equals(this._translucencyByDistance, other._translucencyByDistance) && - DistanceDisplayCondition.equals(this._distanceDisplayCondition, other._distanceDisplayCondition); + DistanceDisplayCondition.equals(this._distanceDisplayCondition, other._distanceDisplayCondition) && + this._disableDepthTestDistance === other._disableDepthTestDistance; }; PointPrimitive.prototype._destroy = function() { diff --git a/Source/Scene/PointPrimitiveCollection.js b/Source/Scene/PointPrimitiveCollection.js index a00d101618d5..9dd0d4bd690c 100644 --- a/Source/Scene/PointPrimitiveCollection.js +++ b/Source/Scene/PointPrimitiveCollection.js @@ -66,6 +66,7 @@ define([ var SCALE_BY_DISTANCE_INDEX = PointPrimitive.SCALE_BY_DISTANCE_INDEX; var TRANSLUCENCY_BY_DISTANCE_INDEX = PointPrimitive.TRANSLUCENCY_BY_DISTANCE_INDEX; var DISTANCE_DISPLAY_CONDITION_INDEX = PointPrimitive.DISTANCE_DISPLAY_CONDITION_INDEX; + var DISABLE_DEPTH_DISTANCE_INDEX = PointPrimitive.DISABLE_DEPTH_DISTANCE_INDEX; var NUMBER_OF_PROPERTIES = PointPrimitive.NUMBER_OF_PROPERTIES; var attributeLocations = { @@ -74,7 +75,7 @@ define([ compressedAttribute0 : 2, // color, outlineColor, pick color compressedAttribute1 : 3, // show, translucency by distance, some free space scaleByDistance : 4, - distanceDisplayCondition : 5 + distanceDisplayConditionAndDisableDepth : 5 }; /** @@ -144,6 +145,10 @@ define([ this._compiledShaderDistanceDisplayCondition = false; this._compiledShaderDistanceDisplayConditionPick = false; + this._shaderDisableDepthDistance = false; + this._compiledShaderDisableDepthDistance = false; + this._compiledShaderDisableDepthDistancePick = false; + this._propertiesChanged = new Uint32Array(NUMBER_OF_PROPERTIES); this._maxPixelSize = 1.0; @@ -489,8 +494,8 @@ define([ componentDatatype : ComponentDatatype.FLOAT, usage : buffersUsage[SCALE_BY_DISTANCE_INDEX] }, { - index : attributeLocations.distanceDisplayCondition, - componentsPerAttribute : 2, + index : attributeLocations.distanceDisplayConditionAndDisableDepth, + componentsPerAttribute : 3, componentDatatype : ComponentDatatype.FLOAT, usage : buffersUsage[DISTANCE_DISPLAY_CONDITION_INDEX] }], numberOfPointPrimitives); // 1 vertex per pointPrimitive @@ -628,9 +633,9 @@ define([ writer(i, near, nearValue, far, farValue); } - function writeDistanceDisplayCondition(pointPrimitiveCollection, context, vafWriters, pointPrimitive) { + function writeDistanceDisplayConditionAndDepthDisable(pointPrimitiveCollection, context, vafWriters, pointPrimitive) { var i = pointPrimitive._index; - var writer = vafWriters[attributeLocations.distanceDisplayCondition]; + var writer = vafWriters[attributeLocations.distanceDisplayConditionAndDisableDepth]; var near = 0.0; var far = Number.MAX_VALUE; @@ -638,10 +643,23 @@ define([ if (defined(distanceDisplayCondition)) { near = distanceDisplayCondition.near; far = distanceDisplayCondition.far; + + near *= near; + far *= far; + pointPrimitiveCollection._shaderDistanceDisplayCondition = true; } - writer(i, near, far); + var disableDepthTestDistance = pointPrimitive.disableDepthTestDistance; + disableDepthTestDistance *= disableDepthTestDistance; + if (disableDepthTestDistance > 0.0) { + pointPrimitiveCollection._shaderDisableDepthDistance = true; + if (disableDepthTestDistance === Number.POSITIVE_INFINITY) { + disableDepthTestDistance = -1.0; + } + } + + writer(i, near, far, disableDepthTestDistance); } function writePointPrimitive(pointPrimitiveCollection, context, vafWriters, pointPrimitive) { @@ -649,7 +667,7 @@ define([ writeCompressedAttrib0(pointPrimitiveCollection, context, vafWriters, pointPrimitive); writeCompressedAttrib1(pointPrimitiveCollection, context, vafWriters, pointPrimitive); writeScaleByDistance(pointPrimitiveCollection, context, vafWriters, pointPrimitive); - writeDistanceDisplayCondition(pointPrimitiveCollection, context, vafWriters, pointPrimitive); + writeDistanceDisplayConditionAndDepthDisable(pointPrimitiveCollection, context, vafWriters, pointPrimitive); } function recomputeActualPositions(pointPrimitiveCollection, pointPrimitives, length, frameState, modelMatrix, recomputeBoundingVolume) { @@ -788,8 +806,8 @@ define([ writers.push(writeScaleByDistance); } - if (properties[DISTANCE_DISPLAY_CONDITION_INDEX]) { - writers.push(writeDistanceDisplayCondition); + if (properties[DISTANCE_DISPLAY_CONDITION_INDEX] || properties[DISABLE_DEPTH_DISTANCE_INDEX]) { + writers.push(writeDistanceDisplayConditionAndDepthDisable); } var numWriters = writers.length; @@ -883,10 +901,13 @@ define([ } } + this._shaderDisableDepthDistance = this._shaderDisableDepthDistance || frameState.minimumDisableDepthTestDistance !== 0.0; + if (blendOptionChanged || (this._shaderScaleByDistance && !this._compiledShaderScaleByDistance) || (this._shaderTranslucencyByDistance && !this._compiledShaderTranslucencyByDistance) || - (this._shaderDistanceDisplayCondition && !this._compiledShaderDistanceDisplayCondition)) { + (this._shaderDistanceDisplayCondition && !this._compiledShaderDistanceDisplayCondition) || + (this._shaderDisableDepthDistance !== this._compiledShaderDisableDepthDistance)) { vs = new ShaderSource({ sources : [PointPrimitiveCollectionVS] @@ -900,6 +921,9 @@ define([ if (this._shaderDistanceDisplayCondition) { vs.defines.push('DISTANCE_DISPLAY_CONDITION'); } + if (this._shaderDisableDepthDistance) { + vs.defines.push('DISABLE_DEPTH_DISTANCE'); + } if (this._blendOption === BlendOption.OPAQUE_AND_TRANSLUCENT) { fs = new ShaderSource({ @@ -956,12 +980,14 @@ define([ this._compiledShaderScaleByDistance = this._shaderScaleByDistance; this._compiledShaderTranslucencyByDistance = this._shaderTranslucencyByDistance; this._compiledShaderDistanceDisplayCondition = this._shaderDistanceDisplayCondition; + this._compiledShaderDisableDepthDistance = this._shaderDisableDepthDistance; } if (!defined(this._spPick) || (this._shaderScaleByDistance && !this._compiledShaderScaleByDistancePick) || (this._shaderTranslucencyByDistance && !this._compiledShaderTranslucencyByDistancePick) || - (this._shaderDistanceDisplayCondition && !this._compiledShaderDistanceDisplayConditionPick)) { + (this._shaderDistanceDisplayCondition && !this._compiledShaderDistanceDisplayConditionPick) || + (this._shaderDisableDepthDistance !== this._compiledShaderDisableDepthDistancePick)) { vs = new ShaderSource({ defines : ['RENDER_FOR_PICK'], @@ -977,6 +1003,9 @@ define([ if (this._shaderDistanceDisplayCondition) { vs.defines.push('DISTANCE_DISPLAY_CONDITION'); } + if (this._shaderDisableDepthDistance) { + vs.defines.push('DISABLE_DEPTH_DISTANCE'); + } fs = new ShaderSource({ defines : ['RENDER_FOR_PICK'], @@ -994,6 +1023,7 @@ define([ this._compiledShaderScaleByDistancePick = this._shaderScaleByDistance; this._compiledShaderTranslucencyByDistancePick = this._shaderTranslucencyByDistance; this._compiledShaderDistanceDisplayConditionPick = this._shaderDistanceDisplayCondition; + this._compiledShaderDisableDepthDistancePick = this._shaderDisableDepthDistance; } var va; diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 3cb81ea8ba6f..33b8cfec3b26 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -321,6 +321,8 @@ define([ this._cameraStartFired = false; this._cameraMovedTime = undefined; + this._minimumDisableDepthTestDistance = 0.0; + /** * Exceptions occurring in render are always caught in order to raise the * renderError event. If this property is true, the error is rethrown @@ -1141,10 +1143,32 @@ define([ get: function() { return this._frameState.imagerySplitPosition; }, - set: function(value) { this._frameState.imagerySplitPosition = value; } + }, + + /** + * The distance from the camera at which to disable the depth test of billboards, labels and points + * to, for example, prevent clipping against terrain. When set to zero, the depth test should always + * be applied. When less than zero, the depth test should never be applied. Setting the disableDepthTestDistance + * property of a billboard, label or point will override this value. + * @memberof Scene.prototype + * @type {Number} + * @default 0.0 + */ + minimumDisableDepthTestDistance : { + get : function() { + return this._minimumDisableDepthTestDistance; + }, + set : function(value) { + //>>includeStart('debug', pragmas.debug); + if (!defined(value) || value < 0.0) { + throw new DeveloperError('minimumDisableDepthTestDistance must be greater than or equal to 0.0.'); + } + //>>includeEnd('debug'); + this._minimumDisableDepthTestDistance = value; + } } }); @@ -1257,6 +1281,7 @@ define([ frameState.cullingVolume = camera.frustum.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC); frameState.occluder = getOccluder(scene); frameState.terrainExaggeration = scene._terrainExaggeration; + frameState.minimumDisableDepthTestDistance = scene._minimumDisableDepthTestDistance; if (defined(scene.globe)) { frameState.maximumScreenSpaceError = scene.globe.maximumScreenSpaceError; } else { diff --git a/Source/Shaders/BillboardCollectionVS.glsl b/Source/Shaders/BillboardCollectionVS.glsl index e9448a6cdf69..2757474d9787 100644 --- a/Source/Shaders/BillboardCollectionVS.glsl +++ b/Source/Shaders/BillboardCollectionVS.glsl @@ -3,13 +3,13 @@ attribute vec2 direction; #endif attribute vec4 positionHighAndScale; attribute vec4 positionLowAndRotation; -attribute vec4 compressedAttribute0; // pixel offset, translate, horizontal origin, vertical origin, show, direction, texture coordinates (texture offset) -attribute vec4 compressedAttribute1; // aligned axis, translucency by distance, image width -attribute vec4 compressedAttribute2; // image height, color, pick color, size in meters, valid aligned axis, 13 bits free -attribute vec4 eyeOffset; // eye offset in meters, 4 bytes free (texture range) -attribute vec4 scaleByDistance; // near, nearScale, far, farScale -attribute vec4 pixelOffsetScaleByDistance; // near, nearScale, far, farScale -attribute vec2 distanceDisplayCondition; // near, far +attribute vec4 compressedAttribute0; // pixel offset, translate, horizontal origin, vertical origin, show, direction, texture coordinates (texture offset) +attribute vec4 compressedAttribute1; // aligned axis, translucency by distance, image width +attribute vec4 compressedAttribute2; // image height, color, pick color, size in meters, valid aligned axis, 13 bits free +attribute vec4 eyeOffset; // eye offset in meters, 4 bytes free (texture range) +attribute vec4 scaleByDistance; // near, nearScale, far, farScale +attribute vec4 pixelOffsetScaleByDistance; // near, nearScale, far, farScale +attribute vec3 distanceDisplayConditionAndDisableDepth; // near, far, disableDepthTestDistance varying vec2 v_textureCoordinates; @@ -205,7 +205,7 @@ void main() /////////////////////////////////////////////////////////////////////////// -#if defined(EYE_DISTANCE_SCALING) || defined(EYE_DISTANCE_TRANSLUCENCY) || defined(EYE_DISTANCE_PIXEL_OFFSET) || defined(DISTANCE_DISPLAY_CONDITION) +#if defined(EYE_DISTANCE_SCALING) || defined(EYE_DISTANCE_TRANSLUCENCY) || defined(EYE_DISTANCE_PIXEL_OFFSET) || defined(DISTANCE_DISPLAY_CONDITION) || defined(DISABLE_DEPTH_DISTANCE) float lengthSq; if (czm_sceneMode == czm_sceneMode2D) { @@ -246,8 +246,8 @@ void main() #endif #ifdef DISTANCE_DISPLAY_CONDITION - float nearSq = distanceDisplayCondition.x * distanceDisplayCondition.x; - float farSq = distanceDisplayCondition.y * distanceDisplayCondition.y; + float nearSq = distanceDisplayConditionAndDisableDepth.x; + float farSq = distanceDisplayConditionAndDisableDepth.y; if (lengthSq < nearSq || lengthSq > farSq) { positionEC.xyz = vec3(0.0); @@ -258,6 +258,25 @@ void main() gl_Position = czm_viewportOrthographic * vec4(positionWC.xy, -positionWC.z, 1.0); v_textureCoordinates = textureCoordinates; +#ifdef DISABLE_DEPTH_DISTANCE + float disableDepthTestDistance = distanceDisplayConditionAndDisableDepth.z; + if (disableDepthTestDistance == 0.0 && czm_minimumDisableDepthTestDistance != 0.0) + { + disableDepthTestDistance = czm_minimumDisableDepthTestDistance; + } + + if (disableDepthTestDistance != 0.0) + { + gl_Position.z = min(gl_Position.z, gl_Position.w); + + bool clipped = gl_Position.z < -gl_Position.w || gl_Position.z > gl_Position.w; + if (!clipped && (disableDepthTestDistance < 0.0 || (lengthSq > 0.0 && lengthSq < disableDepthTestDistance))) + { + gl_Position.z = -gl_Position.w; + } + } +#endif + #ifdef RENDER_FOR_PICK v_pickColor = pickColor; #else diff --git a/Source/Shaders/PointPrimitiveCollectionVS.glsl b/Source/Shaders/PointPrimitiveCollectionVS.glsl index a11ea4b95f6b..cdb0fa4faf4c 100644 --- a/Source/Shaders/PointPrimitiveCollectionVS.glsl +++ b/Source/Shaders/PointPrimitiveCollectionVS.glsl @@ -2,10 +2,10 @@ uniform float u_maxTotalPointSize; attribute vec4 positionHighAndSize; attribute vec4 positionLowAndOutline; -attribute vec4 compressedAttribute0; // color, outlineColor, pick color -attribute vec4 compressedAttribute1; // show, translucency by distance, some free space -attribute vec4 scaleByDistance; // near, nearScale, far, farScale -attribute vec2 distanceDisplayCondition; // near, far +attribute vec4 compressedAttribute0; // color, outlineColor, pick color +attribute vec4 compressedAttribute1; // show, translucency by distance, some free space +attribute vec4 scaleByDistance; // near, nearScale, far, farScale +attribute vec3 distanceDisplayConditionAndDisableDepth; // near, far, disableDepthTestDistance varying vec4 v_color; varying vec4 v_outlineColor; @@ -102,7 +102,7 @@ void main() /////////////////////////////////////////////////////////////////////////// -#if defined(EYE_DISTANCE_SCALING) || defined(EYE_DISTANCE_TRANSLUCENCY) || defined(DISTANCE_DISPLAY_CONDITION) +#if defined(EYE_DISTANCE_SCALING) || defined(EYE_DISTANCE_TRANSLUCENCY) || defined(DISTANCE_DISPLAY_CONDITION) || defined(DISABLE_DEPTH_DISTANCE) float lengthSq; if (czm_sceneMode == czm_sceneMode2D) { @@ -140,8 +140,8 @@ void main() #endif #ifdef DISTANCE_DISPLAY_CONDITION - float nearSq = distanceDisplayCondition.x * distanceDisplayCondition.x; - float farSq = distanceDisplayCondition.y * distanceDisplayCondition.y; + float nearSq = distanceDisplayConditionAndDisableDepth.x; + float farSq = distanceDisplayConditionAndDisableDepth.y; if (lengthSq < nearSq || lengthSq > farSq) { positionEC.xyz = vec3(0.0); } @@ -151,6 +151,25 @@ void main() gl_Position = czm_viewportOrthographic * vec4(positionWC.xy, -positionWC.z, 1.0); +#ifdef DISABLE_DEPTH_DISTANCE + float disableDepthTestDistance = distanceDisplayConditionAndDisableDepth.z; + if (disableDepthTestDistance == 0.0 && czm_minimumDisableDepthTestDistance != 0.0) + { + disableDepthTestDistance = czm_minimumDisableDepthTestDistance; + } + + if (disableDepthTestDistance != 0.0) + { + gl_Position.z = min(gl_Position.z, gl_Position.w); + + bool clipped = gl_Position.z < -gl_Position.w || gl_Position.z > gl_Position.w; + if (!clipped && (disableDepthTestDistance < 0.0 || (lengthSq > 0.0 && lengthSq < disableDepthTestDistance))) + { + gl_Position.z = -gl_Position.w; + } + } +#endif + v_color = color; v_color.a *= translucency; v_outlineColor = outlineColor; diff --git a/Specs/DataSources/BillboardGraphicsSpec.js b/Specs/DataSources/BillboardGraphicsSpec.js index efdbb17cb80d..a8a9ef615111 100644 --- a/Specs/DataSources/BillboardGraphicsSpec.js +++ b/Specs/DataSources/BillboardGraphicsSpec.js @@ -42,7 +42,8 @@ defineSuite([ translucencyByDistance : new NearFarScalar(17, 18, 19, 20), pixelOffsetScaleByDistance : new NearFarScalar(21, 22, 23, 24), sizeInMeters : true, - distanceDisplayCondition : new DistanceDisplayCondition(10.0, 100.0) + distanceDisplayCondition : new DistanceDisplayCondition(10.0, 100.0), + disableDepthTestDistance : 10.0 }; var billboard = new BillboardGraphics(options); @@ -63,6 +64,7 @@ defineSuite([ expect(billboard.pixelOffsetScaleByDistance).toBeInstanceOf(ConstantProperty); expect(billboard.sizeInMeters).toBeInstanceOf(ConstantProperty); expect(billboard.distanceDisplayCondition).toBeInstanceOf(ConstantProperty); + expect(billboard.disableDepthTestDistance).toBeInstanceOf(ConstantProperty); expect(billboard.image.getValue()).toEqual(options.image); expect(billboard.rotation.getValue()).toEqual(options.rotation); @@ -81,6 +83,7 @@ defineSuite([ expect(billboard.pixelOffsetScaleByDistance.getValue()).toEqual(options.pixelOffsetScaleByDistance); expect(billboard.sizeInMeters.getValue()).toEqual(options.sizeInMeters); expect(billboard.distanceDisplayCondition.getValue()).toEqual(options.distanceDisplayCondition); + expect(billboard.disableDepthTestDistance.getValue()).toEqual(options.disableDepthTestDistance); }); it('merge assigns unassigned properties', function() { @@ -104,6 +107,7 @@ defineSuite([ source.pixelOffsetScaleByDistance = new ConstantProperty(new NearFarScalar(1.0, 0.0, 3.0e9, 0.0)); source.sizeInMeters = new ConstantProperty(true); source.distanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition(10.0, 100.0)); + source.disableDepthTestDistance = 10.0; var target = new BillboardGraphics(); target.merge(source); @@ -127,6 +131,7 @@ defineSuite([ expect(target.pixelOffsetScaleByDistance).toBe(source.pixelOffsetScaleByDistance); expect(target.sizeInMeters).toBe(source.sizeInMeters); expect(target.distanceDisplayCondition).toBe(source.distanceDisplayCondition); + expect(target.disableDepthTestDistance).toBe(source.disableDepthTestDistance); }); it('merge does not assign assigned properties', function() { @@ -150,6 +155,7 @@ defineSuite([ source.pixelOffsetScaleByDistance = new ConstantProperty(new NearFarScalar(1.0, 0.0, 3.0e9, 0.0)); source.sizeInMeters = new ConstantProperty(true); source.distanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition(10.0, 100.0)); + source.disableDepthTestDistance = new ConstantProperty(10.0); var image = new ConstantProperty(''); var imageSubRegion = new ConstantProperty(); @@ -170,6 +176,7 @@ defineSuite([ var pixelOffsetScaleByDistance = new ConstantProperty(new NearFarScalar()); var sizeInMeters = new ConstantProperty(true); var distanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition()); + var disableDepthTestDistance = new ConstantProperty(10.0); var target = new BillboardGraphics(); target.image = image; @@ -191,6 +198,7 @@ defineSuite([ target.pixelOffsetScaleByDistance = pixelOffsetScaleByDistance; target.sizeInMeters = sizeInMeters; target.distanceDisplayCondition = distanceDisplayCondition; + target.disableDepthTestDistance = disableDepthTestDistance; target.merge(source); @@ -213,6 +221,7 @@ defineSuite([ expect(target.pixelOffsetScaleByDistance).toBe(pixelOffsetScaleByDistance); expect(target.sizeInMeters).toBe(sizeInMeters); expect(target.distanceDisplayCondition).toBe(distanceDisplayCondition); + expect(target.disableDepthTestDistance).toBe(disableDepthTestDistance); }); it('clone works', function() { @@ -236,6 +245,7 @@ defineSuite([ source.pixelOffsetScaleByDistance = new ConstantProperty(new NearFarScalar(1.0, 0.0, 3.0e9, 0.0)); source.sizeInMeters = new ConstantProperty(true); source.distanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition(10.0, 100.0)); + source.disableDepthTestDistance = new ConstantProperty(10.0); var result = source.clone(); expect(result.image).toBe(source.image); @@ -257,6 +267,7 @@ defineSuite([ expect(result.pixelOffsetScaleByDistance).toBe(source.pixelOffsetScaleByDistance); expect(result.sizeInMeters).toBe(source.sizeInMeters); expect(result.distanceDisplayCondition).toBe(source.distanceDisplayCondition); + expect(result.disableDepthTestDistance).toBe(source.disableDepthTestDistance); }); it('merge throws if source undefined', function() { diff --git a/Specs/DataSources/BillboardVisualizerSpec.js b/Specs/DataSources/BillboardVisualizerSpec.js index d802621455e7..8ac829b2344e 100644 --- a/Specs/DataSources/BillboardVisualizerSpec.js +++ b/Specs/DataSources/BillboardVisualizerSpec.js @@ -163,6 +163,7 @@ defineSuite([ billboard.pixelOffsetScaleByDistance = new ConstantProperty(new NearFarScalar(1.0, 0.0, 3.0e9, 0.0)); billboard.sizeInMeters = new ConstantProperty(true); billboard.distanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition(10.0, 100.0)); + billboard.disableDepthTestDistance = new ConstantProperty(10.0); visualizer.update(time); @@ -191,6 +192,7 @@ defineSuite([ expect(bb.pixelOffsetScaleByDistance).toEqual(testObject.billboard.pixelOffsetScaleByDistance.getValue(time)); expect(bb.sizeInMeters).toEqual(testObject.billboard.sizeInMeters.getValue(time)); expect(bb.distanceDisplayCondition).toEqual(testObject.billboard.distanceDisplayCondition.getValue(time)); + expect(bb.disableDepthTestDistance).toEqual(testObject.billboard.disableDepthTestDistance.getValue(time)); expect(bb._imageSubRegion).toEqual(testObject.billboard.imageSubRegion.getValue(time)); billboard.show = new ConstantProperty(false); @@ -232,6 +234,7 @@ defineSuite([ billboard.pixelOffsetScaleByDistance = new ConstantProperty(new NearFarScalar(1.0, 0.0, 3.0e9, 0.0)); billboard.sizeInMeters = new ConstantProperty(true); billboard.distanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition(10.0, 100.0)); + billboard.disableDepthTestDistance = new ConstantProperty(10.0); visualizer.update(time); @@ -250,32 +253,33 @@ defineSuite([ visualizer.update(time); return !bb.show; }).then(function() { - billboard.show = new ConstantProperty(true); - - return pollToPromise(function() { - visualizer.update(time); - return bb.show; - }).then(function() { - expect(bb.position).toEqual(testObject.position.getValue(time)); - expect(bb.color).toEqual(testObject.billboard.color.getValue(time)); - expect(bb.eyeOffset).toEqual(testObject.billboard.eyeOffset.getValue(time)); - expect(bb.scale).toEqual(testObject.billboard.scale.getValue(time)); - expect(bb.rotation).toEqual(testObject.billboard.rotation.getValue(time)); - expect(bb.alignedAxis).toEqual(testObject.billboard.alignedAxis.getValue(time)); - expect(bb.heightReference).toEqual(testObject.billboard.heightReference.getValue(time)); - expect(bb.horizontalOrigin).toEqual(testObject.billboard.horizontalOrigin.getValue(time)); - expect(bb.verticalOrigin).toEqual(testObject.billboard.verticalOrigin.getValue(time)); - expect(bb.width).toEqual(testObject.billboard.width.getValue(time)); - expect(bb.height).toEqual(testObject.billboard.height.getValue(time)); - expect(bb.scaleByDistance).toEqual(testObject.billboard.scaleByDistance.getValue(time)); - expect(bb.translucencyByDistance).toEqual(testObject.billboard.translucencyByDistance.getValue(time)); - expect(bb.pixelOffsetScaleByDistance).toEqual(testObject.billboard.pixelOffsetScaleByDistance.getValue(time)); - expect(bb.sizeInMeters).toEqual(testObject.billboard.sizeInMeters.getValue(time)); - expect(bb.distanceDisplayCondition).toEqual(testObject.billboard.distanceDisplayCondition.getValue(time)); - expect(bb.image).toBeDefined(); - expect(bb._imageSubRegion).toEqual(testObject.billboard.imageSubRegion.getValue(time)); - }); - }); + billboard.show = new ConstantProperty(true); + + return pollToPromise(function() { + visualizer.update(time); + return bb.show; + }).then(function() { + expect(bb.position).toEqual(testObject.position.getValue(time)); + expect(bb.color).toEqual(testObject.billboard.color.getValue(time)); + expect(bb.eyeOffset).toEqual(testObject.billboard.eyeOffset.getValue(time)); + expect(bb.scale).toEqual(testObject.billboard.scale.getValue(time)); + expect(bb.rotation).toEqual(testObject.billboard.rotation.getValue(time)); + expect(bb.alignedAxis).toEqual(testObject.billboard.alignedAxis.getValue(time)); + expect(bb.heightReference).toEqual(testObject.billboard.heightReference.getValue(time)); + expect(bb.horizontalOrigin).toEqual(testObject.billboard.horizontalOrigin.getValue(time)); + expect(bb.verticalOrigin).toEqual(testObject.billboard.verticalOrigin.getValue(time)); + expect(bb.width).toEqual(testObject.billboard.width.getValue(time)); + expect(bb.height).toEqual(testObject.billboard.height.getValue(time)); + expect(bb.scaleByDistance).toEqual(testObject.billboard.scaleByDistance.getValue(time)); + expect(bb.translucencyByDistance).toEqual(testObject.billboard.translucencyByDistance.getValue(time)); + expect(bb.pixelOffsetScaleByDistance).toEqual(testObject.billboard.pixelOffsetScaleByDistance.getValue(time)); + expect(bb.sizeInMeters).toEqual(testObject.billboard.sizeInMeters.getValue(time)); + expect(bb.distanceDisplayCondition).toEqual(testObject.billboard.distanceDisplayCondition.getValue(time)); + expect(bb.disableDepthTestDistance).toEqual(testObject.billboard.disableDepthTestDistance.getValue(time)); + expect(bb.image).toBeDefined(); + expect(bb._imageSubRegion).toEqual(testObject.billboard.imageSubRegion.getValue(time)); + }); + }); }); }); diff --git a/Specs/DataSources/LabelGraphicsSpec.js b/Specs/DataSources/LabelGraphicsSpec.js index d210b3035904..70e9d6c9c3f7 100644 --- a/Specs/DataSources/LabelGraphicsSpec.js +++ b/Specs/DataSources/LabelGraphicsSpec.js @@ -40,7 +40,8 @@ defineSuite([ translucencyByDistance : new NearFarScalar(9, 10, 11, 12), pixelOffsetScaleByDistance : new NearFarScalar(13, 14, 15, 16), scaleByDistance : new NearFarScalar(17, 18, 19, 20), - distanceDisplayCondition : new DistanceDisplayCondition(10.0, 100.0) + distanceDisplayCondition : new DistanceDisplayCondition(10.0, 100.0), + disableDepthTestDistance : 10.0 }; var label = new LabelGraphics(options); @@ -59,6 +60,7 @@ defineSuite([ expect(label.pixelOffsetScaleByDistance).toBeInstanceOf(ConstantProperty); expect(label.scaleByDistance).toBeInstanceOf(ConstantProperty); expect(label.distanceDisplayCondition).toBeInstanceOf(ConstantProperty); + expect(label.disableDepthTestDistance).toBeInstanceOf(ConstantProperty); expect(label.text.getValue()).toEqual(options.text); expect(label.font.getValue()).toEqual(options.font); @@ -75,6 +77,7 @@ defineSuite([ expect(label.pixelOffsetScaleByDistance.getValue()).toEqual(options.pixelOffsetScaleByDistance); expect(label.scaleByDistance.getValue()).toEqual(options.scaleByDistance); expect(label.distanceDisplayCondition.getValue()).toEqual(options.distanceDisplayCondition); + expect(label.disableDepthTestDistance.getValue()).toEqual(options.disableDepthTestDistance); }); it('merge assigns unassigned properties', function() { @@ -95,6 +98,7 @@ defineSuite([ source.pixelOffsetScaleByDistance = new ConstantProperty(new NearFarScalar(1.0, 0.0, 3.0e9, 0.0)); source.scaleByDistance = new ConstantProperty(new NearFarScalar(1.0, 0.0, 3.0e9, 0.0)); source.distanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition(10.0, 100.0)); + source.disableDepthTestDistance = new ConstantProperty(10.0); var target = new LabelGraphics(); target.merge(source); @@ -115,6 +119,7 @@ defineSuite([ expect(target.pixelOffsetScaleByDistance).toBe(source.pixelOffsetScaleByDistance); expect(target.scaleByDistance).toBe(source.scaleByDistance); expect(target.distanceDisplayCondition).toBe(source.distanceDisplayCondition); + expect(target.disableDepthTestDistance).toBe(source.disableDepthTestDistance); }); it('merge does not assign assigned properties', function() { @@ -135,6 +140,7 @@ defineSuite([ source.pixelOffsetScaleByDistance = new ConstantProperty(new NearFarScalar(1.0, 0.0, 3.0e9, 0.0)); source.scaleByDistance = new ConstantProperty(new NearFarScalar(1.0, 0.0, 3.0e9, 0.0)); source.distanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition(10.0, 100.0)); + source.disableDepthTestDistance = new ConstantProperty(10.0); var text = new ConstantProperty('my text'); var font = new ConstantProperty('10px serif'); @@ -152,6 +158,7 @@ defineSuite([ var pixelOffsetScaleByDistance = new ConstantProperty(new NearFarScalar()); var scaleByDistance = new ConstantProperty(new NearFarScalar()); var distanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition()); + var disableDepthTestDistance = new ConstantProperty(20.0); var target = new LabelGraphics(); target.text = text; @@ -170,6 +177,7 @@ defineSuite([ target.pixelOffsetScaleByDistance = pixelOffsetScaleByDistance; target.scaleByDistance = scaleByDistance; target.distanceDisplayCondition = distanceDisplayCondition; + target.disableDepthTestDistance = disableDepthTestDistance; target.merge(source); @@ -189,6 +197,7 @@ defineSuite([ expect(target.pixelOffsetScaleByDistance).toBe(pixelOffsetScaleByDistance); expect(target.scaleByDistance).toBe(scaleByDistance); expect(target.distanceDisplayCondition).toBe(distanceDisplayCondition); + expect(target.disableDepthTestDistance).toBe(disableDepthTestDistance); }); it('clone works', function() { @@ -209,6 +218,7 @@ defineSuite([ source.pixelOffsetScaleByDistance = new ConstantProperty(new NearFarScalar(1.0, 0.0, 3.0e9, 0.0)); source.scaleByDistance = new ConstantProperty(new NearFarScalar(1.0, 0.0, 3.0e9, 0.0)); source.distanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition(10.0, 100.0)); + source.disableDepthTestDistance = new ConstantProperty(10.0); var result = source.clone(); expect(result.text).toBe(source.text); @@ -227,6 +237,7 @@ defineSuite([ expect(result.pixelOffsetScaleByDistance).toBe(source.pixelOffsetScaleByDistance); expect(result.scaleByDistance).toBe(source.scaleByDistance); expect(result.distanceDisplayCondition).toBe(source.distanceDisplayCondition); + expect(result.disableDepthTestDistance).toBe(source.disableDepthTestDistance); }); it('merge throws if source undefined', function() { diff --git a/Specs/DataSources/LabelVisualizerSpec.js b/Specs/DataSources/LabelVisualizerSpec.js index 7805b4f18345..591f0fe84094 100644 --- a/Specs/DataSources/LabelVisualizerSpec.js +++ b/Specs/DataSources/LabelVisualizerSpec.js @@ -156,6 +156,7 @@ defineSuite([ label.pixelOffsetScaleByDistance = new ConstantProperty(new NearFarScalar()); label.scaleByDistance = new ConstantProperty(new NearFarScalar()); label.distanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition()); + label.disableDepthTestDistance = new ConstantProperty(10.0); visualizer.update(time); @@ -182,6 +183,7 @@ defineSuite([ expect(l.pixelOffsetScaleByDistance).toEqual(testObject.label.pixelOffsetScaleByDistance.getValue(time)); expect(l.scaleByDistance).toEqual(testObject.label.scaleByDistance.getValue(time)); expect(l.distanceDisplayCondition).toEqual(testObject.label.distanceDisplayCondition.getValue(time)); + expect(l.disableDepthTestDistance).toEqual(testObject.label.disableDepthTestDistance.getValue(time)); testObject.position = new ConstantProperty(new Cartesian3(5678, 1234, 1293434)); label.text = new ConstantProperty('b'); @@ -200,6 +202,7 @@ defineSuite([ label.pixelOffsetScaleByDistance = new ConstantProperty(new NearFarScalar()); label.scaleByDistance = new ConstantProperty(new NearFarScalar()); label.distanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition()); + label.disableDepthTestDistance = new ConstantProperty(20.0); visualizer.update(time); expect(l.position).toEqual(testObject.position.getValue(time)); @@ -219,6 +222,7 @@ defineSuite([ expect(l.pixelOffsetScaleByDistance).toEqual(testObject.label.pixelOffsetScaleByDistance.getValue(time)); expect(l.scaleByDistance).toEqual(testObject.label.scaleByDistance.getValue(time)); expect(l.distanceDisplayCondition).toEqual(testObject.label.distanceDisplayCondition.getValue(time)); + expect(l.disableDepthTestDistance).toEqual(testObject.label.disableDepthTestDistance.getValue(time)); label.show = new ConstantProperty(false); visualizer.update(time); diff --git a/Specs/DataSources/PointGraphicsSpec.js b/Specs/DataSources/PointGraphicsSpec.js index 912a67f2586c..5d57aba5f204 100644 --- a/Specs/DataSources/PointGraphicsSpec.js +++ b/Specs/DataSources/PointGraphicsSpec.js @@ -24,7 +24,8 @@ defineSuite([ show : false, scaleByDistance : new NearFarScalar(3, 4, 5, 6), heightReference : HeightReference.RELATIVE_TO_GROUND, - distanceDisplayCondition : new DistanceDisplayCondition(10.0, 100.0) + distanceDisplayCondition : new DistanceDisplayCondition(10.0, 100.0), + disableDepthTestDistance : 10.0 }; var point = new PointGraphics(options); @@ -36,6 +37,7 @@ defineSuite([ expect(point.scaleByDistance).toBeInstanceOf(ConstantProperty); expect(point.heightReference).toBeInstanceOf(ConstantProperty); expect(point.distanceDisplayCondition).toBeInstanceOf(ConstantProperty); + expect(point.disableDepthTestDistance).toBeInstanceOf(ConstantProperty); expect(point.color.getValue()).toEqual(options.color); expect(point.pixelSize.getValue()).toEqual(options.pixelSize); @@ -45,6 +47,7 @@ defineSuite([ expect(point.scaleByDistance.getValue()).toEqual(options.scaleByDistance); expect(point.heightReference.getValue()).toEqual(options.heightReference); expect(point.distanceDisplayCondition.getValue()).toEqual(options.distanceDisplayCondition); + expect(point.disableDepthTestDistance.getValue()).toEqual(options.disableDepthTestDistance); }); it('merge assigns unassigned properties', function() { @@ -57,6 +60,7 @@ defineSuite([ source.scaleByDistance = new ConstantProperty(new NearFarScalar()); source.heightReference = new ConstantProperty(HeightReference.RELATIVE_TO_GROUND); source.distanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition(10.0, 100.0)); + source.disableDepthTestDistance = new ConstantProperty(10.0); var target = new PointGraphics(); target.merge(source); @@ -68,6 +72,7 @@ defineSuite([ expect(target.scaleByDistance).toBe(source.scaleByDistance); expect(target.heightReference).toBe(source.heightReference); expect(target.distanceDisplayCondition).toBe(source.distanceDisplayCondition); + expect(target.disableDepthTestDistance).toBe(source.disableDepthTestDistance); }); it('merge does not assign assigned properties', function() { @@ -80,6 +85,7 @@ defineSuite([ source.scaleByDistance = new ConstantProperty(new NearFarScalar()); source.heightReference = new ConstantProperty(HeightReference.RELATIVE_TO_GROUND); source.distanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition(10.0, 100.0)); + source.disableDepthTestDistance = new ConstantProperty(10.0); var color = new ConstantProperty(Color.WHITE); var pixelSize = new ConstantProperty(1); @@ -88,6 +94,7 @@ defineSuite([ var show = new ConstantProperty(true); var heightReference = new ConstantProperty(HeightReference.CLAMP_TO_GROUND); var distanDisplayCondition = new ConstantProperty(new DistanceDisplayCondition(10.0, 100.0)); + var disableDepthTestDistance = new ConstantProperty(20.0); var target = new PointGraphics(); target.color = color; @@ -98,6 +105,7 @@ defineSuite([ target.scaleByDistance = show; target.heightReference = heightReference; target.distanceDisplayCondition = distanDisplayCondition; + target.disableDepthTestDistance = disableDepthTestDistance; target.merge(source); expect(target.color).toBe(color); @@ -108,6 +116,7 @@ defineSuite([ expect(target.scaleByDistance).toBe(show); expect(target.heightReference).toBe(heightReference); expect(target.distanceDisplayCondition).toBe(distanDisplayCondition); + expect(target.disableDepthTestDistance).toBe(disableDepthTestDistance); }); it('clone works', function() { @@ -120,6 +129,7 @@ defineSuite([ source.scaleByDistance = new ConstantProperty(new NearFarScalar()); source.heightReference = new ConstantProperty(HeightReference.RELATIVE_TO_GROUND); source.distanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition(10.0, 100.0)); + source.disableDepthTestDistance = new ConstantProperty(10.0); var result = source.clone(); expect(result.color).toBe(source.color); @@ -130,6 +140,7 @@ defineSuite([ expect(result.scaleByDistance).toBe(source.scaleByDistance); expect(result.heightReference).toBe(source.heightReference); expect(result.distanceDisplayCondition).toBe(source.distanceDisplayCondition); + expect(result.disableDepthTestDistance).toBe(source.disableDepthTestDistance); }); it('merge throws if source undefined', function() { diff --git a/Specs/DataSources/PointVisualizerSpec.js b/Specs/DataSources/PointVisualizerSpec.js index b1115a51eabe..4878402f6624 100644 --- a/Specs/DataSources/PointVisualizerSpec.js +++ b/Specs/DataSources/PointVisualizerSpec.js @@ -161,7 +161,8 @@ defineSuite([ outlineWidth : 9, pixelSize : 10, scaleByDistance : new NearFarScalar(11, 12, 13, 14), - distanceDisplayCondition : new DistanceDisplayCondition(10.0, 100.0) + distanceDisplayCondition : new DistanceDisplayCondition(10.0, 100.0), + disableDepthTestDistance : 10.0 } }); var point = entity.point; @@ -180,6 +181,7 @@ defineSuite([ expect(pointPrimitive.outlineColor).toEqual(point.outlineColor.getValue(time)); expect(pointPrimitive.outlineWidth).toEqual(point.outlineWidth.getValue(time)); expect(pointPrimitive.distanceDisplayCondition).toEqual(point.distanceDisplayCondition.getValue(time)); + expect(pointPrimitive.disableDepthTestDistance).toEqual(point.disableDepthTestDistance.getValue(time)); point.color = new Color(0.15, 0.16, 0.17, 0.18); point.outlineColor = new Color(0.19, 0.20, 0.21, 0.22); @@ -187,6 +189,7 @@ defineSuite([ point.outlineWidth = 24; point.scaleByDistance = new NearFarScalar(25, 26, 27, 28); point.distanceDisplayCondition = new DistanceDisplayCondition(1000.0, 1000000.0); + point.disableDepthTestDistance = 20.0; visualizer.update(time); @@ -197,6 +200,7 @@ defineSuite([ expect(pointPrimitive.outlineColor).toEqual(point.outlineColor.getValue(time)); expect(pointPrimitive.outlineWidth).toEqual(point.outlineWidth.getValue(time)); expect(pointPrimitive.distanceDisplayCondition).toEqual(point.distanceDisplayCondition.getValue(time)); + expect(pointPrimitive.disableDepthTestDistance).toEqual(point.disableDepthTestDistance.getValue(time)); point.show = false; visualizer.update(time); @@ -219,6 +223,7 @@ defineSuite([ pixelSize : 10, scaleByDistance : new NearFarScalar(11, 12, 13, 14), distanceDisplayCondition : new DistanceDisplayCondition(10.0, 100.0), + disableDepthTestDistance : 10.0, heightReference : HeightReference.CLAMP_TO_GROUND } }); @@ -235,6 +240,7 @@ defineSuite([ expect(billboard.position).toEqual(entity.position.getValue(time)); expect(billboard.scaleByDistance).toEqual(point.scaleByDistance.getValue(time)); expect(billboard.distanceDisplayCondition).toEqual(point.distanceDisplayCondition.getValue(time)); + expect(billboard.disableDepthTestDistance).toEqual(point.disableDepthTestDistance.getValue(time)); //expect(billboard.color).toEqual(point.color.getValue(time)); //expect(billboard.outlineColor).toEqual(point.outlineColor.getValue(time)); //expect(billboard.outlineWidth).toEqual(point.outlineWidth.getValue(time)); @@ -245,6 +251,7 @@ defineSuite([ point.outlineWidth = 24; point.scaleByDistance = new NearFarScalar(25, 26, 27, 28); point.distanceDisplayCondition = new DistanceDisplayCondition(1000.0, 1000000.0); + point.disableDepthTestDistance = 20.0; visualizer.update(time); @@ -252,6 +259,7 @@ defineSuite([ expect(billboard.position).toEqual(entity.position.getValue(time)); expect(billboard.scaleByDistance).toEqual(point.scaleByDistance.getValue(time)); expect(billboard.distanceDisplayCondition).toEqual(point.distanceDisplayCondition.getValue(time)); + expect(billboard.disableDepthTestDistance).toEqual(point.disableDepthTestDistance.getValue(time)); //expect(billboard.color).toEqual(point.color.getValue(time)); //expect(billboard.outlineColor).toEqual(point.outlineColor.getValue(time)); //expect(billboard.outlineWidth).toEqual(point.outlineWidth.getValue(time)); diff --git a/Specs/Renderer/AutomaticUniformSpec.js b/Specs/Renderer/AutomaticUniformSpec.js index 83648a60cfe6..c3e9ac2d201e 100644 --- a/Specs/Renderer/AutomaticUniformSpec.js +++ b/Specs/Renderer/AutomaticUniformSpec.js @@ -1254,4 +1254,17 @@ defineSuite([ }).contextToRender(); }); + it('has czm_minimumDisableDepthTestDistance', function() { + var frameState = createFrameState(context, createMockCamera()); + context.uniformState.update(frameState); + var fs = + 'void main() {' + + ' gl_FragColor = vec4(czm_minimumDisableDepthTestDistance == 0.0);' + + '}'; + expect({ + context : context, + fragmentShader : fs + }).contextToRender(); + }); + }, 'WebGL'); diff --git a/Specs/Scene/BillboardCollectionSpec.js b/Specs/Scene/BillboardCollectionSpec.js index a180990d815b..555dd139d50b 100644 --- a/Specs/Scene/BillboardCollectionSpec.js +++ b/Specs/Scene/BillboardCollectionSpec.js @@ -132,6 +132,7 @@ defineSuite([ expect(b.heightReference).toEqual(HeightReference.NONE); expect(b.sizeInMeters).toEqual(false); expect(b.distanceDisplayCondition).not.toBeDefined(); + expect(b.disableDepthTestDistance).toEqual(0.0); }); it('can add and remove before first update.', function() { @@ -165,6 +166,7 @@ defineSuite([ height : 200.0, sizeInMeters : true, distanceDisplayCondition : new DistanceDisplayCondition(10.0, 100.0), + disableDepthTestDistance : 10.0, id : 'id' }); @@ -189,6 +191,7 @@ defineSuite([ expect(b.height).toEqual(200.0); expect(b.sizeInMeters).toEqual(true); expect(b.distanceDisplayCondition).toEqual(new DistanceDisplayCondition(10.0, 100.0)); + expect(b.disableDepthTestDistance).toEqual(10.0); expect(b.id).toEqual('id'); }); @@ -212,6 +215,7 @@ defineSuite([ b.pixelOffsetScaleByDistance = new NearFarScalar(1.0e6, 3.0, 1.0e8, 0.0); b.sizeInMeters = true; b.distanceDisplayCondition = new DistanceDisplayCondition(10.0, 100.0); + b.disableDepthTestDistance = 10.0; expect(b.show).toEqual(false); expect(b.position).toEqual(new Cartesian3(1.0, 2.0, 3.0)); @@ -234,6 +238,7 @@ defineSuite([ expect(b.height).toEqual(200.0); expect(b.sizeInMeters).toEqual(true); expect(b.distanceDisplayCondition).toEqual(new DistanceDisplayCondition(10.0, 100.0)); + expect(b.disableDepthTestDistance).toEqual(10.0); }); it('is not destroyed', function() { @@ -456,6 +461,37 @@ defineSuite([ }).toThrowDeveloperError(); }); + it('renders with disableDepthTestDistance', function() { + var b = billboards.add({ + position : new Cartesian3(-1.0, 0.0, 0.0), + image : greenImage + }); + billboards.add({ + position : Cartesian3.ZERO, + image : blueImage + }); + + expect(scene).toRender([0, 0, 255, 255]); + + b.disableDepthTestDistance = Number.POSITIVE_INFINITY; + expect(scene).toRender([0, 255, 0, 255]); + }); + + it('throws with new billboard with disableDepthTestDistance less than 0.0', function() { + expect(function() { + billboards.add({ + disableDepthTestDistance : -1.0 + }); + }).toThrowDeveloperError(); + }); + + it('throws with disableDepthTestDistance set less than 0.0', function() { + var b = billboards.add(); + expect(function() { + b.disableDepthTestDistance = -1.0; + }).toThrowDeveloperError(); + }); + it('sets a removed billboard property', function() { var b = billboards.add(); billboards.remove(b); diff --git a/Specs/Scene/LabelCollectionSpec.js b/Specs/Scene/LabelCollectionSpec.js index 5a0830cf6ef6..61b348fe3dc5 100644 --- a/Specs/Scene/LabelCollectionSpec.js +++ b/Specs/Scene/LabelCollectionSpec.js @@ -100,6 +100,7 @@ defineSuite([ expect(label.pixelOffsetScaleByDistance).not.toBeDefined(); expect(label.scaleByDistance).not.toBeDefined(); expect(label.distanceDisplayCondition).not.toBeDefined(); + expect(label.disableDepthTestDistance).toEqual(0.0); }); it('can add a label with specified values', function() { @@ -134,6 +135,7 @@ defineSuite([ var pixelOffsetScale = new NearFarScalar(1.0e4, 1.0, 1.0e6, 0.0); var scaleByDistance = new NearFarScalar(1.0e4, 1.0, 1.0e6, 0.0); var distanceDisplayCondition = new DistanceDisplayCondition(10.0, 100.0); + var disableDepthTestDistance = 10.0; var label = labels.add({ show : show, position : position, @@ -155,7 +157,8 @@ defineSuite([ translucencyByDistance : translucency, pixelOffsetScaleByDistance : pixelOffsetScale, scaleByDistance : scaleByDistance, - distanceDisplayCondition : distanceDisplayCondition + distanceDisplayCondition : distanceDisplayCondition, + disableDepthTestDistance : disableDepthTestDistance }); expect(label.show).toEqual(show); @@ -179,6 +182,7 @@ defineSuite([ expect(label.pixelOffsetScaleByDistance).toEqual(pixelOffsetScale); expect(label.scaleByDistance).toEqual(scaleByDistance); expect(label.distanceDisplayCondition).toEqual(distanceDisplayCondition); + expect(label.disableDepthTestDistance).toEqual(disableDepthTestDistance); }); it('can specify font using units other than pixels', function() { @@ -675,6 +679,43 @@ defineSuite([ }).toThrowDeveloperError(); }); + it('renders with disableDepthTestDistance', function() { + var l = labels.add({ + position : new Cartesian3(-1.0, 0.0, 0.0), + text : solidBox, + fillColor : Color.LIME, + horizontalOrigin : HorizontalOrigin.CENTER, + verticalOrigin : VerticalOrigin.CENTER + }); + labels.add({ + position : Cartesian3.ZERO, + text : solidBox, + fillColor : Color.BLUE, + horizontalOrigin : HorizontalOrigin.CENTER, + verticalOrigin : VerticalOrigin.CENTER + }); + + expect(scene).toRender([0, 0, 255, 255]); + + l.disableDepthTestDistance = Number.POSITIVE_INFINITY; + expect(scene).toRender([0, 255, 0, 255]); + }); + + it('throws with new label with disableDepthTestDistance less than 0.0', function() { + expect(function() { + labels.add({ + disableDepthTestDistance : -1.0 + }); + }).toThrowDeveloperError(); + }); + + it('throws with disableDepthTestDistance set less than 0.0', function() { + var l = labels.add(); + expect(function() { + l.disableDepthTestDistance = -1.0; + }).toThrowDeveloperError(); + }); + it('can pick a label', function() { var label = labels.add({ position : Cartesian3.ZERO, diff --git a/Specs/Scene/PointPrimitiveCollectionSpec.js b/Specs/Scene/PointPrimitiveCollectionSpec.js index 3f00c48dddfc..b706146371c5 100644 --- a/Specs/Scene/PointPrimitiveCollectionSpec.js +++ b/Specs/Scene/PointPrimitiveCollectionSpec.js @@ -73,6 +73,7 @@ defineSuite([ expect(p.scaleByDistance).not.toBeDefined(); expect(p.translucencyByDistance).not.toBeDefined(); expect(p.distanceDisplayCondition).not.toBeDefined(); + expect(p.disableDepthTestDistance).toEqual(0.0); expect(p.id).not.toBeDefined(); }); @@ -103,6 +104,7 @@ defineSuite([ scaleByDistance : new NearFarScalar(1.0, 3.0, 1.0e6, 0.0), translucencyByDistance : new NearFarScalar(1.0, 1.0, 1.0e6, 0.0), distanceDisplayCondition : new DistanceDisplayCondition(10.0, 100.0), + disableDepthTestDistance : 10.0, id : 'id' }); @@ -121,6 +123,7 @@ defineSuite([ expect(p.scaleByDistance).toEqual(new NearFarScalar(1.0, 3.0, 1.0e6, 0.0)); expect(p.translucencyByDistance).toEqual(new NearFarScalar(1.0, 1.0, 1.0e6, 0.0)); expect(p.distanceDisplayCondition).toEqual(new DistanceDisplayCondition(10.0, 100.0)); + expect(p.disableDepthTestDistance).toEqual(10.0); expect(p.id).toEqual('id'); }); @@ -135,6 +138,7 @@ defineSuite([ p.scaleByDistance = new NearFarScalar(1.0e6, 3.0, 1.0e8, 0.0); p.translucencyByDistance = new NearFarScalar(1.0e6, 1.0, 1.0e8, 0.0); p.distanceDisplayCondition = new DistanceDisplayCondition(10.0, 100.0); + p.disableDepthTestDistance = 10.0; expect(p.show).toEqual(false); expect(p.position).toEqual(new Cartesian3(1.0, 2.0, 3.0)); @@ -151,6 +155,7 @@ defineSuite([ expect(p.scaleByDistance).toEqual(new NearFarScalar(1.0e6, 3.0, 1.0e8, 0.0)); expect(p.translucencyByDistance).toEqual(new NearFarScalar(1.0e6, 1.0, 1.0e8, 0.0)); expect(p.distanceDisplayCondition).toEqual(new DistanceDisplayCondition(10.0, 100.0)); + expect(p.disableDepthTestDistance).toEqual(10.0); }); it('is not destroyed', function() { @@ -309,6 +314,39 @@ defineSuite([ }).toThrowDeveloperError(); }); + it('renders with disableDepthTestDistance', function() { + var p = pointPrimitives.add({ + position : new Cartesian3(-1.0, 0.0, 0.0), + pixelSize : 10.0, + color : Color.LIME + }); + pointPrimitives.add({ + position : Cartesian3.ZERO, + pixelSize : 10.0, + color : Color.BLUE + }); + + expect(scene).toRender([0 , 0, 255, 255]); + + p.disableDepthTestDistance = Number.POSITIVE_INFINITY; + expect(scene).toRender([0, 255, 0, 255]); + }); + + it('throws with new point primitive with invalid disableDepthTestDistance (< 0.0)', function() { + expect(function() { + pointPrimitives.add({ + disableDepthTestDistance : -1.0 + }); + }).toThrowDeveloperError(); + }); + + it('throws with disableDepthTestDistance set less than 0.0', function() { + var p = pointPrimitives.add(); + expect(function() { + p.disableDepthTestDistance = -1.0; + }).toThrowDeveloperError(); + }); + it('set a removed pointPrimitive property', function() { var p = pointPrimitives.add(); pointPrimitives.remove(p); diff --git a/Specs/Scene/SceneSpec.js b/Specs/Scene/SceneSpec.js index 03beddb71f27..eed4a60940bf 100644 --- a/Specs/Scene/SceneSpec.js +++ b/Specs/Scene/SceneSpec.js @@ -1078,4 +1078,11 @@ defineSuite([ } s.destroyForSpecs(); }); + + it('throws when minimumDisableDepthTestDistance is set less than 0.0', function() { + expect(function() { + scene.minimumDisableDepthTestDistance = -1.0; + }).toThrowDeveloperError(); + }); + }, 'WebGL'); diff --git a/Specs/createFrameState.js b/Specs/createFrameState.js index 003291b39bc1..65fbc10abeff 100644 --- a/Specs/createFrameState.js +++ b/Specs/createFrameState.js @@ -37,6 +37,8 @@ define([ frameState.passes.render = true; frameState.passes.pick = false; + frameState.minimumDisableDepthTestDistance = 0.0; + return frameState; }