From 26ba43a48c3707d9be225bfcfb7ae39e6be57f6a Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 24 Mar 2017 19:12:21 -0400 Subject: [PATCH 01/13] Add depth fail material to primitives. --- Apps/Sandcastle/gallery/Hello World.html | 126 +++++++++++++++++++++++ Source/Scene/Primitive.js | 106 ++++++++++++++++++- 2 files changed, 227 insertions(+), 5 deletions(-) diff --git a/Apps/Sandcastle/gallery/Hello World.html b/Apps/Sandcastle/gallery/Hello World.html index 640e8e317705..1e61b7892b67 100644 --- a/Apps/Sandcastle/gallery/Hello World.html +++ b/Apps/Sandcastle/gallery/Hello World.html @@ -28,6 +28,132 @@ 'use strict'; //Sandcastle_Begin var viewer = new Cesium.Viewer('cesiumContainer'); +viewer.terrainProvider = new Cesium.CesiumTerrainProvider({ + url : 'https://assets.agi.com/stk-terrain/world', + requestWaterMask : true, + requestVertexNormals : true +}); + +var scene = viewer.scene; +scene.globe.depthTestAgainstTerrain = true; + +(function lookAtMtEverest() { + var target = new Cesium.Cartesian3(300770.50872389384, 5634912.131394585, 2978152.2865545116); + var offset = new Cesium.Cartesian3(6344.974098678562, -793.3419798081741, 2499.9508860763162); + viewer.camera.lookAt(target, offset); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); +})(); + +function createPositions() { + var length = 1000; + + var startLon = Cesium.Math.toRadians(86.953793); + var endLon = Cesium.Math.toRadians(86.896497); + + var lat = Cesium.Math.toRadians(27.988257); + + var terrainSamplePositions = []; + for (var i = 0; i < length; ++i) { + var lon = Cesium.Math.lerp(endLon, startLon, i / (length - 1)); + var position = new Cesium.Cartographic(lon, lat); + terrainSamplePositions.push(position); + } + return terrainSamplePositions; +} + +Cesium.when(Cesium.sampleTerrainMostDetailed(viewer.terrainProvider, createPositions()), function(samples) { + var offset = 10.0; + for (var i = 0; i < samples.length; ++i) { + samples[i].height += offset; + } + + var cartesianSamples = Cesium.Ellipsoid.WGS84.cartographicArrayToCartesianArray(samples); + + var material = Cesium.Material.fromType(Cesium.Material.PolylineOutlineType); + material.uniforms.color = Cesium.Color.ORANGE; + material.uniforms.outlineWidth = 2; + material.uniforms.outlineColor = Cesium.Color.BLACK; + + var line = scene.primitives.add(new Cesium.Primitive({ + geometryInstances : new Cesium.GeometryInstance({ + geometry : new Cesium.PolylineGeometry({ + positions : cartesianSamples, + followSurface : false, + width : 5, + vertexFormat : Cesium.PolylineMaterialAppearance.VERTEX_FORMAT + }) + }), + appearance : new Cesium.PolylineMaterialAppearance({ + material : material + }) + })); + + var material = Cesium.Material.fromType(Cesium.Material.PolylineOutlineType); + material.uniforms.color = Cesium.Color.RED; + material.uniforms.outlineColor = Cesium.Color.BLACK; + material.uniforms.outlineWidth = 2; + + line._depthFailAppearance = new Cesium.PolylineMaterialAppearance({ + material : material + }); + + var vs = line._depthFailAppearance.vertexShaderSource; + vs = Cesium.ShaderSource.replaceMain(vs, 'czm_old_main'); + vs += 'varying float v_WindowZ;\n' + + 'void main() {\n' + + ' czm_old_main();\n' + + ' vec4 position = gl_Position;\n' + + ' v_WindowZ = (0.5 * (position.z / position.w) + 0.5) * position.w;\n' + + ' position.z = min(position.z, position.w);\n' + + ' gl_Position = position;' + + '}\n'; + + var fs = line._depthFailAppearance.fragmentShaderSource; + fs = Cesium.ShaderSource.replaceMain(fs, 'czm_old_main()'); + fs += 'varying float v_WindowZ;\n' + + 'void main() {\n' + + ' czm_old_main();\n' + + ' gl_FragDepthEXT = min(v_WindowZ * gl_FragCoord.w, 1.0);\n' + + '}\n'; + fs = '#extension GL_EXT_frag_depth : enable\n' + fs; + + line._depthFailAppearance._vertexShaderSource = vs; + line._depthFailAppearance._fragmentShaderSource = fs; +}); + + +var dimension = 500.0; +var positionCart = new Cesium.Cartographic(1.51728, 0.488037, 8407.4); +var position = Cesium.Ellipsoid.WGS84.cartographicToCartesian(positionCart); + +var box = scene.primitives.add(new Cesium.Primitive({ + geometryInstances : new Cesium.GeometryInstance({ + geometry : Cesium.BoxGeometry.fromDimensions({ + vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, + dimensions : new Cesium.Cartesian3(dimension, dimension, dimension) + }), + modelMatrix : Cesium.Transforms.eastNorthUpToFixedFrame(position), + attributes : { + color : Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 0.0, 1.0, 0.5)), + depthFailColor : Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 0.0, 0.0, 0.5)) + } + }), + appearance : new Cesium.PerInstanceColorAppearance({ + closed: true + }) +})); + + +box._depthFailAppearance = new Cesium.PerInstanceColorAppearance({ + closed: true +}); + +var vs = box._depthFailAppearance.vertexShaderSource; +vs = vs.replace(/attribute\s+vec(?:3|4)\s+color;/g, ''); +vs = vs.replace(/(\b)color(\b)/g, '$1czm_batchTable_depthFailColor(batchId)$2'); + +box._depthFailAppearance._vertexShaderSource = vs; + //Sandcastle_End Sandcastle.finishedLoading(); } diff --git a/Source/Scene/Primitive.js b/Source/Scene/Primitive.js index 90968e3ba53e..4261a9337d8f 100644 --- a/Source/Scene/Primitive.js +++ b/Source/Scene/Primitive.js @@ -35,6 +35,9 @@ define([ '../ThirdParty/when', './BatchTable', './CullFace', + './DepthFunction', + './Material', + './PolylineMaterialAppearance', './PrimitivePipeline', './PrimitiveState', './SceneMode', @@ -75,6 +78,9 @@ define([ when, BatchTable, CullFace, + DepthFunction, + Material, + PolylineMaterialAppearance, PrimitivePipeline, PrimitiveState, SceneMode, @@ -325,6 +331,11 @@ define([ this._backFaceRS = undefined; this._sp = undefined; + this._depthFailAppearance = undefined; + this._backFaceDepthFailRS = undefined; + this._spDepthFail = undefined; + this._frontFaceDepthFailRS = undefined; + this._pickRS = undefined; this._pickSP = undefined; this._pickIds = []; @@ -1316,6 +1327,25 @@ define([ primitive._pickRS = RenderState.fromCache(rs); } } + + if (defined(primitive._depthFailAppearance)) { + renderState = primitive._depthFailAppearance.getRenderState(); + rs = clone(renderState, false); + rs.depthTest.func = DepthFunction.GREATER; + if (twoPasses) { + rs.cull = { + enabled : true, + face : CullFace.BACK + }; + primitive._frontFaceDepthFailRS = RenderState.fromCache(rs); + + rs.cull.face = CullFace.FRONT; + primitive._backFaceDepthFailRS = RenderState.fromCache(rs); + } else { + primitive._frontFaceDepthFailRS = RenderState.fromCache(rs); + primitive._backFaceDepthFailRS = primitive._frontFaceRS; + } + } } function createShaderProgram(primitive, frameState, appearance) { @@ -1361,12 +1391,27 @@ define([ attributeLocations : attributeLocations }); validateShaderMatching(primitive._sp, attributeLocations); - } - var modifiedModelViewScratch = new Matrix4(); - var rtcScratch = new Cartesian3(); + if (defined(primitive._depthFailAppearance)) { + vs = primitive._batchTable.getVertexShaderCallback()(primitive._depthFailAppearance.vertexShaderSource); + vs = Primitive._appendShowToShader(primitive, vs); + vs = Primitive._appendDistanceDisplayConditionToShader(primitive, vs, frameState.scene3DOnly); + vs = Primitive._updateColorAttribute(primitive, vs); + vs = modifyForEncodedNormals(primitive, vs); + vs = Primitive._modifyShaderPosition(primitive, vs, frameState.scene3DOnly); - function createCommands(primitive, appearance, material, translucent, twoPasses, colorCommands, pickCommands, frameState) { + primitive._spDepthFail = ShaderProgram.replaceCache({ + context : context, + shaderProgram : primitive._spDepthFail, + vertexShaderSource : vs, + fragmentShaderSource : fs, + attributeLocations : attributeLocations + }); + validateShaderMatching(primitive._spDepthFail, attributeLocations); + } + } + + function getUniforms(primitive, appearance, material, frameState) { // Create uniform map by combining uniforms from the appearance and material if either have uniforms. var materialUniformMap = defined(material) ? material._uniforms : undefined; var appearanceUniformMap = {}; @@ -1399,9 +1444,26 @@ define([ }; } + return uniforms; + } + + var modifiedModelViewScratch = new Matrix4(); + var rtcScratch = new Cartesian3(); + + function createCommands(primitive, appearance, material, translucent, twoPasses, colorCommands, pickCommands, frameState) { + var uniforms = getUniforms(primitive, appearance, material, frameState); + + var depthFailUniforms; + if (defined(primitive._depthFailAppearance)) { + depthFailUniforms = getUniforms(primitive, primitive._depthFailAppearance, primitive._depthFailAppearance.material, frameState); + } + var pass = translucent ? Pass.TRANSLUCENT : Pass.OPAQUE; - colorCommands.length = primitive._va.length * (twoPasses ? 2 : 1); + var multiplier = twoPasses ? 2 : 1; + multiplier *= defined(primitive._depthFailAppearance) ? 2 : 1; + + colorCommands.length = primitive._va.length * multiplier; pickCommands.length = primitive._va.length; var length = colorCommands.length; @@ -1440,6 +1502,40 @@ define([ colorCommand.uniformMap = uniforms; colorCommand.pass = pass; + if (defined(primitive._depthFailAppearance)) { + ++i; + + if (twoPasses) { + colorCommand = colorCommands[i]; + if (!defined(colorCommand)) { + colorCommand = colorCommands[i] = new DrawCommand({ + owner : primitive, + primitiveType : primitive._primitiveType + }); + } + colorCommand.vertexArray = primitive._va[vaIndex]; + colorCommand.renderState = primitive._backFaceDepthFailRS; + colorCommand.shaderProgram = primitive._spDepthFail; + colorCommand.uniformMap = depthFailUniforms; + colorCommand.pass = pass; + + ++i; + } + + colorCommand = colorCommands[i]; + if (!defined(colorCommand)) { + colorCommand = colorCommands[i] = new DrawCommand({ + owner : primitive, + primitiveType : primitive._primitiveType + }); + } + colorCommand.vertexArray = primitive._va[vaIndex]; + colorCommand.renderState = primitive._frontFaceDepthFailRS; + colorCommand.shaderProgram = primitive._spDepthFail; + colorCommand.uniformMap = depthFailUniforms; + colorCommand.pass = pass; + } + var pickCommand = pickCommands[m]; if (!defined(pickCommand)) { pickCommand = pickCommands[m] = new DrawCommand({ From 28f6a940b90c08393501c199bc3302ff369879f3 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 27 Mar 2017 14:42:46 -0400 Subject: [PATCH 02/13] Clean up depth fail appearance. --- Apps/Sandcastle/gallery/Hello World.html | 58 ++++----------- Source/Scene/Primitive.js | 91 ++++++++++++++++++++++-- 2 files changed, 98 insertions(+), 51 deletions(-) diff --git a/Apps/Sandcastle/gallery/Hello World.html b/Apps/Sandcastle/gallery/Hello World.html index 1e61b7892b67..93391db8d0d9 100644 --- a/Apps/Sandcastle/gallery/Hello World.html +++ b/Apps/Sandcastle/gallery/Hello World.html @@ -74,7 +74,12 @@ material.uniforms.outlineWidth = 2; material.uniforms.outlineColor = Cesium.Color.BLACK; - var line = scene.primitives.add(new Cesium.Primitive({ + var depthFailMaterial = Cesium.Material.fromType(Cesium.Material.PolylineOutlineType); + depthFailMaterial.uniforms.color = Cesium.Color.RED; + depthFailMaterial.uniforms.outlineColor = Cesium.Color.BLACK; + depthFailMaterial.uniforms.outlineWidth = 2; + + scene.primitives.add(new Cesium.Primitive({ geometryInstances : new Cesium.GeometryInstance({ geometry : new Cesium.PolylineGeometry({ positions : cartesianSamples, @@ -85,40 +90,11 @@ }), appearance : new Cesium.PolylineMaterialAppearance({ material : material + }), + depthFailAppearance : new Cesium.PolylineMaterialAppearance({ + material : depthFailMaterial }) })); - - var material = Cesium.Material.fromType(Cesium.Material.PolylineOutlineType); - material.uniforms.color = Cesium.Color.RED; - material.uniforms.outlineColor = Cesium.Color.BLACK; - material.uniforms.outlineWidth = 2; - - line._depthFailAppearance = new Cesium.PolylineMaterialAppearance({ - material : material - }); - - var vs = line._depthFailAppearance.vertexShaderSource; - vs = Cesium.ShaderSource.replaceMain(vs, 'czm_old_main'); - vs += 'varying float v_WindowZ;\n' + - 'void main() {\n' + - ' czm_old_main();\n' + - ' vec4 position = gl_Position;\n' + - ' v_WindowZ = (0.5 * (position.z / position.w) + 0.5) * position.w;\n' + - ' position.z = min(position.z, position.w);\n' + - ' gl_Position = position;' + - '}\n'; - - var fs = line._depthFailAppearance.fragmentShaderSource; - fs = Cesium.ShaderSource.replaceMain(fs, 'czm_old_main()'); - fs += 'varying float v_WindowZ;\n' + - 'void main() {\n' + - ' czm_old_main();\n' + - ' gl_FragDepthEXT = min(v_WindowZ * gl_FragCoord.w, 1.0);\n' + - '}\n'; - fs = '#extension GL_EXT_frag_depth : enable\n' + fs; - - line._depthFailAppearance._vertexShaderSource = vs; - line._depthFailAppearance._fragmentShaderSource = fs; }); @@ -126,7 +102,7 @@ var positionCart = new Cesium.Cartographic(1.51728, 0.488037, 8407.4); var position = Cesium.Ellipsoid.WGS84.cartographicToCartesian(positionCart); -var box = scene.primitives.add(new Cesium.Primitive({ +scene.primitives.add(new Cesium.Primitive({ geometryInstances : new Cesium.GeometryInstance({ geometry : Cesium.BoxGeometry.fromDimensions({ vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, @@ -140,20 +116,12 @@ }), appearance : new Cesium.PerInstanceColorAppearance({ closed: true + }), + depthFailAppearance : new Cesium.PerInstanceColorAppearance({ + closed: true }) })); - -box._depthFailAppearance = new Cesium.PerInstanceColorAppearance({ - closed: true -}); - -var vs = box._depthFailAppearance.vertexShaderSource; -vs = vs.replace(/attribute\s+vec(?:3|4)\s+color;/g, ''); -vs = vs.replace(/(\b)color(\b)/g, '$1czm_batchTable_depthFailColor(batchId)$2'); - -box._depthFailAppearance._vertexShaderSource = vs; - //Sandcastle_End Sandcastle.finishedLoading(); } diff --git a/Source/Scene/Primitive.js b/Source/Scene/Primitive.js index 4261a9337d8f..d03825b30197 100644 --- a/Source/Scene/Primitive.js +++ b/Source/Scene/Primitive.js @@ -213,7 +213,7 @@ define([ this.geometryInstances = options.geometryInstances; /** - * The {@link Appearance} used to shade this primitive. Each geometry + * The {@link Appearance} used to shade this primitive. Each geometry * instance is shaded with the same appearance. Some appearances, like * {@link PerInstanceColorAppearance} allow giving each instance unique * properties. @@ -226,6 +226,29 @@ define([ this._appearance = undefined; this._material = undefined; + /** + * The {@link Appearance} used to shade this primitive when it fails the depth test. Each geometry + * instance is shaded with the same appearance. Some appearances, like + * {@link PerInstanceColorAppearance} allow giving each instance unique + * properties. + * + *

+ * When using an appearance that requires a color attribute, like PerInstanceColorAppearance, + * add a depthFailColor per-instance attribute instead. + *

+ * + *

+ * Requires the EXT_frag_depth WebGL extension to render properly. If the extension is not supported, + * a DeveloperError will be thrown. + *

+ * @type Appearance + * + * @default undefined + */ + this.depthFailAppearance = options.depthFailAppearance; + this._depthFailAppearance = undefined; + this._depthFailMaterial = undefined; + /** * The 4x4 transformation matrix that transforms the primitive (all geometry instances) from model to world coordinates. * When this is the identity matrix, the primitive is drawn in world coordinates, i.e., Earth's WGS84 coordinates. @@ -332,9 +355,9 @@ define([ this._sp = undefined; this._depthFailAppearance = undefined; - this._backFaceDepthFailRS = undefined; this._spDepthFail = undefined; this._frontFaceDepthFailRS = undefined; + this._backFaceDepthFailRS = undefined; this._pickRS = undefined; this._pickSP = undefined; @@ -805,7 +828,7 @@ define([ return renamedVS + '\n' + showMain; }; - Primitive._updateColorAttribute = function(primitive, vertexShaderSource) { + Primitive._updateColorAttribute = function(primitive, vertexShaderSource, isDepthFail) { // some appearances have a color attribute for per vertex color. // only remove if color is a per instance attribute. if (!defined(primitive._batchTableAttributeIndices.color)) { @@ -816,9 +839,19 @@ define([ return vertexShaderSource; } + //>>includeStart('debug', pragmas.debug); + if (isDepthFail && !defined(primitive._batchTableAttributeIndices.depthFailColor)) { + throw new DeveloperError('A depthFailColor per-instance attribute is required when using a depth fail appearance that uses a color attribute.'); + } + //>>includeEnd('debug'); + var modifiedVS = vertexShaderSource; modifiedVS = modifiedVS.replace(/attribute\s+vec4\s+color;/g, ''); - modifiedVS = modifiedVS.replace(/(\b)color(\b)/g, '$1czm_batchTable_color(batchId)$2'); + if (!isDepthFail) { + modifiedVS = modifiedVS.replace(/(\b)color(\b)/g, '$1czm_batchTable_color(batchId)$2'); + } else { + modifiedVS = modifiedVS.replace(/(\b)color(\b)/g, '$1czm_batchTable_depthFailColor(batchId)$2'); + } return modifiedVS; }; @@ -958,6 +991,36 @@ define([ return [attributeDecl, globalDecl, modifiedVS, compressedMain].join('\n'); } + function depthClampVS(vertexShaderSource) { + var modifiedVS = ShaderSource.replaceMain(vertexShaderSource, 'czm_non_depth_clamp_main'); + modifiedVS += 'varying float v_WindowZ;\n' + + 'void main() {\n' + + ' czm_non_depth_clamp_main();\n' + + ' vec4 position = gl_Position;\n' + + ' v_WindowZ = (0.5 * (position.z / position.w) + 0.5) * position.w;\n' + + ' position.z = min(position.z, position.w);\n' + + ' gl_Position = position;' + + '}\n'; + return modifiedVS; + } + + function depthClampFS(context, fragmentShaderSource) { + //>>includeStart('debug', pragmas.debug); + if (!context.fragmentDepth) { + throw new DeveloperError('The depth fail appearance requires the EXT_frag_depth extension.'); + } + //>>includeEnd('debug'); + + var modifiedFS = ShaderSource.replaceMain(fragmentShaderSource, 'czm_non_depth_clamp_main'); + modifiedFS += 'varying float v_WindowZ;\n' + + 'void main() {\n' + + ' czm_non_depth_clamp_main();\n' + + ' gl_FragDepthEXT = min(v_WindowZ * gl_FragCoord.w, 1.0);\n' + + '}\n'; + modifiedFS = '#extension GL_EXT_frag_depth : enable\n' + modifiedFS; + return modifiedFS; + } + function validateShaderMatching(shaderProgram, attributeLocations) { // For a VAO and shader program to be compatible, the VAO must have // all active attribute in the shader program. The VAO may have @@ -1356,7 +1419,7 @@ define([ var vs = primitive._batchTable.getVertexShaderCallback()(appearance.vertexShaderSource); vs = Primitive._appendShowToShader(primitive, vs); vs = Primitive._appendDistanceDisplayConditionToShader(primitive, vs, frameState.scene3DOnly); - vs = Primitive._updateColorAttribute(primitive, vs); + vs = Primitive._updateColorAttribute(primitive, vs, false); vs = modifyForEncodedNormals(primitive, vs); vs = Primitive._modifyShaderPosition(primitive, vs, frameState.scene3DOnly); var fs = appearance.getFragmentShaderSource(); @@ -1396,9 +1459,12 @@ define([ vs = primitive._batchTable.getVertexShaderCallback()(primitive._depthFailAppearance.vertexShaderSource); vs = Primitive._appendShowToShader(primitive, vs); vs = Primitive._appendDistanceDisplayConditionToShader(primitive, vs, frameState.scene3DOnly); - vs = Primitive._updateColorAttribute(primitive, vs); + vs = Primitive._updateColorAttribute(primitive, vs, true); vs = modifyForEncodedNormals(primitive, vs); vs = Primitive._modifyShaderPosition(primitive, vs, frameState.scene3DOnly); + vs = depthClampVS(vs); + + fs = depthClampFS(context, primitive._depthFailAppearance.getFragmentShaderSource()); primitive._spDepthFail = ShaderProgram.replaceCache({ context : context, @@ -1719,6 +1785,19 @@ define([ createSP = true; } + var depthFailAppearance = this.depthFailAppearance; + var depthFailMaterial = defined(depthFailAppearance) ? depthFailAppearance.material : undefined; + + if (this._depthFailAppearance !== depthFailAppearance) { + this._depthFailAppearance = depthFailAppearance; + this._depthFailMaterial = depthFailMaterial; + createRS = true; + createSP = true; + } else if (this._depthFailMaterial !== depthFailMaterial) { + this._depthFailMaterial = depthFailMaterial; + createSP = true; + } + var translucent = this._appearance.isTranslucent(); if (this._translucent !== translucent) { this._translucent = translucent; From 88da9ca3f9a8f41f4b8c3da1bf9fa444a47f2a1b Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 27 Mar 2017 20:03:54 -0400 Subject: [PATCH 03/13] Add depth fail appearance entity support to polylines only. --- Apps/Sandcastle/gallery/Hello World.html | 84 +++++-- Source/DataSources/GeometryVisualizer.js | 45 +++- Source/DataSources/PolylineGeometryUpdater.js | 48 ++-- Source/DataSources/PolylineGraphics.js | 6 + .../DataSources/StaticGeometryColorBatch.js | 220 ++++++++++++++---- .../StaticGeometryPerMaterialBatch.js | 67 +++++- Source/Scene/Primitive.js | 2 +- 7 files changed, 369 insertions(+), 103 deletions(-) diff --git a/Apps/Sandcastle/gallery/Hello World.html b/Apps/Sandcastle/gallery/Hello World.html index 93391db8d0d9..48a49996c6d4 100644 --- a/Apps/Sandcastle/gallery/Hello World.html +++ b/Apps/Sandcastle/gallery/Hello World.html @@ -69,35 +69,70 @@ var cartesianSamples = Cesium.Ellipsoid.WGS84.cartographicArrayToCartesianArray(samples); - var material = Cesium.Material.fromType(Cesium.Material.PolylineOutlineType); - material.uniforms.color = Cesium.Color.ORANGE; - material.uniforms.outlineWidth = 2; - material.uniforms.outlineColor = Cesium.Color.BLACK; + /* + viewer.entities.add({ + polyline : { + positions : cartesianSamples, + followSurface : false, + width : 5, + material : Cesium.Color.RED, + depthFailMaterial : Cesium.Color.BLUE + } + }); + */ - var depthFailMaterial = Cesium.Material.fromType(Cesium.Material.PolylineOutlineType); - depthFailMaterial.uniforms.color = Cesium.Color.RED; - depthFailMaterial.uniforms.outlineColor = Cesium.Color.BLACK; - depthFailMaterial.uniforms.outlineWidth = 2; + /* + viewer.entities.add({ + polyline : { + positions : cartesianSamples, + followSurface : false, + width : 5, + material : Cesium.Color.RED, + depthFailMaterial : new Cesium.PolylineOutlineMaterialProperty({ + color : Cesium.Color.ORANGE, + outlineWidth : 2, + outlineColor : Cesium.Color.BLACK + }) + } + }); + */ - scene.primitives.add(new Cesium.Primitive({ - geometryInstances : new Cesium.GeometryInstance({ - geometry : new Cesium.PolylineGeometry({ - positions : cartesianSamples, - followSurface : false, - width : 5, - vertexFormat : Cesium.PolylineMaterialAppearance.VERTEX_FORMAT + /* + viewer.entities.add({ + polyline : { + positions : cartesianSamples, + followSurface : false, + width : 5, + material : new Cesium.PolylineOutlineMaterialProperty({ + color : Cesium.Color.ORANGE, + outlineWidth : 2, + outlineColor : Cesium.Color.BLACK + }), + depthFailMaterial : Cesium.Color.RED + } + }); + */ + + viewer.entities.add({ + polyline : { + positions : cartesianSamples, + followSurface : false, + width : 5, + material : new Cesium.PolylineOutlineMaterialProperty({ + color : Cesium.Color.ORANGE, + outlineWidth : 2, + outlineColor : Cesium.Color.BLACK + }), + depthFailMaterial : new Cesium.PolylineOutlineMaterialProperty({ + color : Cesium.Color.RED, + outlineWidth : 2, + outlineColor : Cesium.Color.BLACK }) - }), - appearance : new Cesium.PolylineMaterialAppearance({ - material : material - }), - depthFailAppearance : new Cesium.PolylineMaterialAppearance({ - material : depthFailMaterial - }) - })); + } + }); }); - +/* var dimension = 500.0; var positionCart = new Cesium.Cartographic(1.51728, 0.488037, 8407.4); var position = Cesium.Ellipsoid.WGS84.cartographicToCartesian(positionCart); @@ -121,6 +156,7 @@ closed: true }) })); +*/ //Sandcastle_End Sandcastle.finishedLoading(); diff --git a/Source/DataSources/GeometryVisualizer.js b/Source/DataSources/GeometryVisualizer.js index df3cc9e6f5e0..ad62ca0c7be7 100644 --- a/Source/DataSources/GeometryVisualizer.js +++ b/Source/DataSources/GeometryVisualizer.js @@ -95,21 +95,31 @@ define([ that._outlineBatches[shadows].add(time, updater); } + var multiplier = 0; + if (defined(updater.depthFailMaterialProperty)) { + multiplier = updater.depthFailMaterialProperty instanceof ColorMaterialProperty ? 1 : 2; + } + + var index; + if (defined(shadows)) { + index = shadows + multiplier * ShadowMode.NUMBER_OF_SHADOW_MODES; + } + if (updater.fillEnabled) { if (updater.onTerrain) { that._groundColorBatch.add(time, updater); } else { if (updater.isClosed) { if (updater.fillMaterialProperty instanceof ColorMaterialProperty) { - that._closedColorBatches[shadows].add(time, updater); + that._closedColorBatches[index].add(time, updater); } else { - that._closedMaterialBatches[shadows].add(time, updater); + that._closedMaterialBatches[index].add(time, updater); } } else { if (updater.fillMaterialProperty instanceof ColorMaterialProperty) { - that._openColorBatches[shadows].add(time, updater); + that._openColorBatches[index].add(time, updater); } else { - that._openMaterialBatches[shadows].add(time, updater); + that._openMaterialBatches[index].add(time, updater); } } } @@ -152,17 +162,28 @@ define([ var numberOfShadowModes = ShadowMode.NUMBER_OF_SHADOW_MODES; this._outlineBatches = new Array(numberOfShadowModes); - this._closedColorBatches = new Array(numberOfShadowModes); - this._closedMaterialBatches = new Array(numberOfShadowModes); - this._openColorBatches = new Array(numberOfShadowModes); - this._openMaterialBatches = new Array(numberOfShadowModes); + this._closedColorBatches = new Array(numberOfShadowModes * 3); + this._closedMaterialBatches = new Array(numberOfShadowModes * 3); + this._openColorBatches = new Array(numberOfShadowModes * 3); + this._openMaterialBatches = new Array(numberOfShadowModes * 3); for (var i = 0; i < numberOfShadowModes; ++i) { this._outlineBatches[i] = new StaticOutlineGeometryBatch(primitives, scene, i); - this._closedColorBatches[i] = new StaticGeometryColorBatch(primitives, type.perInstanceColorAppearanceType, true, i); - this._closedMaterialBatches[i] = new StaticGeometryPerMaterialBatch(primitives, type.materialAppearanceType, true, i); - this._openColorBatches[i] = new StaticGeometryColorBatch(primitives, type.perInstanceColorAppearanceType, false, i); - this._openMaterialBatches[i] = new StaticGeometryPerMaterialBatch(primitives, type.materialAppearanceType, false, i); + + this._closedColorBatches[i] = new StaticGeometryColorBatch(primitives, type.perInstanceColorAppearanceType, undefined, true, i); + this._closedMaterialBatches[i] = new StaticGeometryPerMaterialBatch(primitives, type.materialAppearanceType, undefined, true, i); + this._openColorBatches[i] = new StaticGeometryColorBatch(primitives, type.perInstanceColorAppearanceType, undefined, false, i); + this._openMaterialBatches[i] = new StaticGeometryPerMaterialBatch(primitives, type.materialAppearanceType, undefined, false, i); + + this._closedColorBatches[i + numberOfShadowModes] = new StaticGeometryColorBatch(primitives, type.perInstanceColorAppearanceType, type.perInstanceColorAppearanceType, true, i); + this._closedMaterialBatches[i + numberOfShadowModes] = new StaticGeometryPerMaterialBatch(primitives, type.materialAppearanceType, type.perInstanceColorAppearanceType, true, i); + this._openColorBatches[i + numberOfShadowModes] = new StaticGeometryColorBatch(primitives, type.perInstanceColorAppearanceType, type.perInstanceColorAppearanceType, false, i); + this._openMaterialBatches[i + numberOfShadowModes] = new StaticGeometryPerMaterialBatch(primitives, type.materialAppearanceType, type.perInstanceColorAppearanceType, false, i); + + this._closedColorBatches[i + numberOfShadowModes * 2] = new StaticGeometryColorBatch(primitives, type.perInstanceColorAppearanceType, type.materialAppearanceType, true, i); + this._closedMaterialBatches[i + numberOfShadowModes * 2] = new StaticGeometryPerMaterialBatch(primitives, type.materialAppearanceType, type.materialAppearanceType, true, i); + this._openColorBatches[i + numberOfShadowModes * 2] = new StaticGeometryColorBatch(primitives, type.perInstanceColorAppearanceType, type.materialAppearanceType, false, i); + this._openMaterialBatches[i + numberOfShadowModes * 2] = new StaticGeometryPerMaterialBatch(primitives, type.materialAppearanceType, type.materialAppearanceType, false, i); } this._groundColorBatch = new StaticGroundGeometryColorBatch(groundPrimitives); diff --git a/Source/DataSources/PolylineGeometryUpdater.js b/Source/DataSources/PolylineGeometryUpdater.js index f4714c250878..422a65d0d7c2 100644 --- a/Source/DataSources/PolylineGeometryUpdater.js +++ b/Source/DataSources/PolylineGeometryUpdater.js @@ -99,6 +99,7 @@ define([ this._materialProperty = undefined; this._shadowsProperty = undefined; this._distanceDisplayConditionProperty = undefined; + this._depthFailMaterialProperty = undefined; this._options = new GeometryOptions(entity); this._onEntityPropertyChanged(entity, 'polyline', entity.polyline, undefined); } @@ -171,6 +172,11 @@ define([ return this._materialProperty; } }, + depthFailMaterialProperty : { + get : function() { + return this._depthFailMaterialProperty; + } + }, /** * Gets a value indicating if the geometry has an outline component. * @memberof PolylineGeometryUpdater.prototype @@ -205,7 +211,7 @@ define([ * Gets the property specifying whether the geometry * casts or receives shadows from each light source. * @memberof PolylineGeometryUpdater.prototype - * + * * @type {Property} * @readonly */ @@ -306,30 +312,32 @@ define([ } //>>includeEnd('debug'); - var color; - var attributes; var entity = this._entity; var isAvailable = entity.isAvailable(time); var show = new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time)); var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time); var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition); + var attributes = { + show : show, + distanceDisplayCondition : distanceDisplayConditionAttribute + }; + + var currentColor; if (this._materialProperty instanceof ColorMaterialProperty) { - var currentColor = Color.WHITE; + currentColor = Color.WHITE; if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) { currentColor = this._materialProperty.color.getValue(time); } - color = ColorGeometryInstanceAttribute.fromColor(currentColor); - attributes = { - show : show, - distanceDisplayCondition : distanceDisplayConditionAttribute, - color : color - }; - } else { - attributes = { - show : show, - distanceDisplayCondition : distanceDisplayConditionAttribute - }; + attributes.color = ColorGeometryInstanceAttribute.fromColor(currentColor); + } + + if (defined(this._depthFailMaterialProperty) && this._depthFailMaterialProperty instanceof ColorMaterialProperty) { + currentColor = Color.WHITE; + if (defined(this._depthFailMaterialProperty.color) && (this._depthFailMaterialProperty.color.isConstant || isAvailable)) { + currentColor = this._depthFailMaterialProperty.color.getValue(time); + } + attributes.depthFailColor = ColorGeometryInstanceAttribute.fromColor(currentColor); } return new GeometryInstance({ @@ -402,6 +410,7 @@ define([ var material = defaultValue(polyline.material, defaultMaterial); var isColorMaterial = material instanceof ColorMaterialProperty; this._materialProperty = material; + this._depthFailMaterialProperty = polyline.depthFailMaterial; this._showProperty = defaultValue(show, defaultShow); this._shadowsProperty = defaultValue(polyline.shadows, defaultShadows); this._distanceDisplayConditionProperty = defaultValue(polyline.distanceDisplayCondition, defaultDistanceDisplayCondition); @@ -431,7 +440,14 @@ define([ return; } - options.vertexFormat = isColorMaterial ? PolylineColorAppearance.VERTEX_FORMAT : PolylineMaterialAppearance.VERTEX_FORMAT; + var vertexFormat; + if (isColorMaterial && (!defined(this._depthFailMaterialProperty) || this._depthFailMaterialProperty instanceof ColorMaterialProperty)) { + vertexFormat = PolylineColorAppearance.VERTEX_FORMAT; + } else { + vertexFormat = PolylineMaterialAppearance.VERTEX_FORMAT; + } + + options.vertexFormat = vertexFormat; options.positions = positions; options.width = defined(width) ? width.getValue(Iso8601.MINIMUM_VALUE) : undefined; options.followSurface = defined(followSurface) ? followSurface.getValue(Iso8601.MINIMUM_VALUE) : undefined; diff --git a/Source/DataSources/PolylineGraphics.js b/Source/DataSources/PolylineGraphics.js index 4b22a4a9602c..70c16372e96a 100644 --- a/Source/DataSources/PolylineGraphics.js +++ b/Source/DataSources/PolylineGraphics.js @@ -43,6 +43,8 @@ define([ this._showSubscription = undefined; this._material = undefined; this._materialSubscription = undefined; + this._depthFailMaterial = undefined; + this._depthFailMaterialSubscription = undefined; this._positions = undefined; this._positionsSubscription = undefined; this._followSurface = undefined; @@ -91,6 +93,8 @@ define([ */ material : createMaterialPropertyDescriptor('material'), + depthFailMaterial : createMaterialPropertyDescriptor('depthFailMaterial'), + /** * Gets or sets the Property specifying the array of {@link Cartesian3} * positions that define the line strip. @@ -153,6 +157,7 @@ define([ } result.show = this.show; result.material = this.material; + result.depthFailMaterial = this.depthFailMaterial; result.positions = this.positions; result.width = this.width; result.followSurface = this.followSurface; @@ -177,6 +182,7 @@ define([ this.show = defaultValue(this.show, source.show); this.material = defaultValue(this.material, source.material); + this.depthFailMaterial = defaultValue(this.depthFailMaterial, source.depthFailMaterial); this.positions = defaultValue(this.positions, source.positions); this.width = defaultValue(this.width, source.width); this.followSurface = defaultValue(this.followSurface, source.followSurface); diff --git a/Source/DataSources/StaticGeometryColorBatch.js b/Source/DataSources/StaticGeometryColorBatch.js index eca570d7a0ef..cd1dbad79074 100644 --- a/Source/DataSources/StaticGeometryColorBatch.js +++ b/Source/DataSources/StaticGeometryColorBatch.js @@ -9,6 +9,8 @@ define([ '../Core/ShowGeometryInstanceAttribute', '../Scene/Primitive', './BoundingSphereState', + './ColorMaterialProperty', + './MaterialProperty', './Property' ], function( AssociativeArray, @@ -20,15 +22,20 @@ define([ ShowGeometryInstanceAttribute, Primitive, BoundingSphereState, + ColorMaterialProperty, + MaterialProperty, Property) { 'use strict'; var colorScratch = new Color(); var distanceDisplayConditionScratch = new DistanceDisplayCondition(); - function Batch(primitives, translucent, appearanceType, closed, shadows) { + function Batch(primitives, translucent, appearanceType, depthFailAppearanceType, depthFailMaterialProperty, closed, shadows) { this.translucent = translucent; this.appearanceType = appearanceType; + this.depthFailAppearanceType = depthFailAppearanceType; + this.depthFailMaterialProperty = depthFailMaterialProperty; + this.depthFailMaterial = undefined; this.closed = closed; this.shadows = shadows; this.primitives = primitives; @@ -43,8 +50,31 @@ define([ this.subscriptions = new AssociativeArray(); this.showsUpdated = new AssociativeArray(); this.itemsToRemove = []; + this.invalidated = false; + + var removeMaterialSubscription; + if (defined(depthFailMaterialProperty)) { + removeMaterialSubscription = depthFailMaterialProperty.definitionChanged.addEventListener(Batch.prototype.onMaterialChanged, this); + } + this.removeMaterialSubscription = removeMaterialSubscription; } + Batch.prototype.onMaterialChanged = function() { + this.invalidated = true; + }; + + Batch.prototype.isMaterial = function(updater) { + var material = this.depthFailMaterialProperty; + var updaterMaterial = updater.depthFailMaterialProperty; + if (updaterMaterial === material) { + return true; + } + if (defined(material)) { + return material.equals(updaterMaterial); + } + return false; + }; + Batch.prototype.add = function(updater, instance) { var id = updater.entity.id; this.createPrimitive = true; @@ -107,9 +137,24 @@ define([ if (defined(originalAttributes.color)) { originalAttributes.color.value = attributes.color; } + if (defined(originalAttributes.depthFailColor)) { + originalAttributes.depthFailColor.value = attributes.depthFailColor; + } } } + var depthFailAppearance; + if (defined(this.depthFailAppearanceType)) { + if (defined(this.depthFailMaterialProperty)) { + this.depthFailMaterial = MaterialProperty.getValue(time, this.depthFailMaterialProperty, this.depthFailMaterial); + } + depthFailAppearance = new this.depthFailAppearanceType({ + material : this.depthFailMaterial, + translucent : this.translucent, + closed : this.closed + }); + } + primitive = new Primitive({ asynchronous : true, geometryInstances : geometries, @@ -117,6 +162,7 @@ define([ translucent : this.translucent, closed : this.closed }), + depthFailAppearance : depthFailAppearance, shadows : this.shadows }); primitives.add(primitive); @@ -142,6 +188,12 @@ define([ primitives.remove(this.oldPrimitive); this.oldPrimitive = undefined; } + + if (defined(this.depthFailAppearanceType) && !(this.depthFailMaterialProperty instanceof ColorMaterialProperty)) { + this.depthFailMaterial = MaterialProperty.getValue(time, this.depthFailMaterialProperty, this.depthFailMaterial); + this.primitive.depthFailAppearance.material = this.depthFailMaterial; + } + var updatersWithAttributes = this.updatersWithAttributes.values; var length = updatersWithAttributes.length; var waitingOnCreate = this.waitingOnCreate; @@ -167,6 +219,15 @@ define([ } } + if (defined(this.depthFailAppearanceType) && this.depthFailAppearanceType instanceof ColorMaterialProperty && (!updater.depthFailMaterialProperty.isConstant || waitingOnCreate)) { + var depthFailColorProperty = updater.depthFailMaterialProperty.color; + depthFailColorProperty.getValue(time, colorScratch); + if (!Color.equals(attributes._lastDepthFailColor, colorScratch)) { + attributes._lastDepthFailColor = Color.clone(colorScratch, attributes._lastDepthFailColor); + attributes.depthFailColor = ColorGeometryInstanceAttribute.toValue(colorScratch, attributes.depthFailColor); + } + } + var show = updater.entity.isShowing && (updater.hasConstantFill || updater.isFilled(time)); var currentShow = attributes.show[0] === 1; if (show !== currentShow) { @@ -253,77 +314,152 @@ define([ /** * @private */ - function StaticGeometryColorBatch(primitives, appearanceType, closed, shadows) { - this._solidBatch = new Batch(primitives, false, appearanceType, closed, shadows); - this._translucentBatch = new Batch(primitives, true, appearanceType, closed, shadows); + function StaticGeometryColorBatch(primitives, appearanceType, depthFailAppearanceType, closed, shadows) { + this._solidItems = []; + this._translucentItems = []; + this._primitives = primitives; + this._appearanceType = appearanceType; + this._depthFailAppearanceType = depthFailAppearanceType; + this._closed = closed; + this._shadows = shadows; } StaticGeometryColorBatch.prototype.add = function(time, updater) { + var items; + var translucent; var instance = updater.createFillGeometryInstance(time); if (instance.attributes.color.value[3] === 255) { - this._solidBatch.add(updater, instance); + items = this._solidItems; + translucent = false; } else { - this._translucentBatch.add(updater, instance); + items = this._translucentItems; + translucent = true; } - }; - StaticGeometryColorBatch.prototype.remove = function(updater) { - if (!this._solidBatch.remove(updater)) { - this._translucentBatch.remove(updater); + var length = items.length; + for (var i = 0; i < length; i++) { + var item = items[i]; + if (item.isMaterial(updater)) { + item.add(updater, instance); + return; + } } + var batch = new Batch(this._primitives, translucent, this._appearanceType, this._depthFailAppearanceType, updater.depthFailMaterialProperty, this._closed, this._shadows); + batch.add(updater, instance); + items.push(batch); }; - StaticGeometryColorBatch.prototype.update = function(time) { - var i; - var updater; + function removeItem(items, updater) { + var length = items.length; + for (var i = length - 1; i >= 0; i--) { + var item = items[i]; + if (item.remove(updater)) { + if (item.updaters.length === 0) { + items.splice(i, 1); + item.destroy(); + return true; + } + } + } + return false; + } - //Perform initial update - var isUpdated = this._solidBatch.update(time); - isUpdated = this._translucentBatch.update(time) && isUpdated; + StaticGeometryColorBatch.prototype.remove = function(updater) { + if (!removeItem(this._solidItems, updater)) { + removeItem(this._translucentItems, updater); + } + }; - //If any items swapped between solid/translucent, we need to - //move them between batches - var itemsToRemove = this._solidBatch.itemsToRemove; - var solidsToMoveLength = itemsToRemove.length; - if (solidsToMoveLength > 0) { - for (i = 0; i < solidsToMoveLength; i++) { - updater = itemsToRemove[i]; - this._solidBatch.remove(updater); - this._translucentBatch.add(updater, updater.createFillGeometryInstance(time)); + function moveItems(batch, items, time) { + var itemsMoved = false; + var length = items.length; + for (var i = 0; i < length; ++i) { + var item = items[i]; + var itemsToRemove = item.itemsToRemove; + var itemsToMoveLength = itemsToRemove.length; + if (itemsToMoveLength > 0) { + for (i = 0; i < itemsToMoveLength; i++) { + var updater = itemsToRemove[i]; + item.remove(updater); + batch.add(time, updater); + itemsMoved = true; + } } } + return itemsMoved; + } - itemsToRemove = this._translucentBatch.itemsToRemove; - var translucentToMoveLength = itemsToRemove.length; - if (translucentToMoveLength > 0) { - for (i = 0; i < translucentToMoveLength; i++) { - updater = itemsToRemove[i]; - this._translucentBatch.remove(updater); - this._solidBatch.add(updater, updater.createFillGeometryInstance(time)); + function updateItems(batch, items, time, isUpdated) { + var length = items.length; + for (i = length - 1; i >= 0; i--) { + var item = items[i]; + if (item.invalidated) { + items.splice(i, 1); + var updaters = item.updaters.values; + var updatersLength = updaters.length; + for (var h = 0; h < updatersLength; h++) { + batch.add(time, updaters[h]); + } + item.destroy(); } } + length = items.length; + for (var i = 0; i < length; ++i) { + isUpdated = items[i].update(time) && isUpdated; + } + return isUpdated; + } + + StaticGeometryColorBatch.prototype.update = function(time) { + //Perform initial update + var isUpdated = updateItems(this, this._solidItems, time, true); + isUpdated = updateItems(this, this._translucentItems, time, isUpdated) && isUpdated; + + //If any items swapped between solid/translucent, we need to + //move them between batches + var solidsMoved = moveItems(this, this._solidItems, time); + var translucentsMoved = moveItems(this, this._translucentItems, time); + //If we moved anything around, we need to re-build the primitive - if (solidsToMoveLength > 0 || translucentToMoveLength > 0) { - isUpdated = this._solidBatch.update(time) && isUpdated; - isUpdated = this._translucentBatch.update(time) && isUpdated; + if (solidsMoved || translucentsMoved) { + isUpdated = updateItems(this, this._solidItems, time, isUpdated) && isUpdated; + isUpdated = updateItems(this, this._translucentItems, time, isUpdated)&& isUpdated; } return isUpdated; }; - StaticGeometryColorBatch.prototype.getBoundingSphere = function(entity, result) { - if (this._solidBatch.contains(entity)) { - return this._solidBatch.getBoundingSphere(entity, result); - } else if (this._translucentBatch.contains(entity)) { - return this._translucentBatch.getBoundingSphere(entity, result); + function getBoundingSphere(items, entity, result) { + var length = items.length; + for (var i = 0; i < length; i++) { + var item = items[i]; + if(item.contains(entity)){ + return item.getBoundingSphere(entity, result); + } } return BoundingSphereState.FAILED; + } + + StaticGeometryColorBatch.prototype.getBoundingSphere = function(entity, result) { + var boundingSphere = getBoundingSphere(this._solidItems, entity, result); + if (boundingSphere === BoundingSphereState.FAILED) { + return getBoundingSphere(this._translucentItems, entity, result); + } + return boundingSphere; }; + function removeAllPrimitives(items) { + var length = items.length; + for (var i = 0; i < length; i++) { + items[i].destroy(); + } + items.length = 0; + } + StaticGeometryColorBatch.prototype.removeAllPrimitives = function() { - this._solidBatch.removeAllPrimitives(); - this._translucentBatch.removeAllPrimitives(); + removeAllPrimitives(this._solidItems); + removeAllPrimitives(this._translucentItems); }; return StaticGeometryColorBatch; diff --git a/Source/DataSources/StaticGeometryPerMaterialBatch.js b/Source/DataSources/StaticGeometryPerMaterialBatch.js index df16c8ebf9cc..dfff26f0cb0b 100644 --- a/Source/DataSources/StaticGeometryPerMaterialBatch.js +++ b/Source/DataSources/StaticGeometryPerMaterialBatch.js @@ -1,32 +1,40 @@ /*global define*/ define([ '../Core/AssociativeArray', + '../Core/Color', + '../Core/ColorGeometryInstanceAttribute', '../Core/defined', '../Core/DistanceDisplayCondition', '../Core/DistanceDisplayConditionGeometryInstanceAttribute', '../Core/ShowGeometryInstanceAttribute', '../Scene/Primitive', './BoundingSphereState', + './ColorMaterialProperty', './MaterialProperty', './Property' ], function( AssociativeArray, + Color, + ColorGeometryInstanceAttribute, defined, DistanceDisplayCondition, DistanceDisplayConditionGeometryInstanceAttribute, ShowGeometryInstanceAttribute, Primitive, BoundingSphereState, + ColorMaterialProperty, MaterialProperty, Property) { 'use strict'; var distanceDisplayConditionScratch = new DistanceDisplayCondition(); - function Batch(primitives, appearanceType, materialProperty, closed, shadows) { + function Batch(primitives, appearanceType, materialProperty, depthFailAppearanceType, depthFailMaterialProperty, closed, shadows) { this.primitives = primitives; this.appearanceType = appearanceType; this.materialProperty = materialProperty; + this.depthFailAppearanceType = depthFailAppearanceType; + this.depthFailMaterialProperty = depthFailMaterialProperty; this.closed = closed; this.shadows = shadows; this.updaters = new AssociativeArray(); @@ -35,6 +43,7 @@ define([ this.oldPrimitive = undefined; this.geometry = new AssociativeArray(); this.material = undefined; + this.depthFailMaterial = undefined; this.updatersWithAttributes = new AssociativeArray(); this.attributes = new AssociativeArray(); this.invalidated = false; @@ -42,6 +51,7 @@ define([ this.subscriptions = new AssociativeArray(); this.showsUpdated = new AssociativeArray(); } + Batch.prototype.onMaterialChanged = function() { this.invalidated = true; }; @@ -49,13 +59,15 @@ define([ Batch.prototype.isMaterial = function(updater) { var material = this.materialProperty; var updaterMaterial = updater.fillMaterialProperty; - if (updaterMaterial === material) { + var depthFailMaterial = this.depthFailMaterialProperty; + var updaterDepthFailMaterial = updater.depthFailMaterialProperty; + + if (updaterMaterial === material && updaterDepthFailMaterial === depthFailMaterial) { return true; } - if (defined(material)) { - return material.equals(updaterMaterial); - } - return false; + var equals = defined(material) && material.equals(updaterMaterial); + equals = ((!defined(depthFailMaterial) && !defined(updaterDepthFailMaterial)) || (defined(depthFailMaterial) && depthFailMaterial.equals(updaterDepthFailMaterial))) && equals; + return equals; }; Batch.prototype.add = function(time, updater) { @@ -89,6 +101,8 @@ define([ return this.createPrimitive; }; + var colorScratch = new Color(); + Batch.prototype.update = function(time) { var isUpdated = true; var primitive = this.primitive; @@ -120,10 +134,30 @@ define([ if (defined(originalAttributes.color)) { originalAttributes.color.value = attributes.color; } + if (defined(originalAttributes.depthFailColor)) { + originalAttributes.depthFailColor.value = attributes.depthFailColor; + } } } this.material = MaterialProperty.getValue(time, this.materialProperty, this.material); + + var depthFailAppearance; + if (defined(this.depthFailMaterialProperty)) { + var translucent; + if (this.depthFailMaterialProperty instanceof MaterialProperty) { + this.depthFailMaterial = MaterialProperty.getValue(time, this.depthFailMaterialProperty, this.depthFailMaterial); + translucent = this.depthFailMaterial.isTranslucent(); + } else { + translucent = this.material.isTranslucent(); + } + depthFailAppearance = new this.depthFailAppearanceType({ + material : this.depthFailMaterial, + translucent : translucent, + closed : this.closed + }); + } + primitive = new Primitive({ asynchronous : true, geometryInstances : geometries, @@ -132,6 +166,7 @@ define([ translucent : this.material.isTranslucent(), closed : this.closed }), + depthFailAppearance : depthFailAppearance, shadows : this.shadows }); @@ -161,6 +196,11 @@ define([ this.material = MaterialProperty.getValue(time, this.materialProperty, this.material); this.primitive.appearance.material = this.material; + if (defined(this.depthFailAppearanceType) && !(this.depthFailMaterialProperty instanceof ColorMaterialProperty)) { + this.depthFailMaterial = MaterialProperty.getValue(time, this.depthFailMaterialProperty, this.depthFailMaterial); + this.primitive.depthFailAppearance.material = this.depthFailMaterial; + } + var updatersWithAttributes = this.updatersWithAttributes.values; var length = updatersWithAttributes.length; for (i = 0; i < length; i++) { @@ -174,6 +214,15 @@ define([ this.attributes.set(instance.id.id, attributes); } + if (defined(this.depthFailAppearanceType) && this.depthFailAppearanceType instanceof ColorMaterialProperty && !updater.depthFailMaterialProperty.isConstant) { + var depthFailColorProperty = updater.depthFailMaterialProperty.color; + depthFailColorProperty.getValue(time, colorScratch); + if (!Color.equals(attributes._lastDepthFailColor, colorScratch)) { + attributes._lastDepthFailColor = Color.clone(colorScratch, attributes._lastDepthFailColor); + attributes.depthFailColor = ColorGeometryInstanceAttribute.toValue(colorScratch, attributes.depthFailColor); + } + } + var show = entity.isShowing && (updater.hasConstantFill || updater.isFilled(time)); var currentShow = attributes.show[0] === 1; if (show !== currentShow) { @@ -254,13 +303,15 @@ define([ /** * @private */ - function StaticGeometryPerMaterialBatch(primitives, appearanceType, closed, shadows) { + function StaticGeometryPerMaterialBatch(primitives, appearanceType, depthFailAppearanceType, closed, shadows) { this._items = []; this._primitives = primitives; this._appearanceType = appearanceType; + this._depthFailAppearanceType = depthFailAppearanceType; this._closed = closed; this._shadows = shadows; } + StaticGeometryPerMaterialBatch.prototype.add = function(time, updater) { var items = this._items; var length = items.length; @@ -271,7 +322,7 @@ define([ return; } } - var batch = new Batch(this._primitives, this._appearanceType, updater.fillMaterialProperty, this._closed, this._shadows); + var batch = new Batch(this._primitives, this._appearanceType, updater.fillMaterialProperty, this._depthFailAppearanceType, updater.depthFailMaterialProperty, this._closed, this._shadows); batch.add(time, updater); items.push(batch); }; diff --git a/Source/Scene/Primitive.js b/Source/Scene/Primitive.js index d03825b30197..06b978ef9082 100644 --- a/Source/Scene/Primitive.js +++ b/Source/Scene/Primitive.js @@ -831,7 +831,7 @@ define([ Primitive._updateColorAttribute = function(primitive, vertexShaderSource, isDepthFail) { // some appearances have a color attribute for per vertex color. // only remove if color is a per instance attribute. - if (!defined(primitive._batchTableAttributeIndices.color)) { + if (!defined(primitive._batchTableAttributeIndices.color) && !defined(primitive._batchTableAttributeIndices.depthFailColor)) { return vertexShaderSource; } From 69e45d219d1ff0f4d111864286238f6d7a822f3a Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 6 Apr 2017 14:04:30 -0400 Subject: [PATCH 04/13] Remove writing framgment depth. --- Source/Scene/Primitive.js | 34 ++++++++-------------------------- 1 file changed, 8 insertions(+), 26 deletions(-) diff --git a/Source/Scene/Primitive.js b/Source/Scene/Primitive.js index 06b978ef9082..60f5cdf4047e 100644 --- a/Source/Scene/Primitive.js +++ b/Source/Scene/Primitive.js @@ -993,34 +993,16 @@ define([ function depthClampVS(vertexShaderSource) { var modifiedVS = ShaderSource.replaceMain(vertexShaderSource, 'czm_non_depth_clamp_main'); - modifiedVS += 'varying float v_WindowZ;\n' + - 'void main() {\n' + - ' czm_non_depth_clamp_main();\n' + - ' vec4 position = gl_Position;\n' + - ' v_WindowZ = (0.5 * (position.z / position.w) + 0.5) * position.w;\n' + - ' position.z = min(position.z, position.w);\n' + - ' gl_Position = position;' + - '}\n'; + modifiedVS += + 'void main() {\n' + + ' czm_non_depth_clamp_main();\n' + + ' vec4 position = gl_Position;\n' + + ' position.z = min(position.z, position.w);\n' + + ' gl_Position = position;' + + '}\n'; return modifiedVS; } - function depthClampFS(context, fragmentShaderSource) { - //>>includeStart('debug', pragmas.debug); - if (!context.fragmentDepth) { - throw new DeveloperError('The depth fail appearance requires the EXT_frag_depth extension.'); - } - //>>includeEnd('debug'); - - var modifiedFS = ShaderSource.replaceMain(fragmentShaderSource, 'czm_non_depth_clamp_main'); - modifiedFS += 'varying float v_WindowZ;\n' + - 'void main() {\n' + - ' czm_non_depth_clamp_main();\n' + - ' gl_FragDepthEXT = min(v_WindowZ * gl_FragCoord.w, 1.0);\n' + - '}\n'; - modifiedFS = '#extension GL_EXT_frag_depth : enable\n' + modifiedFS; - return modifiedFS; - } - function validateShaderMatching(shaderProgram, attributeLocations) { // For a VAO and shader program to be compatible, the VAO must have // all active attribute in the shader program. The VAO may have @@ -1464,7 +1446,7 @@ define([ vs = Primitive._modifyShaderPosition(primitive, vs, frameState.scene3DOnly); vs = depthClampVS(vs); - fs = depthClampFS(context, primitive._depthFailAppearance.getFragmentShaderSource()); + fs = primitive._depthFailAppearance.getFragmentShaderSource(); primitive._spDepthFail = ShaderProgram.replaceCache({ context : context, From e3a885c8f7c5e43d4c851ad87d75f7d7151d55b5 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 6 Apr 2017 14:57:05 -0400 Subject: [PATCH 05/13] Re-add writing fragment depth but disabled if unsupported. --- Source/Scene/Primitive.js | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/Source/Scene/Primitive.js b/Source/Scene/Primitive.js index 60f5cdf4047e..70e8c2ec2e92 100644 --- a/Source/Scene/Primitive.js +++ b/Source/Scene/Primitive.js @@ -994,15 +994,41 @@ define([ function depthClampVS(vertexShaderSource) { var modifiedVS = ShaderSource.replaceMain(vertexShaderSource, 'czm_non_depth_clamp_main'); modifiedVS += + '#ifdef GL_EXT_frag_depth\n' + + 'varying float v_WindowZ;\n' + + '#endif\n' + 'void main() {\n' + ' czm_non_depth_clamp_main();\n' + ' vec4 position = gl_Position;\n' + + '#ifdef GL_EXT_frag_depth\n' + + ' v_WindowZ = (0.5 * (position.z / position.w) + 0.5) * position.w;\n' + + '#endif\n' + ' position.z = min(position.z, position.w);\n' + ' gl_Position = position;' + '}\n'; return modifiedVS; } + function depthClampFS(fragmentShaderSource) { + var modifiedFS = ShaderSource.replaceMain(fragmentShaderSource, 'czm_non_depth_clamp_main'); + modifiedFS += + '#ifdef GL_EXT_frag_depth\n' + + 'varying float v_WindowZ;\n' + + '#endif\n' + + 'void main() {\n' + + ' czm_non_depth_clamp_main();\n' + + '#ifdef GL_EXT_frag_depth\n' + + ' gl_FragDepthEXT = min(v_WindowZ * gl_FragCoord.w, 1.0);\n' + + '#endif\n' + + '}\n'; + modifiedFS = + '#ifdef GL_EXT_frag_depth\n' + + '#extension GL_EXT_frag_depth : enable\n' + + '#endif\n' + + modifiedFS; + return modifiedFS; + } + function validateShaderMatching(shaderProgram, attributeLocations) { // For a VAO and shader program to be compatible, the VAO must have // all active attribute in the shader program. The VAO may have @@ -1446,7 +1472,7 @@ define([ vs = Primitive._modifyShaderPosition(primitive, vs, frameState.scene3DOnly); vs = depthClampVS(vs); - fs = primitive._depthFailAppearance.getFragmentShaderSource(); + fs = depthClampFS(primitive._depthFailAppearance.getFragmentShaderSource()); primitive._spDepthFail = ShaderProgram.replaceCache({ context : context, From 82f54ca6f030f85ecabc8b46973503530cea849a Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 6 Apr 2017 15:37:15 -0400 Subject: [PATCH 06/13] Fix existing tests. --- Source/DataSources/StaticGeometryColorBatch.js | 15 +++++++++++++++ .../DataSources/StaticGeometryPerMaterialBatch.js | 2 +- Specs/DataSources/GeometryVisualizerSpec.js | 4 ++-- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/Source/DataSources/StaticGeometryColorBatch.js b/Source/DataSources/StaticGeometryColorBatch.js index cd1dbad79074..4e6e7aa2fcfc 100644 --- a/Source/DataSources/StaticGeometryColorBatch.js +++ b/Source/DataSources/StaticGeometryColorBatch.js @@ -311,6 +311,21 @@ define([ } }; + Batch.prototype.destroy = function() { + var primitive = this.primitive; + var primitives = this.primitives; + if (defined(primitive)) { + primitives.remove(primitive); + } + var oldPrimitive = this.oldPrimitive; + if (defined(oldPrimitive)) { + primitives.remove(oldPrimitive); + } + if(defined(this.removeMaterialSubscription)) { + this.removeMaterialSubscription(); + } + }; + /** * @private */ diff --git a/Source/DataSources/StaticGeometryPerMaterialBatch.js b/Source/DataSources/StaticGeometryPerMaterialBatch.js index dfff26f0cb0b..527c6690130c 100644 --- a/Source/DataSources/StaticGeometryPerMaterialBatch.js +++ b/Source/DataSources/StaticGeometryPerMaterialBatch.js @@ -287,7 +287,7 @@ define([ return BoundingSphereState.DONE; }; - Batch.prototype.destroy = function(time) { + Batch.prototype.destroy = function() { var primitive = this.primitive; var primitives = this.primitives; if (defined(primitive)) { diff --git a/Specs/DataSources/GeometryVisualizerSpec.js b/Specs/DataSources/GeometryVisualizerSpec.js index 285d295be647..80f5b7cc3e52 100644 --- a/Specs/DataSources/GeometryVisualizerSpec.js +++ b/Specs/DataSources/GeometryVisualizerSpec.js @@ -533,7 +533,7 @@ defineSuite([ }); it('StaticGeometryPerMaterialBatch handles shared material being invalidated', function() { - var batch = new StaticGeometryPerMaterialBatch(scene.primitives, EllipseGeometryUpdater.materialAppearanceType, false, ShadowMode.DISABLED); + var batch = new StaticGeometryPerMaterialBatch(scene.primitives, EllipseGeometryUpdater.materialAppearanceType, undefined, false, ShadowMode.DISABLED); var ellipse = new EllipseGraphics(); ellipse.semiMajorAxis = new ConstantProperty(2); @@ -580,7 +580,7 @@ defineSuite([ }); it('StaticGeometryColorBatch updates color attribute after rebuilding primitive', function() { - var batch = new StaticGeometryColorBatch(scene.primitives, EllipseGeometryUpdater.materialAppearanceType, false, ShadowMode.DISABLED); + var batch = new StaticGeometryColorBatch(scene.primitives, EllipseGeometryUpdater.materialAppearanceType, undefined, false, ShadowMode.DISABLED); var entity = new Entity({ position : new Cartesian3(1234, 5678, 9101112), From d7869d4af481f65fd104cfe0feb6c2c24110375a Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 6 Apr 2017 16:20:05 -0400 Subject: [PATCH 07/13] Add depth fail primitive appearance test. --- Specs/Scene/PrimitiveSpec.js | 58 ++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/Specs/Scene/PrimitiveSpec.js b/Specs/Scene/PrimitiveSpec.js index ca981609044b..69e6faa53780 100644 --- a/Specs/Scene/PrimitiveSpec.js +++ b/Specs/Scene/PrimitiveSpec.js @@ -156,6 +156,7 @@ defineSuite([ primitive = new Primitive(); expect(primitive.geometryInstances).not.toBeDefined(); expect(primitive.appearance).not.toBeDefined(); + expect(primitive.depthFailAppearance).not.toBeDefined(); expect(primitive.modelMatrix).toEqual(Matrix4.IDENTITY); expect(primitive.show).toEqual(true); expect(primitive.vertexCacheOptimize).toEqual(false); @@ -171,11 +172,13 @@ defineSuite([ it('Constructs with options', function() { var geometryInstances = {}; var appearance = {}; + var depthFailAppearance = {}; var modelMatrix = Matrix4.fromUniformScale(5.0); primitive = new Primitive({ geometryInstances : geometryInstances, appearance : appearance, + depthFailAppearance : depthFailAppearance, modelMatrix : modelMatrix, show : false, vertexCacheOptimize : true, @@ -190,6 +193,7 @@ defineSuite([ expect(primitive.geometryInstances).toEqual(geometryInstances); expect(primitive.appearance).toEqual(appearance); + expect(primitive.depthFailAppearance).toEqual(depthFailAppearance); expect(primitive.modelMatrix).toEqual(modelMatrix); expect(primitive.show).toEqual(false); expect(primitive.vertexCacheOptimize).toEqual(true); @@ -433,6 +437,60 @@ defineSuite([ scene._camera = camera; }); + it('renders with depth fail appearance', function() { + var rect = Rectangle.fromDegrees(-1.0, -1.0, 1.0, 1.0); + var translation = Cartesian3.multiplyByScalar(Cartesian3.normalize(ellipsoid.cartographicToCartesian(Rectangle.center(rect)), new Cartesian3()), 100.0, new Cartesian3()); + var rectInstance = new GeometryInstance({ + geometry : new RectangleGeometry({ + vertexFormat : PerInstanceColorAppearance.VERTEX_FORMAT, + ellipsoid : ellipsoid, + rectangle : rect + }), + modelMatrix : Matrix4.fromTranslation(translation, new Matrix4()), + id : 'rect', + attributes : { + color : new ColorGeometryInstanceAttribute(1.0, 1.0, 0.0, 1.0) + } + }); + var p0 = new Primitive({ + geometryInstances : rectInstance, + appearance : new PerInstanceColorAppearance({ + translucent : false + }), + asynchronous : false + }); + + var rectInstance2 = new GeometryInstance({ + geometry : new RectangleGeometry({ + vertexFormat : PerInstanceColorAppearance.VERTEX_FORMAT, + ellipsoid : ellipsoid, + rectangle : rect + }), + id : 'rect2', + attributes : { + color : new ColorGeometryInstanceAttribute(1.0, 0.0, 0.0, 1.0), + depthFailColor : new ColorGeometryInstanceAttribute(1.0, 0.0, 1.0, 1.0) + } + }); + var p1 = new Primitive({ + geometryInstances : rectInstance2, + appearance : new PerInstanceColorAppearance({ + translucent : false + }), + depthFailAppearance : new PerInstanceColorAppearance({ + translucent : false + }), + asynchronous : false + }); + + scene.primitives.add(p0); + scene.primitives.add(p1); + scene.camera.setView({ destination : rect }); + scene.renderForSpecs(); + + expect(scene).toRender([255, 0, 255, 255]); + }); + it('RTC throws with more than one instance', function() { expect(function() { return new Primitive({ From 0169370f6292c8074d312cbaf1beda6f1b8fd8ed Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 6 Apr 2017 17:03:20 -0400 Subject: [PATCH 08/13] Add data source tests and doc. --- Source/DataSources/PolylineGeometryUpdater.js | 7 + Source/DataSources/PolylineGraphics.js | 11 +- Source/Scene/Primitive.js | 2 +- Specs/DataSources/GeometryVisualizerSpec.js | 172 ++++++++++++++++++ .../PolylineGeometryUpdaterSpec.js | 59 ++++++ Specs/DataSources/PolylineGraphicsSpec.js | 12 ++ 6 files changed, 261 insertions(+), 2 deletions(-) diff --git a/Source/DataSources/PolylineGeometryUpdater.js b/Source/DataSources/PolylineGeometryUpdater.js index 422a65d0d7c2..88ec9894f8b5 100644 --- a/Source/DataSources/PolylineGeometryUpdater.js +++ b/Source/DataSources/PolylineGeometryUpdater.js @@ -172,6 +172,13 @@ define([ return this._materialProperty; } }, + /** + * Gets the material property used to fill the geometry when it fails the depth test. + * @memberof PolylineGeometryUpdater.prototype + * + * @type {MaterialProperty} + * @readonly + */ depthFailMaterialProperty : { get : function() { return this._depthFailMaterialProperty; diff --git a/Source/DataSources/PolylineGraphics.js b/Source/DataSources/PolylineGraphics.js index 70c16372e96a..d78cad84e1b6 100644 --- a/Source/DataSources/PolylineGraphics.js +++ b/Source/DataSources/PolylineGraphics.js @@ -93,6 +93,15 @@ define([ */ material : createMaterialPropertyDescriptor('material'), + /** + * Gets or sets the Property specifying the material used to draw the polyline when it fails the depth test. + *

+ * Requires the EXT_frag_depth WebGL extension to render properly. If the extension is not supported, + * there may be artifacts. + *

+ * @type {MaterialProperty} + * @default undefined + */ depthFailMaterial : createMaterialPropertyDescriptor('depthFailMaterial'), /** @@ -127,7 +136,7 @@ define([ * @default Cesium.Math.RADIANS_PER_DEGREE */ granularity : createPropertyDescriptor('granularity'), - + /** * Get or sets the enum Property specifying whether the polyline * casts or receives shadows from each light source. diff --git a/Source/Scene/Primitive.js b/Source/Scene/Primitive.js index 70e8c2ec2e92..843e02fcd666 100644 --- a/Source/Scene/Primitive.js +++ b/Source/Scene/Primitive.js @@ -239,7 +239,7 @@ define([ * *

* Requires the EXT_frag_depth WebGL extension to render properly. If the extension is not supported, - * a DeveloperError will be thrown. + * there may be artifacts. *

* @type Appearance * diff --git a/Specs/DataSources/GeometryVisualizerSpec.js b/Specs/DataSources/GeometryVisualizerSpec.js index 80f5b7cc3e52..9157d46e4aab 100644 --- a/Specs/DataSources/GeometryVisualizerSpec.js +++ b/Specs/DataSources/GeometryVisualizerSpec.js @@ -22,6 +22,8 @@ defineSuite([ 'DataSources/StaticGeometryPerMaterialBatch', 'DataSources/StaticGroundGeometryColorBatch', 'DataSources/StaticOutlineGeometryBatch', + 'DataSources/PolylineGeometryUpdater', + 'DataSources/PolylineGraphics', 'Scene/GroundPrimitive', 'Scene/ShadowMode', 'Specs/createDynamicProperty', @@ -50,6 +52,8 @@ defineSuite([ StaticGeometryPerMaterialBatch, StaticGroundGeometryColorBatch, StaticOutlineGeometryBatch, + PolylineGeometryUpdater, + PolylineGraphics, GroundPrimitive, ShadowMode, createDynamicProperty, @@ -348,6 +352,174 @@ defineSuite([ return createAndRemoveGeometryWithShadows(ShadowMode.RECEIVE_ONLY); }); + it('Creates and removes static color material and static color depth fail material', function() { + var objects = new EntityCollection(); + var visualizer = new GeometryVisualizer(PolylineGeometryUpdater, scene, objects); + + var polyline = new PolylineGraphics(); + polyline.positions = new ConstantProperty([Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 1.0)]); + polyline.material = new ColorMaterialProperty(); + polyline.depthFailMaterial = new ColorMaterialProperty(); + + var entity = new Entity(); + entity.position = new ConstantPositionProperty(new Cartesian3(1234, 5678, 9101112)); + entity.polyline = polyline; + objects.add(entity); + + return pollToPromise(function() { + scene.initializeFrame(); + var isUpdated = visualizer.update(time); + scene.render(time); + return isUpdated; + }).then(function() { + var primitive = scene.primitives.get(0); + var attributes = primitive.getGeometryInstanceAttributes(entity); + expect(attributes).toBeDefined(); + expect(attributes.show).toEqual(ShowGeometryInstanceAttribute.toValue(true)); + expect(attributes.color).toEqual(ColorGeometryInstanceAttribute.toValue(Color.WHITE)); + expect(attributes.depthFailColor).toEqual(ColorGeometryInstanceAttribute.toValue(Color.WHITE)); + expect(primitive.appearance).toBeInstanceOf(PolylineGeometryUpdater.perInstanceColorAppearanceType); + expect(primitive.depthFailAppearance).toBeInstanceOf(PolylineGeometryUpdater.perInstanceColorAppearanceType); + + objects.remove(entity); + + return pollToPromise(function() { + scene.initializeFrame(); + expect(visualizer.update(time)).toBe(true); + scene.render(time); + return scene.primitives.length === 0; + }).then(function(){ + visualizer.destroy(); + }); + }); + }); + + it('Creates and removes static color material and static depth fail material', function() { + var objects = new EntityCollection(); + var visualizer = new GeometryVisualizer(PolylineGeometryUpdater, scene, objects); + + var polyline = new PolylineGraphics(); + polyline.positions = new ConstantProperty([Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 1.0)]); + polyline.material = new ColorMaterialProperty(); + polyline.depthFailMaterial = new GridMaterialProperty(); + + var entity = new Entity(); + entity.position = new ConstantPositionProperty(new Cartesian3(1234, 5678, 9101112)); + entity.polyline = polyline; + objects.add(entity); + + return pollToPromise(function() { + scene.initializeFrame(); + var isUpdated = visualizer.update(time); + scene.render(time); + return isUpdated; + }).then(function() { + var primitive = scene.primitives.get(0); + var attributes = primitive.getGeometryInstanceAttributes(entity); + expect(attributes).toBeDefined(); + expect(attributes.show).toEqual(ShowGeometryInstanceAttribute.toValue(true)); + expect(attributes.color).toEqual(ColorGeometryInstanceAttribute.toValue(Color.WHITE)); + expect(attributes.depthFailColor).toBeUndefined(); + expect(primitive.appearance).toBeInstanceOf(PolylineGeometryUpdater.perInstanceColorAppearanceType); + expect(primitive.depthFailAppearance).toBeInstanceOf(PolylineGeometryUpdater.materialAppearanceType); + + objects.remove(entity); + + return pollToPromise(function() { + scene.initializeFrame(); + expect(visualizer.update(time)).toBe(true); + scene.render(time); + return scene.primitives.length === 0; + }).then(function(){ + visualizer.destroy(); + }); + }); + }); + + it('Creates and removes static material and static depth fail material', function() { + var objects = new EntityCollection(); + var visualizer = new GeometryVisualizer(PolylineGeometryUpdater, scene, objects); + + var polyline = new PolylineGraphics(); + polyline.positions = new ConstantProperty([Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 1.0)]); + polyline.material = new GridMaterialProperty(); + polyline.depthFailMaterial = new GridMaterialProperty(); + + var entity = new Entity(); + entity.position = new ConstantPositionProperty(new Cartesian3(1234, 5678, 9101112)); + entity.polyline = polyline; + objects.add(entity); + + return pollToPromise(function() { + scene.initializeFrame(); + var isUpdated = visualizer.update(time); + scene.render(time); + return isUpdated; + }).then(function() { + var primitive = scene.primitives.get(0); + var attributes = primitive.getGeometryInstanceAttributes(entity); + expect(attributes).toBeDefined(); + expect(attributes.show).toEqual(ShowGeometryInstanceAttribute.toValue(true)); + expect(attributes.color).toBeUndefined(); + expect(attributes.depthFailColor).toBeUndefined(); + expect(primitive.appearance).toBeInstanceOf(PolylineGeometryUpdater.materialAppearanceType); + expect(primitive.depthFailAppearance).toBeInstanceOf(PolylineGeometryUpdater.materialAppearanceType); + + objects.remove(entity); + + return pollToPromise(function() { + scene.initializeFrame(); + expect(visualizer.update(time)).toBe(true); + scene.render(time); + return scene.primitives.length === 0; + }).then(function(){ + visualizer.destroy(); + }); + }); + }); + + it('Creates and removes static material and static color depth fail material', function() { + var objects = new EntityCollection(); + var visualizer = new GeometryVisualizer(PolylineGeometryUpdater, scene, objects); + + var polyline = new PolylineGraphics(); + polyline.positions = new ConstantProperty([Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 1.0)]); + polyline.material = new GridMaterialProperty(); + polyline.depthFailMaterial = new ColorMaterialProperty(); + + var entity = new Entity(); + entity.position = new ConstantPositionProperty(new Cartesian3(1234, 5678, 9101112)); + entity.polyline = polyline; + objects.add(entity); + + return pollToPromise(function() { + scene.initializeFrame(); + var isUpdated = visualizer.update(time); + scene.render(time); + return isUpdated; + }).then(function() { + var primitive = scene.primitives.get(0); + var attributes = primitive.getGeometryInstanceAttributes(entity); + expect(attributes).toBeDefined(); + expect(attributes.show).toEqual(ShowGeometryInstanceAttribute.toValue(true)); + expect(attributes.color).toBeUndefined(); + expect(attributes.depthFailColor).toEqual(ColorGeometryInstanceAttribute.toValue(Color.WHITE)); + expect(primitive.appearance).toBeInstanceOf(PolylineGeometryUpdater.materialAppearanceType); + expect(primitive.depthFailAppearance).toBeInstanceOf(PolylineGeometryUpdater.perInstanceColorAppearanceType); + + objects.remove(entity); + + return pollToPromise(function() { + scene.initializeFrame(); + expect(visualizer.update(time)).toBe(true); + scene.render(time); + return scene.primitives.length === 0; + }).then(function(){ + visualizer.destroy(); + }); + }); + }); + it('Correctly handles geometry changing batches', function() { var objects = new EntityCollection(); var visualizer = new GeometryVisualizer(EllipseGeometryUpdater, scene, objects); diff --git a/Specs/DataSources/PolylineGeometryUpdaterSpec.js b/Specs/DataSources/PolylineGeometryUpdaterSpec.js index 5dc3db3d66ef..2b871c8371ba 100644 --- a/Specs/DataSources/PolylineGeometryUpdaterSpec.js +++ b/Specs/DataSources/PolylineGeometryUpdaterSpec.js @@ -91,6 +91,7 @@ defineSuite([ expect(updater.isClosed).toBe(false); expect(updater.fillEnabled).toBe(false); expect(updater.fillMaterialProperty).toBe(undefined); + expect(updater.depthFailMaterialProperty).toBe(undefined); expect(updater.outlineEnabled).toBe(false); expect(updater.hasConstantFill).toBe(true); expect(updater.hasConstantOutline).toBe(true); @@ -131,6 +132,7 @@ defineSuite([ expect(updater.isClosed).toBe(false); expect(updater.fillEnabled).toBe(true); expect(updater.fillMaterialProperty).toEqual(new ColorMaterialProperty(Color.WHITE)); + expect(updater.depthFailMaterialProperty).toBe(undefined); expect(updater.outlineEnabled).toBe(false); expect(updater.hasConstantFill).toBe(true); expect(updater.hasConstantOutline).toBe(true); @@ -147,6 +149,13 @@ defineSuite([ expect(updater.fillMaterialProperty).toBe(entity.polyline.material); }); + it('Polyline depth fail material is correctly exposed.', function() { + var entity = createBasicPolyline(); + var updater = new PolylineGeometryUpdater(entity, scene); + entity.polyline.depthFailMaterial = new ColorMaterialProperty(); + expect(updater.depthFailMaterialProperty).toBe(entity.polyline.depthFailMaterial); + }); + it('A time-varying positions causes geometry to be dynamic', function() { var entity = createBasicPolyline(); var updater = new PolylineGeometryUpdater(entity, scene); @@ -198,6 +207,7 @@ defineSuite([ var polyline = entity.polyline; polyline.show = new ConstantProperty(options.show); polyline.material = options.material; + polyline.depthFailMaterial = options.depthFailMaterial; polyline.width = new ConstantProperty(options.width); polyline.followSurface = new ConstantProperty(options.followSurface); @@ -221,6 +231,11 @@ defineSuite([ } else { expect(attributes.color).toBeUndefined(); } + if (options.depthFailMaterial && options.depthFailMaterial instanceof ColorMaterialProperty) { + expect(attributes.depthFailColor.value).toEqual(ColorGeometryInstanceAttribute.toValue(options.depthFailMaterial.color.getValue(time))); + } else { + expect(attributes.depthFailColor).toBeUndefined(); + } expect(attributes.show.value).toEqual(ShowGeometryInstanceAttribute.toValue(options.show)); if (options.distanceDisplayCondition) { expect(attributes.distanceDisplayCondition.value).toEqual(DistanceDisplayConditionGeometryInstanceAttribute.toValue(options.distanceDisplayCondition)); @@ -237,6 +252,28 @@ defineSuite([ }); }); + it('Creates expected per-color geometry with color depth fail appearance', function() { + validateGeometryInstance({ + show : true, + material : new ColorMaterialProperty(Color.RED), + depthFailMaterial : new ColorMaterialProperty(Color.BLUE), + width : 3, + followSurface : false, + granularity : 1.0 + }); + }); + + it('Creates expected per-color geometry with material depth fail appearance', function() { + validateGeometryInstance({ + show : true, + material : new ColorMaterialProperty(Color.RED), + depthFailMaterial : new GridMaterialProperty(), + width : 3, + followSurface : false, + granularity : 1.0 + }); + }); + it('Creates expected per-material geometry', function() { validateGeometryInstance({ show : true, @@ -247,6 +284,28 @@ defineSuite([ }); }); + it('Creates expected per-material geometry with color depth fail appearance', function() { + validateGeometryInstance({ + show : true, + material : new GridMaterialProperty(), + depthFailMaterial : new ColorMaterialProperty(Color.BLUE), + width : 4, + followSurface : true, + granularity : 0.5 + }); + }); + + it('Creates expected per-material geometry with color depth fail appearance', function() { + validateGeometryInstance({ + show : true, + material : new GridMaterialProperty(), + depthFailMaterial : new GridMaterialProperty(), + width : 4, + followSurface : true, + granularity : 0.5 + }); + }); + it('Creates expected distance display condition geometry', function() { validateGeometryInstance({ show : true, diff --git a/Specs/DataSources/PolylineGraphicsSpec.js b/Specs/DataSources/PolylineGraphicsSpec.js index 4e303b179e35..a41a146c47dd 100644 --- a/Specs/DataSources/PolylineGraphicsSpec.js +++ b/Specs/DataSources/PolylineGraphicsSpec.js @@ -22,6 +22,7 @@ defineSuite([ it('creates expected instance from raw assignment and construction', function() { var options = { material : Color.BLUE, + depthFailMaterial : Color.RED, positions : [], show : true, width : 1, @@ -33,6 +34,7 @@ defineSuite([ var polyline = new PolylineGraphics(options); expect(polyline.material).toBeInstanceOf(ColorMaterialProperty); + expect(polyline.depthFailMaterial).toBeInstanceOf(ColorMaterialProperty); expect(polyline.positions).toBeInstanceOf(ConstantProperty); expect(polyline.show).toBeInstanceOf(ConstantProperty); expect(polyline.width).toBeInstanceOf(ConstantProperty); @@ -42,6 +44,7 @@ defineSuite([ expect(polyline.distanceDisplayCondition).toBeInstanceOf(ConstantProperty); expect(polyline.material.color.getValue()).toEqual(options.material); + expect(polyline.depthFailMaterial.color.getValue()).toEqual(options.depthFailMaterial); expect(polyline.positions.getValue()).toEqual(options.positions); expect(polyline.show.getValue()).toEqual(options.show); expect(polyline.width.getValue()).toEqual(options.width); @@ -54,6 +57,7 @@ defineSuite([ it('merge assigns unassigned properties', function() { var source = new PolylineGraphics(); source.material = new ColorMaterialProperty(); + source.depthFailMaterial = new ColorMaterialProperty(); source.positions = new ConstantProperty(); source.width = new ConstantProperty(); source.show = new ConstantProperty(); @@ -65,6 +69,7 @@ defineSuite([ var target = new PolylineGraphics(); target.merge(source); expect(target.material).toBe(source.material); + expect(target.depthFailMaterial).toBe(source.depthFailMaterial); expect(target.positions).toBe(source.positions); expect(target.width).toBe(source.width); expect(target.show).toBe(source.show); @@ -77,6 +82,7 @@ defineSuite([ it('merge does not assign assigned properties', function() { var source = new PolylineGraphics(); source.material = new ColorMaterialProperty(); + source.depthFailMaterial = new ColorMaterialProperty(); source.positions = new ConstantProperty(); source.width = new ConstantProperty(); source.show = new ConstantProperty(); @@ -86,6 +92,7 @@ defineSuite([ source.distanceDisplayCondition = new ConstantProperty(); var color = new ColorMaterialProperty(); + var depthFailColor = new ColorMaterialProperty(); var positions = new ConstantProperty(); var width = new ConstantProperty(); var show = new ConstantProperty(); @@ -96,6 +103,7 @@ defineSuite([ var target = new PolylineGraphics(); target.material = color; + target.depthFailMaterial = depthFailColor; target.positions = positions; target.width = width; target.show = show; @@ -106,6 +114,7 @@ defineSuite([ target.merge(source); expect(target.material).toBe(color); + expect(target.depthFailMaterial).toBe(depthFailColor); expect(target.positions).toBe(positions); expect(target.width).toBe(width); expect(target.show).toBe(show); @@ -118,6 +127,7 @@ defineSuite([ it('clone works', function() { var source = new PolylineGraphics(); source.material = new ColorMaterialProperty(); + source.depthFailMaterial = new ColorMaterialProperty(); source.width = new ConstantProperty(); source.positions = new ConstantProperty(); source.show = new ConstantProperty(); @@ -128,6 +138,7 @@ defineSuite([ var result = source.clone(); expect(result.material).toBe(source.material); + expect(result.depthFailMaterial).toBe(source.depthFailMaterial); expect(result.positions).toBe(source.positions); expect(result.width).toBe(source.width); expect(result.show).toBe(source.show); @@ -147,6 +158,7 @@ defineSuite([ it('raises definitionChanged when a property is assigned or modified', function() { var property = new PolylineGraphics(); testMaterialDefinitionChanged(property, 'material', Color.RED, Color.BLUE); + testMaterialDefinitionChanged(property, 'depthFailMaterial', Color.RED, Color.BLUE); testDefinitionChanged(property, 'show', true, false); testDefinitionChanged(property, 'positions', [], []); testDefinitionChanged(property, 'width', 3, 4); From 568d6967916b99f99dd530436132e0947e9b2d77 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 6 Apr 2017 17:13:16 -0400 Subject: [PATCH 09/13] Revert Hello World and add Sandcastle example. --- Apps/Sandcastle/gallery/Ground Clamping.html | 47 +++++++ Apps/Sandcastle/gallery/Hello World.html | 130 ------------------- 2 files changed, 47 insertions(+), 130 deletions(-) diff --git a/Apps/Sandcastle/gallery/Ground Clamping.html b/Apps/Sandcastle/gallery/Ground Clamping.html index f52903ab5a09..f98829dc1c90 100644 --- a/Apps/Sandcastle/gallery/Ground Clamping.html +++ b/Apps/Sandcastle/gallery/Ground Clamping.html @@ -149,6 +149,53 @@ viewer.trackedEntity = e; } +}, { + text : 'Sample line positions and draw with depth test disabled', + onselect : function() { + var length = 1000; + + var startLon = Cesium.Math.toRadians(86.953793); + var endLon = Cesium.Math.toRadians(86.896497); + + var lat = Cesium.Math.toRadians(27.988257); + + var terrainSamplePositions = []; + for (var i = 0; i < length; ++i) { + var lon = Cesium.Math.lerp(endLon, startLon, i / (length - 1)); + var position = new Cesium.Cartographic(lon, lat); + terrainSamplePositions.push(position); + } + + Cesium.when(Cesium.sampleTerrainMostDetailed(viewer.terrainProvider, terrainSamplePositions), function(samples) { + var offset = 10.0; + for (var i = 0; i < samples.length; ++i) { + samples[i].height += offset; + } + + viewer.entities.add({ + polyline : { + positions : Cesium.Ellipsoid.WGS84.cartographicArrayToCartesianArray(samples), + followSurface : false, + width : 5, + material : new Cesium.PolylineOutlineMaterialProperty({ + color : Cesium.Color.ORANGE, + outlineWidth : 2, + outlineColor : Cesium.Color.BLACK + }), + depthFailMaterial : new Cesium.PolylineOutlineMaterialProperty({ + color : Cesium.Color.RED, + outlineWidth : 2, + outlineColor : Cesium.Color.BLACK + }) + } + }); + + var target = new Cesium.Cartesian3(300770.50872389384, 5634912.131394585, 2978152.2865545116); + var offset = new Cesium.Cartesian3(6344.974098678562, -793.3419798081741, 2499.9508860763162); + viewer.camera.lookAt(target, offset); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + }); + } }], 'zoomButtons'); Sandcastle.reset = function () { diff --git a/Apps/Sandcastle/gallery/Hello World.html b/Apps/Sandcastle/gallery/Hello World.html index 48a49996c6d4..640e8e317705 100644 --- a/Apps/Sandcastle/gallery/Hello World.html +++ b/Apps/Sandcastle/gallery/Hello World.html @@ -28,136 +28,6 @@ 'use strict'; //Sandcastle_Begin var viewer = new Cesium.Viewer('cesiumContainer'); -viewer.terrainProvider = new Cesium.CesiumTerrainProvider({ - url : 'https://assets.agi.com/stk-terrain/world', - requestWaterMask : true, - requestVertexNormals : true -}); - -var scene = viewer.scene; -scene.globe.depthTestAgainstTerrain = true; - -(function lookAtMtEverest() { - var target = new Cesium.Cartesian3(300770.50872389384, 5634912.131394585, 2978152.2865545116); - var offset = new Cesium.Cartesian3(6344.974098678562, -793.3419798081741, 2499.9508860763162); - viewer.camera.lookAt(target, offset); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); -})(); - -function createPositions() { - var length = 1000; - - var startLon = Cesium.Math.toRadians(86.953793); - var endLon = Cesium.Math.toRadians(86.896497); - - var lat = Cesium.Math.toRadians(27.988257); - - var terrainSamplePositions = []; - for (var i = 0; i < length; ++i) { - var lon = Cesium.Math.lerp(endLon, startLon, i / (length - 1)); - var position = new Cesium.Cartographic(lon, lat); - terrainSamplePositions.push(position); - } - return terrainSamplePositions; -} - -Cesium.when(Cesium.sampleTerrainMostDetailed(viewer.terrainProvider, createPositions()), function(samples) { - var offset = 10.0; - for (var i = 0; i < samples.length; ++i) { - samples[i].height += offset; - } - - var cartesianSamples = Cesium.Ellipsoid.WGS84.cartographicArrayToCartesianArray(samples); - - /* - viewer.entities.add({ - polyline : { - positions : cartesianSamples, - followSurface : false, - width : 5, - material : Cesium.Color.RED, - depthFailMaterial : Cesium.Color.BLUE - } - }); - */ - - /* - viewer.entities.add({ - polyline : { - positions : cartesianSamples, - followSurface : false, - width : 5, - material : Cesium.Color.RED, - depthFailMaterial : new Cesium.PolylineOutlineMaterialProperty({ - color : Cesium.Color.ORANGE, - outlineWidth : 2, - outlineColor : Cesium.Color.BLACK - }) - } - }); - */ - - /* - viewer.entities.add({ - polyline : { - positions : cartesianSamples, - followSurface : false, - width : 5, - material : new Cesium.PolylineOutlineMaterialProperty({ - color : Cesium.Color.ORANGE, - outlineWidth : 2, - outlineColor : Cesium.Color.BLACK - }), - depthFailMaterial : Cesium.Color.RED - } - }); - */ - - viewer.entities.add({ - polyline : { - positions : cartesianSamples, - followSurface : false, - width : 5, - material : new Cesium.PolylineOutlineMaterialProperty({ - color : Cesium.Color.ORANGE, - outlineWidth : 2, - outlineColor : Cesium.Color.BLACK - }), - depthFailMaterial : new Cesium.PolylineOutlineMaterialProperty({ - color : Cesium.Color.RED, - outlineWidth : 2, - outlineColor : Cesium.Color.BLACK - }) - } - }); -}); - -/* -var dimension = 500.0; -var positionCart = new Cesium.Cartographic(1.51728, 0.488037, 8407.4); -var position = Cesium.Ellipsoid.WGS84.cartographicToCartesian(positionCart); - -scene.primitives.add(new Cesium.Primitive({ - geometryInstances : new Cesium.GeometryInstance({ - geometry : Cesium.BoxGeometry.fromDimensions({ - vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, - dimensions : new Cesium.Cartesian3(dimension, dimension, dimension) - }), - modelMatrix : Cesium.Transforms.eastNorthUpToFixedFrame(position), - attributes : { - color : Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 0.0, 1.0, 0.5)), - depthFailColor : Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 0.0, 0.0, 0.5)) - } - }), - appearance : new Cesium.PerInstanceColorAppearance({ - closed: true - }), - depthFailAppearance : new Cesium.PerInstanceColorAppearance({ - closed: true - }) -})); -*/ - //Sandcastle_End Sandcastle.finishedLoading(); } From 2774f0fd2ee29d54ecfa7e83775e536fc59070e5 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 6 Apr 2017 17:23:42 -0400 Subject: [PATCH 10/13] Fix jsHint error. --- Apps/Sandcastle/gallery/Ground Clamping.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Apps/Sandcastle/gallery/Ground Clamping.html b/Apps/Sandcastle/gallery/Ground Clamping.html index f98829dc1c90..66c66bf69620 100644 --- a/Apps/Sandcastle/gallery/Ground Clamping.html +++ b/Apps/Sandcastle/gallery/Ground Clamping.html @@ -191,7 +191,7 @@ }); var target = new Cesium.Cartesian3(300770.50872389384, 5634912.131394585, 2978152.2865545116); - var offset = new Cesium.Cartesian3(6344.974098678562, -793.3419798081741, 2499.9508860763162); + offset = new Cesium.Cartesian3(6344.974098678562, -793.3419798081741, 2499.9508860763162); viewer.camera.lookAt(target, offset); viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); }); From 880c03f3ae91888f76fc7cbaeb0a6b8f80517384 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 6 Apr 2017 18:51:03 -0400 Subject: [PATCH 11/13] Fix WebGL stub tests. --- Source/Scene/Primitive.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Source/Scene/Primitive.js b/Source/Scene/Primitive.js index 843e02fcd666..0bfe4d91b11a 100644 --- a/Source/Scene/Primitive.js +++ b/Source/Scene/Primitive.js @@ -1686,8 +1686,12 @@ define([ var castShadows = ShadowMode.castShadows(primitive.shadows); var receiveShadows = ShadowMode.receiveShadows(primitive.shadows); var colorLength = colorCommands.length; + + var factor = twoPasses ? 2 : 1; + factor *= defined(primitive._depthFailAppearance) ? 2 : 1; + for (var j = 0; j < colorLength; ++j) { - var sphereIndex = twoPasses ? Math.floor(j / 2) : j; + var sphereIndex = Math.floor(j / factor); var colorCommand = colorCommands[j]; colorCommand.modelMatrix = modelMatrix; colorCommand.boundingVolume = boundingSpheres[sphereIndex]; From 7965baa610bee23ea69129ebd770e6d8d620e846 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 6 Apr 2017 19:04:10 -0400 Subject: [PATCH 12/13] Update CHANGES.md. --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 145981237412..85cbc00a0116 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,7 +4,7 @@ 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) - +* Added a `depthFailMaterial` property to line entities, which is the material used to render the line when it fails the depth test. [#5160](https://github.com/AnalyticalGraphicsInc/cesium/pull/5160) ### 1.32 - 2017-04-03 * Deprecated From 8a290147feab5ce63e1a94467ccee607cdf5bdc2 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 11 Apr 2017 16:23:32 -0400 Subject: [PATCH 13/13] Swap depth fail draw order. --- Source/Scene/Primitive.js | 64 +++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/Source/Scene/Primitive.js b/Source/Scene/Primitive.js index e30c1c465017..9b1afab234ce 100644 --- a/Source/Scene/Primitive.js +++ b/Source/Scene/Primitive.js @@ -1545,39 +1545,7 @@ define([ for (var i = 0; i < length; ++i) { var colorCommand; - if (twoPasses) { - colorCommand = colorCommands[i]; - if (!defined(colorCommand)) { - colorCommand = colorCommands[i] = new DrawCommand({ - owner : primitive, - primitiveType : primitive._primitiveType - }); - } - colorCommand.vertexArray = primitive._va[vaIndex]; - colorCommand.renderState = primitive._backFaceRS; - colorCommand.shaderProgram = primitive._sp; - colorCommand.uniformMap = uniforms; - colorCommand.pass = pass; - - ++i; - } - - colorCommand = colorCommands[i]; - if (!defined(colorCommand)) { - colorCommand = colorCommands[i] = new DrawCommand({ - owner : primitive, - primitiveType : primitive._primitiveType - }); - } - colorCommand.vertexArray = primitive._va[vaIndex]; - colorCommand.renderState = primitive._frontFaceRS; - colorCommand.shaderProgram = primitive._sp; - colorCommand.uniformMap = uniforms; - colorCommand.pass = pass; - if (defined(primitive._depthFailAppearance)) { - ++i; - if (twoPasses) { colorCommand = colorCommands[i]; if (!defined(colorCommand)) { @@ -1607,7 +1575,39 @@ define([ colorCommand.shaderProgram = primitive._spDepthFail; colorCommand.uniformMap = depthFailUniforms; colorCommand.pass = pass; + + ++i; + } + + if (twoPasses) { + colorCommand = colorCommands[i]; + if (!defined(colorCommand)) { + colorCommand = colorCommands[i] = new DrawCommand({ + owner : primitive, + primitiveType : primitive._primitiveType + }); + } + colorCommand.vertexArray = primitive._va[vaIndex]; + colorCommand.renderState = primitive._backFaceRS; + colorCommand.shaderProgram = primitive._sp; + colorCommand.uniformMap = uniforms; + colorCommand.pass = pass; + + ++i; + } + + colorCommand = colorCommands[i]; + if (!defined(colorCommand)) { + colorCommand = colorCommands[i] = new DrawCommand({ + owner : primitive, + primitiveType : primitive._primitiveType + }); } + colorCommand.vertexArray = primitive._va[vaIndex]; + colorCommand.renderState = primitive._frontFaceRS; + colorCommand.shaderProgram = primitive._sp; + colorCommand.uniformMap = uniforms; + colorCommand.pass = pass; var pickCommand = pickCommands[m]; if (!defined(pickCommand)) {