From a67f063f004b01d9be7394c073729ab884181900 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 22 Aug 2017 18:00:37 -0400 Subject: [PATCH 1/9] Render 3D Tiles after terrain depth is cleared. Also render classification on both terrain and 3D Tiles. --- Source/Scene/Scene.js | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index f78c96c463a0..81eabd6c3926 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -1927,17 +1927,6 @@ define([ executeCommand(commands[j], scene, context, passState); } - us.updatePass(Pass.CESIUM_3D_TILE); - commands = frustumCommands.commands[Pass.CESIUM_3D_TILE]; - length = frustumCommands.indices[Pass.CESIUM_3D_TILE]; - for (j = 0; j < length; ++j) { - executeCommand(commands[j], scene, context, passState); - } - - if (length > 0 && context.stencilBuffer) { - scene._stencilClearCommand.execute(context, passState); - } - if (defined(globeDepth) && environmentState.useGlobeDepthFramebuffer && (scene.copyGlobeDepth || scene.debugShowGlobeDepth)) { globeDepth.update(context, passState); globeDepth.executeCopyDepth(context, passState); @@ -1954,11 +1943,6 @@ define([ executeCommand(commands[j], scene, context, passState); } - // Clear the stencil after the ground pass - if (length > 0 && context.stencilBuffer) { - scene._stencilClearCommand.execute(context, passState); - } - if (clearGlobeDepth) { clearDepth.execute(context, passState); if (useDepthPlane) { @@ -1966,6 +1950,24 @@ define([ } } + us.updatePass(Pass.CESIUM_3D_TILE); + commands = frustumCommands.commands[Pass.CESIUM_3D_TILE]; + length = frustumCommands.indices[Pass.CESIUM_3D_TILE]; + for (j = 0; j < length; ++j) { + executeCommand(commands[j], scene, context, passState); + } + + if (length > 0 && context.stencilBuffer) { + scene._stencilClearCommand.execute(context, passState); + } + + us.updatePass(Pass.GROUND); + commands = frustumCommands.commands[Pass.GROUND]; + length = frustumCommands.indices[Pass.GROUND]; + for (j = 0; j < length; ++j) { + executeCommand(commands[j], scene, context, passState); + } + // Execute commands in order by pass up to the translucent pass. // Translucent geometry needs special handling (sorting/OIT). var startPass = Pass.GROUND + 1; From ee2f6aeab3ddcb6fdac09b0ecca6e4c6b9b010b3 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 23 Aug 2017 14:59:15 -0400 Subject: [PATCH 2/9] Fix depth picking 3D Tiles. Add option to classify terrain, 3D Tiles or both. --- Apps/Sandcastle/gallery/Classification.html | 15 ++- .../gallery/development/Ground Primitive.html | 30 +++-- Source/Renderer/Pass.js | 11 +- Source/Scene/ClassificationPrimitive.js | 103 ++++++++++++++---- Source/Scene/ClassificationType.js | 37 +++++++ Source/Scene/GroundPrimitive.js | 64 +++++++++-- Source/Scene/Scene.js | 14 +-- .../passCesium3DTileClassification.glsl | 9 ++ .../Shaders/Builtin/Constants/passGround.glsl | 9 -- .../Shaders/Builtin/Constants/passOpaque.glsl | 2 +- .../Constants/passTerrainClassification.glsl | 9 ++ .../Builtin/Constants/passTranslucent.glsl | 2 +- 12 files changed, 241 insertions(+), 64 deletions(-) create mode 100644 Source/Scene/ClassificationType.js create mode 100644 Source/Shaders/Builtin/Constants/passCesium3DTileClassification.glsl delete mode 100644 Source/Shaders/Builtin/Constants/passGround.glsl create mode 100644 Source/Shaders/Builtin/Constants/passTerrainClassification.glsl diff --git a/Apps/Sandcastle/gallery/Classification.html b/Apps/Sandcastle/gallery/Classification.html index d18be7ca4480..6f6b8ea21f2b 100644 --- a/Apps/Sandcastle/gallery/Classification.html +++ b/Apps/Sandcastle/gallery/Classification.html @@ -73,7 +73,8 @@ color : Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 0.0, 0.0, 0.5)) }, id : 'volume' - }) + }), + classificationType : Cesium.ClassificationType.CESIUM_3D_TILES })); camera.setView({ @@ -106,7 +107,8 @@ color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.fromCssColorString('#F26419').withAlpha(0.5)) }, id : 'volume 1' - }) + }), + classificationType : Cesium.ClassificationType.CESIUM_3D_TILES })); center = new Cesium.Cartesian3(1216394.3346955755, -4736207.431365568, 4081336.7768881875); @@ -125,7 +127,8 @@ color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.fromCssColorString('#F03A47').withAlpha(0.5)) }, id : 'volume 2' - }) + }), + classificationType : Cesium.ClassificationType.CESIUM_3D_TILES })); center = new Cesium.Cartesian3(1216388.1664430483, -4736210.034324032, 4081332.9324705894); @@ -143,7 +146,8 @@ color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.fromCssColorString('#004FFF').withAlpha(0.5)) }, id : 'volume 3' - }) + }), + classificationType : Cesium.ClassificationType.CESIUM_3D_TILES })); center = new Cesium.Cartesian3(1216383.1478702603, -4736211.716097012, 4081329.551077661); @@ -161,7 +165,8 @@ color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.fromCssColorString('#55DDE0').withAlpha(0.5)) }, id : 'volume 4' - }) + }), + classificationType : Cesium.ClassificationType.CESIUM_3D_TILES })); camera.setView({ diff --git a/Apps/Sandcastle/gallery/development/Ground Primitive.html b/Apps/Sandcastle/gallery/development/Ground Primitive.html index b59eb7973999..fcce59b8bd19 100644 --- a/Apps/Sandcastle/gallery/development/Ground Primitive.html +++ b/Apps/Sandcastle/gallery/development/Ground Primitive.html @@ -68,7 +68,8 @@ color: Cesium.ColorGeometryInstanceAttribute.fromColor(color) }, id : 'polygon 1' - }) + }), + classificationType : Cesium.ClassificationType.TERRAIN })); // Same polygon slightly offset and overlapping. @@ -89,7 +90,8 @@ color: Cesium.ColorGeometryInstanceAttribute.fromColor(color) }, id : 'polygon 2' - }) + }), + classificationType : Cesium.ClassificationType.TERRAIN })); // Same polygon slightly offset and overlapping. @@ -110,7 +112,8 @@ color: Cesium.ColorGeometryInstanceAttribute.fromColor(color) }, id : 'polygon 3' - }) + }), + classificationType : Cesium.ClassificationType.TERRAIN })); } @@ -204,7 +207,8 @@ var show = new Cesium.ShowGeometryInstanceAttribute(true); var instances = createBatchedInstances(color, show); scene.groundPrimitives.add(new Cesium.GroundPrimitive({ - geometryInstances : instances + geometryInstances : instances, + classificationType : Cesium.ClassificationType.TERRAIN })); viewOverlappingPolygons(); @@ -216,7 +220,8 @@ var instances = createBatchedInstances(color, show); var primitive = scene.groundPrimitives.add(new Cesium.GroundPrimitive({ - geometryInstances : instances + geometryInstances : instances, + classificationType : Cesium.ClassificationType.TERRAIN })); color = new Cesium.ColorGeometryInstanceAttribute(1.0, 0.0, 1.0, 0.5); @@ -230,7 +235,8 @@ } var pickPrimitive = scene.groundPrimitives.add(new Cesium.GroundPrimitive({ - geometryInstances : instances + geometryInstances : instances, + classificationType : Cesium.ClassificationType.TERRAIN })); viewOverlappingPolygons(); @@ -270,7 +276,8 @@ color : Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 0.0, 0.0, 0.5)) }, id : 'circle' - }) + }), + classificationType : Cesium.ClassificationType.TERRAIN })); // Ellipse Geometry @@ -285,7 +292,8 @@ color : Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(0.0, 1.0, 1.0, 0.5)) }, id : 'ellipse' - }) + }), + classificationType : Cesium.ClassificationType.TERRAIN })); // Corridor Geometry @@ -303,7 +311,8 @@ color : Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(0.0, 0.0, 1.0, 0.5)) }, id : 'corridor' - }) + }), + classificationType : Cesium.ClassificationType.TERRAIN })); // Rectangle geometry @@ -317,7 +326,8 @@ color: Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(0.0, 1.0, 0.0, 0.5)) }, id : 'rectangle' - }) + }), + classificationType : Cesium.ClassificationType.TERRAIN })); }); diff --git a/Source/Renderer/Pass.js b/Source/Renderer/Pass.js index a5f7bdbb04dd..07dd0bb5bd90 100644 --- a/Source/Renderer/Pass.js +++ b/Source/Renderer/Pass.js @@ -21,11 +21,12 @@ define([ COMPUTE : 1, GLOBE : 2, CESIUM_3D_TILE : 3, - GROUND : 4, - OPAQUE : 5, - TRANSLUCENT : 6, - OVERLAY : 7, - NUMBER_OF_PASSES : 8 + TERRAIN_CLASSIFICATION : 4, + CESIUM_3D_TILE_CLASSIFICATION : 5, + OPAQUE : 6, + TRANSLUCENT : 7, + OVERLAY : 8, + NUMBER_OF_PASSES : 9 }; return freezeObject(Pass); diff --git a/Source/Scene/ClassificationPrimitive.js b/Source/Scene/ClassificationPrimitive.js index ae0d0ef2f7fb..9692354246e6 100644 --- a/Source/Scene/ClassificationPrimitive.js +++ b/Source/Scene/ClassificationPrimitive.js @@ -16,6 +16,7 @@ define([ '../Shaders/ShadowVolumeVS', '../ThirdParty/when', './BlendingState', + './ClassificationType', './DepthFunction', './PerInstanceColorAppearance', './Primitive', @@ -40,6 +41,7 @@ define([ ShadowVolumeVS, when, BlendingState, + ClassificationType, DepthFunction, PerInstanceColorAppearance, Primitive, @@ -84,6 +86,7 @@ define([ * @param {Boolean} [options.releaseGeometryInstances=true] When true, the primitive does not keep a reference to the input geometryInstances to save memory. * @param {Boolean} [options.allowPicking=true] When true, each geometry instance will only be pickable with {@link Scene#pick}. When false, GPU memory is saved. * @param {Boolean} [options.asynchronous=true] Determines if the primitive will be created asynchronously or block until ready. If false initializeTerrainHeights() must be called first. + * @param {ClassificationType} [options.classificationType=ClassificationType.BOTH] Determines whether terrain, 3D Tiles or both will be classified. * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. * @param {Boolean} [options.debugShowShadowVolume=false] For debugging only. Determines if the shadow volume for each geometry in the primitive is drawn. Must be true on * creation for the volumes to be created before the geometry is released or options.releaseGeometryInstance must be false. @@ -124,6 +127,14 @@ define([ * @default true */ this.show = defaultValue(options.show, true); + /** + * Determines whether terrain, 3D Tiles or both will be classified. + * + * @type {ClassificationType} + * + * @default ClassificationType.BOTH + */ + this.classificationType = defaultValue(options.classificationType, ClassificationType.BOTH); /** * This property is for debugging only; it is not for production use nor is it optimized. *

@@ -561,16 +572,18 @@ define([ function createColorCommands(classificationPrimitive, colorCommands) { var primitive = classificationPrimitive._primitive; var length = primitive._va.length * 3; - colorCommands.length = length; + colorCommands.length = length * 2; + var i; + var command; var vaIndex = 0; var uniformMap = primitive._batchTable.getUniformMapCallback()(classificationPrimitive._uniformMap); - for (var i = 0; i < length; i += 3) { + for (i = 0; i < length; i += 3) { var vertexArray = primitive._va[vaIndex++]; // stencil preload command - var command = colorCommands[i]; + command = colorCommands[i]; if (!defined(command)) { command = colorCommands[i] = new DrawCommand({ owner : classificationPrimitive, @@ -582,7 +595,7 @@ define([ command.renderState = classificationPrimitive._rsStencilPreloadPass; command.shaderProgram = classificationPrimitive._sp; command.uniformMap = uniformMap; - command.pass = Pass.GROUND; + command.pass = Pass.TERRAIN_CLASSIFICATION; // stencil depth command command = colorCommands[i + 1]; @@ -597,7 +610,7 @@ define([ command.renderState = classificationPrimitive._rsStencilDepthPass; command.shaderProgram = classificationPrimitive._sp; command.uniformMap = uniformMap; - command.pass = Pass.GROUND; + command.pass = Pass.TERRAIN_CLASSIFICATION; // color command command = colorCommands[i + 2]; @@ -612,7 +625,12 @@ define([ command.renderState = classificationPrimitive._rsColorPass; command.shaderProgram = classificationPrimitive._sp; command.uniformMap = uniformMap; - command.pass = Pass.GROUND; + command.pass = Pass.TERRAIN_CLASSIFICATION; + } + + for (i = 0; i < length; ++i) { + command = colorCommands[length + i] = DrawCommand.shallowClone(colorCommands[i], colorCommands[length + i]); + command.pass = Pass.CESIUM_3D_TILE_CLASSIFICATION; } } @@ -620,12 +638,14 @@ define([ var primitive = classificationPrimitive._primitive; var pickOffsets = primitive._pickOffsets; var length = pickOffsets.length * 3; - pickCommands.length = length; + pickCommands.length = length * 2; + var j; + var command; var pickIndex = 0; var uniformMap = primitive._batchTable.getUniformMapCallback()(classificationPrimitive._uniformMap); - for (var j = 0; j < length; j += 3) { + for (j = 0; j < length; j += 3) { var pickOffset = pickOffsets[pickIndex++]; var offset = pickOffset.offset; @@ -633,7 +653,7 @@ define([ var vertexArray = primitive._va[pickOffset.index]; // stencil preload command - var command = pickCommands[j]; + command = pickCommands[j]; if (!defined(command)) { command = pickCommands[j] = new DrawCommand({ owner : classificationPrimitive, @@ -647,7 +667,7 @@ define([ command.renderState = classificationPrimitive._rsStencilPreloadPass; command.shaderProgram = classificationPrimitive._sp; command.uniformMap = uniformMap; - command.pass = Pass.GROUND; + command.pass = Pass.TERRAIN_CLASSIFICATION; // stencil depth command command = pickCommands[j + 1]; @@ -664,7 +684,7 @@ define([ command.renderState = classificationPrimitive._rsStencilDepthPass; command.shaderProgram = classificationPrimitive._sp; command.uniformMap = uniformMap; - command.pass = Pass.GROUND; + command.pass = Pass.TERRAIN_CLASSIFICATION; // color command command = pickCommands[j + 2]; @@ -681,7 +701,12 @@ define([ command.renderState = classificationPrimitive._rsPickPass; command.shaderProgram = classificationPrimitive._spPick; command.uniformMap = uniformMap; - command.pass = Pass.GROUND; + command.pass = Pass.TERRAIN_CLASSIFICATION; + } + + for (j = 0; j < length; ++j) { + command = pickCommands[length + j] = DrawCommand.shallowClone(pickCommands[j], pickCommands[length + j]); + command.pass = Pass.CESIUM_3D_TILE_CLASSIFICATION; } } @@ -690,6 +715,34 @@ define([ createPickCommands(classificationPrimitive, pickCommands); } + function boundingVolumeIndex(commandIndex, length) { + return Math.floor((commandIndex % (length / 2)) / 3); + } + + var scratchCommandIndices = { + start : 0, + end : 0 + }; + + function getCommandIndices(classificationType, length) { + var startIndex; + var endIndex; + if (classificationType === ClassificationType.TERRAIN) { + startIndex = 0; + endIndex = length / 2; + } else if (classificationType === ClassificationType.CESIUM_3D_TILES) { + startIndex = length / 2; + endIndex = length; + } else { + startIndex = 0; + endIndex = length; + } + + scratchCommandIndices.start = startIndex; + scratchCommandIndices.end = endIndex; + return scratchCommandIndices; + } + function updateAndQueueCommands(classificationPrimitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses) { var primitive = classificationPrimitive._primitive; Primitive._updateBoundingVolumes(primitive, frameState, modelMatrix); @@ -707,12 +760,22 @@ define([ var commandList = frameState.commandList; var passes = frameState.passes; + + var indices; + var startIndex; + var endIndex; + var classificationType = classificationPrimitive.classificationType; + if (passes.render) { var colorLength = colorCommands.length; - for (var i = 0; i < colorLength; ++i) { + indices = getCommandIndices(classificationType, colorLength); + startIndex = indices.start; + endIndex = indices.end; + + for (var i = startIndex; i < endIndex; ++i) { var colorCommand = colorCommands[i]; colorCommand.modelMatrix = modelMatrix; - colorCommand.boundingVolume = boundingVolumes[Math.floor(i / 3)]; + colorCommand.boundingVolume = boundingVolumes[boundingVolumeIndex(i, colorLength)]; colorCommand.cull = cull; colorCommand.debugShowBoundingVolume = debugShowBoundingVolume; @@ -721,12 +784,14 @@ define([ } if (passes.pick) { - var pickOffsets = primitive._pickOffsets; - var length = pickOffsets.length * 3; - pickCommands.length = length; + var pickLength = pickCommands.length; + indices = getCommandIndices(classificationType, pickLength); + startIndex = indices.start; + endIndex = indices.end; - for (var j = 0; j < length; ++j) { - var pickOffset = pickOffsets[Math.floor(j / 3)]; + var pickOffsets = primitive._pickOffsets; + for (var j = startIndex; j < endIndex; ++j) { + var pickOffset = pickOffsets[boundingVolumeIndex(j, pickLength)]; var pickCommand = pickCommands[j]; pickCommand.modelMatrix = modelMatrix; pickCommand.boundingVolume = boundingVolumes[pickOffset.index]; diff --git a/Source/Scene/ClassificationType.js b/Source/Scene/ClassificationType.js new file mode 100644 index 000000000000..e3dd18f97091 --- /dev/null +++ b/Source/Scene/ClassificationType.js @@ -0,0 +1,37 @@ +define([ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * Whether a classification affects terrain, 3D Tiles or both. + * + * @exports ClassificationOption + */ + var ClassificationType = { + /** + * Only terrain will be classified. + * + * @type {Number} + * @constant + */ + TERRAIN : 0, + /** + * Only 3D Tiles will be classified. + * + * @type {Number} + * @constant + */ + CESIUM_3D_TILES : 1, + /** + * Both terrain and 3D Tiles will be classified. + * + * @type {Number} + * @constant + */ + BOTH : 2 + }; + + return freezeObject(ClassificationType); +}); diff --git a/Source/Scene/GroundPrimitive.js b/Source/Scene/GroundPrimitive.js index 9a46f35d16c4..6c0d334ce0cd 100644 --- a/Source/Scene/GroundPrimitive.js +++ b/Source/Scene/GroundPrimitive.js @@ -18,6 +18,7 @@ define([ '../Core/Rectangle', '../ThirdParty/when', './ClassificationPrimitive', + './ClassificationType', './SceneMode' ], function( BoundingSphere, @@ -39,6 +40,7 @@ define([ Rectangle, when, ClassificationPrimitive, + ClassificationType, SceneMode) { 'use strict'; @@ -78,6 +80,7 @@ define([ * @param {Boolean} [options.releaseGeometryInstances=true] When true, the primitive does not keep a reference to the input geometryInstances to save memory. * @param {Boolean} [options.allowPicking=true] When true, each geometry instance will only be pickable with {@link Scene#pick}. When false, GPU memory is saved. * @param {Boolean} [options.asynchronous=true] Determines if the primitive will be created asynchronously or block until ready. If false initializeTerrainHeights() must be called first. + * @param {ClassificationType} [options.classificationType=ClassificationType.BOTH] Determines whether terrain, 3D Tiles or both will be classified. * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. * @param {Boolean} [options.debugShowShadowVolume=false] For debugging only. Determines if the shadow volume for each geometry in the primitive is drawn. Must be true on * creation for the volumes to be created before the geometry is released or options.releaseGeometryInstance must be false. @@ -159,6 +162,14 @@ define([ * @default true */ this.show = defaultValue(options.show, true); + /** + * Determines whether terrain, 3D Tiles or both will be classified. + * + * @type {ClassificationType} + * + * @default ClassificationType.BOTH + */ + this.classificationType = defaultValue(options.classificationType, ClassificationType.BOTH); /** * This property is for debugging only; it is not for production use nor is it optimized. *

@@ -554,6 +565,34 @@ define([ } } + function boundingVolumeIndex(commandIndex, length) { + return Math.floor((commandIndex % (length / 2)) / 3); + } + + var scratchCommandIndices = { + start : 0, + end : 0 + }; + + function getCommandIndices(classificationType, length) { + var startIndex; + var endIndex; + if (classificationType === ClassificationType.TERRAIN) { + startIndex = 0; + endIndex = length / 2; + } else if (classificationType === ClassificationType.CESIUM_3D_TILES) { + startIndex = length / 2; + endIndex = length; + } else { + startIndex = 0; + endIndex = length; + } + + scratchCommandIndices.start = startIndex; + scratchCommandIndices.end = endIndex; + return scratchCommandIndices; + } + function updateAndQueueCommands(groundPrimitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses) { var boundingVolumes; if (frameState.mode === SceneMode.SCENE3D) { @@ -562,15 +601,24 @@ define([ boundingVolumes = groundPrimitive._boundingVolumes2D; } + var indices; + var startIndex; + var endIndex; + var classificationType = groundPrimitive.classificationType; + var commandList = frameState.commandList; var passes = frameState.passes; if (passes.render) { var colorLength = colorCommands.length; - for (var i = 0; i < colorLength; ++i) { + indices = getCommandIndices(classificationType, colorLength); + startIndex = indices.start; + endIndex = indices.end; + + for (var i = startIndex; i < endIndex; ++i) { var colorCommand = colorCommands[i]; colorCommand.owner = groundPrimitive; colorCommand.modelMatrix = modelMatrix; - colorCommand.boundingVolume = boundingVolumes[Math.floor(i / 3)]; + colorCommand.boundingVolume = boundingVolumes[boundingVolumeIndex(i, colorLength)]; colorCommand.cull = cull; colorCommand.debugShowBoundingVolume = debugShowBoundingVolume; @@ -579,13 +627,15 @@ define([ } if (passes.pick) { + var pickLength = pickCommands.length; + indices = getCommandIndices(classificationType, pickLength); + startIndex = indices.start; + endIndex = indices.end; + var primitive = groundPrimitive._primitive._primitive; var pickOffsets = primitive._pickOffsets; - var length = pickOffsets.length * 3; - pickCommands.length = length; - - for (var j = 0; j < length; ++j) { - var pickOffset = pickOffsets[Math.floor(j / 3)]; + for (var j = startIndex; j < endIndex; ++j) { + var pickOffset = pickOffsets[boundingVolumeIndex(j, pickLength)]; var bv = boundingVolumes[pickOffset.index]; var pickCommand = pickCommands[j]; diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 81eabd6c3926..2eaacf1baea6 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -1936,9 +1936,9 @@ define([ passState.framebuffer = fb; } - us.updatePass(Pass.GROUND); - commands = frustumCommands.commands[Pass.GROUND]; - length = frustumCommands.indices[Pass.GROUND]; + us.updatePass(Pass.TERRAIN_CLASSIFICATION); + commands = frustumCommands.commands[Pass.TERRAIN_CLASSIFICATION]; + length = frustumCommands.indices[Pass.TERRAIN_CLASSIFICATION]; for (j = 0; j < length; ++j) { executeCommand(commands[j], scene, context, passState); } @@ -1961,16 +1961,16 @@ define([ scene._stencilClearCommand.execute(context, passState); } - us.updatePass(Pass.GROUND); - commands = frustumCommands.commands[Pass.GROUND]; - length = frustumCommands.indices[Pass.GROUND]; + us.updatePass(Pass.CESIUM_3D_TILE_CLASSIFICATION); + commands = frustumCommands.commands[Pass.CESIUM_3D_TILE_CLASSIFICATION]; + length = frustumCommands.indices[Pass.CESIUM_3D_TILE_CLASSIFICATION]; for (j = 0; j < length; ++j) { executeCommand(commands[j], scene, context, passState); } // Execute commands in order by pass up to the translucent pass. // Translucent geometry needs special handling (sorting/OIT). - var startPass = Pass.GROUND + 1; + var startPass = Pass.CESIUM_3D_TILE_CLASSIFICATION + 1; var endPass = Pass.TRANSLUCENT; for (var pass = startPass; pass < endPass; ++pass) { us.updatePass(pass); diff --git a/Source/Shaders/Builtin/Constants/passCesium3DTileClassification.glsl b/Source/Shaders/Builtin/Constants/passCesium3DTileClassification.glsl new file mode 100644 index 000000000000..253b34ea8bc8 --- /dev/null +++ b/Source/Shaders/Builtin/Constants/passCesium3DTileClassification.glsl @@ -0,0 +1,9 @@ +/** + * The automatic GLSL constant for {@link Pass#CESIUM_3D_TILE_CLASSIFICATION} + * + * @name czm_passCesium3DTileClassification + * @glslConstant + * + * @see czm_pass + */ +const float czm_passCesium3DTileClassification = 5.0; diff --git a/Source/Shaders/Builtin/Constants/passGround.glsl b/Source/Shaders/Builtin/Constants/passGround.glsl deleted file mode 100644 index 427bc235d4ba..000000000000 --- a/Source/Shaders/Builtin/Constants/passGround.glsl +++ /dev/null @@ -1,9 +0,0 @@ -/** - * The automatic GLSL constant for {@link Pass#GROUND} - * - * @name czm_passGround - * @glslConstant - * - * @see czm_pass - */ -const float czm_passGround = 4.0; diff --git a/Source/Shaders/Builtin/Constants/passOpaque.glsl b/Source/Shaders/Builtin/Constants/passOpaque.glsl index 7f7fbe11276e..4e3994f4ff3c 100644 --- a/Source/Shaders/Builtin/Constants/passOpaque.glsl +++ b/Source/Shaders/Builtin/Constants/passOpaque.glsl @@ -6,4 +6,4 @@ * * @see czm_pass */ -const float czm_passOpaque = 5.0; +const float czm_passOpaque = 6.0; diff --git a/Source/Shaders/Builtin/Constants/passTerrainClassification.glsl b/Source/Shaders/Builtin/Constants/passTerrainClassification.glsl new file mode 100644 index 000000000000..7fd88f1d6e56 --- /dev/null +++ b/Source/Shaders/Builtin/Constants/passTerrainClassification.glsl @@ -0,0 +1,9 @@ +/** + * The automatic GLSL constant for {@link Pass#TERRAIN_CLASSIFICATION} + * + * @name czm_passTerrainClassification + * @glslConstant + * + * @see czm_pass + */ +const float czm_passTerrainClassification = 4.0; diff --git a/Source/Shaders/Builtin/Constants/passTranslucent.glsl b/Source/Shaders/Builtin/Constants/passTranslucent.glsl index eb2bb2d4b7a1..2f25f8c07a7d 100644 --- a/Source/Shaders/Builtin/Constants/passTranslucent.glsl +++ b/Source/Shaders/Builtin/Constants/passTranslucent.glsl @@ -6,4 +6,4 @@ * * @see czm_pass */ -const float czm_passTranslucent = 6.0; +const float czm_passTranslucent = 7.0; From 34c5435a1414f0af2b0e5b1c18c0b18324f2ee28 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 23 Aug 2017 15:07:13 -0400 Subject: [PATCH 3/9] Fix automatic uniform tests. --- .../Builtin/Constants/passOverlay.glsl | 2 +- Specs/Renderer/AutomaticUniformSpec.js | 20 ++++++++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/Source/Shaders/Builtin/Constants/passOverlay.glsl b/Source/Shaders/Builtin/Constants/passOverlay.glsl index f780993b6638..e04091b33848 100644 --- a/Source/Shaders/Builtin/Constants/passOverlay.glsl +++ b/Source/Shaders/Builtin/Constants/passOverlay.glsl @@ -6,4 +6,4 @@ * * @see czm_pass */ -const float czm_passOverlay = 7.0; +const float czm_passOverlay = 8.0; diff --git a/Specs/Renderer/AutomaticUniformSpec.js b/Specs/Renderer/AutomaticUniformSpec.js index 724ad7fa5d37..239897440a44 100644 --- a/Specs/Renderer/AutomaticUniformSpec.js +++ b/Specs/Renderer/AutomaticUniformSpec.js @@ -1080,13 +1080,27 @@ defineSuite([ }).contextToRender(); }); - it('has czm_pass and czm_passGround', function() { + it('has czm_pass and czm_passTerrainClassification', function() { var us = context.uniformState; - us.updatePass(Pass.GROUND); + us.updatePass(Pass.TERRAIN_CLASSIFICATION); var fs = 'void main() { ' + - ' gl_FragColor = vec4(czm_pass == czm_passGround);' + + ' gl_FragColor = vec4(czm_pass == czm_passTerrainClassification);' + + '}'; + expect({ + context : context, + fragmentShader : fs + }).contextToRender(); + }); + + it('has czm_pass and czm_passCesium3DTileClassification', function() { + var us = context.uniformState; + us.updatePass(Pass.CESIUM_3D_TILE_CLASSIFICATION); + + var fs = + 'void main() { ' + + ' gl_FragColor = vec4(czm_pass == czm_passCesium3DTileClassification);' + '}'; expect({ context : context, From 7dc93e772555cb43f3e6327c48358d61203fd6cd Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 23 Aug 2017 15:10:33 -0400 Subject: [PATCH 4/9] Update CHANGES.md. --- CHANGES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 34f80cc4f458..65bb22fd68a1 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,6 +12,8 @@ Change Log * Fixed a bug that caused imagery splitting to work incorrectly when CSS pixels were not equivalent to WebGL drawing buffer pixels, such as on high DPI displays in Microsoft Edge and Internet Explorer. * Added `Cesium3DTileset.loadJson` to support overriding the default tileset loading behavior. [#5685](https://github.com/AnalyticalGraphicsInc/cesium/pull/5685) * Fixed loading of binary glTFs containing CRN or KTX textures. [#5753](https://github.com/AnalyticalGraphicsInc/cesium/pull/5753) +* Fixed depth picking on 3D Tiles. [#5676](https://github.com/AnalyticalGraphicsInc/cesium/issues/5676) +* Added `classificationType` to `ClassificationPrimitive` and `GroundPrimitive` to choose whether terrain, 3D Tiles, or both are classified. [#5683](https://github.com/AnalyticalGraphicsInc/cesium/issues/5676) ### 1.36 - 2017-08-01 From 330c1fd210f164ab1a79042c9d7bcdc72a8adc57 Mon Sep 17 00:00:00 2001 From: Patrick Cozzi Date: Wed, 23 Aug 2017 19:40:02 -0400 Subject: [PATCH 5/9] Update CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 65bb22fd68a1..a282934066bd 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -13,6 +13,7 @@ Change Log * Added `Cesium3DTileset.loadJson` to support overriding the default tileset loading behavior. [#5685](https://github.com/AnalyticalGraphicsInc/cesium/pull/5685) * Fixed loading of binary glTFs containing CRN or KTX textures. [#5753](https://github.com/AnalyticalGraphicsInc/cesium/pull/5753) * Fixed depth picking on 3D Tiles. [#5676](https://github.com/AnalyticalGraphicsInc/cesium/issues/5676) +* Fixed glTF model translucency bug. [#5731](https://github.com/AnalyticalGraphicsInc/cesium/issues/5731) * Added `classificationType` to `ClassificationPrimitive` and `GroundPrimitive` to choose whether terrain, 3D Tiles, or both are classified. [#5683](https://github.com/AnalyticalGraphicsInc/cesium/issues/5676) ### 1.36 - 2017-08-01 From 2f8dbc74fd5bf869bb503140f7bbeeb1cc51abff Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 24 Aug 2017 14:45:50 -0400 Subject: [PATCH 6/9] Add Sandcastle example and rename from review. --- .../gallery/Classification Types.html | 94 ++++++++++++++++++ .../gallery/Classification Types.jpg | Bin 0 -> 20664 bytes Apps/Sandcastle/gallery/Classification.html | 12 +-- Source/Scene/ClassificationPrimitive.js | 2 +- Source/Scene/ClassificationType.js | 2 +- Source/Scene/GroundPrimitive.js | 2 +- 6 files changed, 102 insertions(+), 10 deletions(-) create mode 100644 Apps/Sandcastle/gallery/Classification Types.html create mode 100644 Apps/Sandcastle/gallery/Classification Types.jpg diff --git a/Apps/Sandcastle/gallery/Classification Types.html b/Apps/Sandcastle/gallery/Classification Types.html new file mode 100644 index 000000000000..2503a7c73889 --- /dev/null +++ b/Apps/Sandcastle/gallery/Classification Types.html @@ -0,0 +1,94 @@ + + + + + + + + + Cesium Demo + + + + + + +

+

Loading...

+
+ + + diff --git a/Apps/Sandcastle/gallery/Classification Types.jpg b/Apps/Sandcastle/gallery/Classification Types.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8f1ca451c167c6f2df0a96f055dfc3d4260ded3f GIT binary patch literal 20664 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 literal 0 HcmV?d00001 diff --git a/Apps/Sandcastle/gallery/Classification.html b/Apps/Sandcastle/gallery/Classification.html index 6f6b8ea21f2b..b5ec8301a0bc 100644 --- a/Apps/Sandcastle/gallery/Classification.html +++ b/Apps/Sandcastle/gallery/Classification.html @@ -31,8 +31,6 @@ var scene = viewer.scene; var camera = scene.camera; -scene.globe.depthTestAgainstTerrain = true; - var buildingHighlight; var treeHighlight1; var treeHighlight2; @@ -74,7 +72,7 @@ }, id : 'volume' }), - classificationType : Cesium.ClassificationType.CESIUM_3D_TILES + classificationType : Cesium.ClassificationType.CESIUM_3D_TILE })); camera.setView({ @@ -108,7 +106,7 @@ }, id : 'volume 1' }), - classificationType : Cesium.ClassificationType.CESIUM_3D_TILES + classificationType : Cesium.ClassificationType.CESIUM_3D_TILE })); center = new Cesium.Cartesian3(1216394.3346955755, -4736207.431365568, 4081336.7768881875); @@ -128,7 +126,7 @@ }, id : 'volume 2' }), - classificationType : Cesium.ClassificationType.CESIUM_3D_TILES + classificationType : Cesium.ClassificationType.CESIUM_3D_TILE })); center = new Cesium.Cartesian3(1216388.1664430483, -4736210.034324032, 4081332.9324705894); @@ -147,7 +145,7 @@ }, id : 'volume 3' }), - classificationType : Cesium.ClassificationType.CESIUM_3D_TILES + classificationType : Cesium.ClassificationType.CESIUM_3D_TILE })); center = new Cesium.Cartesian3(1216383.1478702603, -4736211.716097012, 4081329.551077661); @@ -166,7 +164,7 @@ }, id : 'volume 4' }), - classificationType : Cesium.ClassificationType.CESIUM_3D_TILES + classificationType : Cesium.ClassificationType.CESIUM_3D_TILE })); camera.setView({ diff --git a/Source/Scene/ClassificationPrimitive.js b/Source/Scene/ClassificationPrimitive.js index 9692354246e6..49da56ec4403 100644 --- a/Source/Scene/ClassificationPrimitive.js +++ b/Source/Scene/ClassificationPrimitive.js @@ -730,7 +730,7 @@ define([ if (classificationType === ClassificationType.TERRAIN) { startIndex = 0; endIndex = length / 2; - } else if (classificationType === ClassificationType.CESIUM_3D_TILES) { + } else if (classificationType === ClassificationType.CESIUM_3D_TILE) { startIndex = length / 2; endIndex = length; } else { diff --git a/Source/Scene/ClassificationType.js b/Source/Scene/ClassificationType.js index e3dd18f97091..b8b9e7eced1b 100644 --- a/Source/Scene/ClassificationType.js +++ b/Source/Scene/ClassificationType.js @@ -23,7 +23,7 @@ define([ * @type {Number} * @constant */ - CESIUM_3D_TILES : 1, + CESIUM_3D_TILE : 1, /** * Both terrain and 3D Tiles will be classified. * diff --git a/Source/Scene/GroundPrimitive.js b/Source/Scene/GroundPrimitive.js index 6c0d334ce0cd..c024c6212fb3 100644 --- a/Source/Scene/GroundPrimitive.js +++ b/Source/Scene/GroundPrimitive.js @@ -580,7 +580,7 @@ define([ if (classificationType === ClassificationType.TERRAIN) { startIndex = 0; endIndex = length / 2; - } else if (classificationType === ClassificationType.CESIUM_3D_TILES) { + } else if (classificationType === ClassificationType.CESIUM_3D_TILE) { startIndex = length / 2; endIndex = length; } else { From e7d046c23a491fccf2df624f5262d42d31e1386c Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 28 Aug 2017 16:15:22 -0400 Subject: [PATCH 7/9] Fix classification + depth plane artifact. --- Source/Scene/DepthPlane.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Source/Scene/DepthPlane.js b/Source/Scene/DepthPlane.js index 8559baa6219a..e6c00c868577 100644 --- a/Source/Scene/DepthPlane.js +++ b/Source/Scene/DepthPlane.js @@ -50,15 +50,23 @@ define([ } var depthQuadScratch = FeatureDetection.supportsTypedArrays() ? new Float32Array(12) : []; + var scratchRadii = new Cartesian3(); var scratchCartesian1 = new Cartesian3(); var scratchCartesian2 = new Cartesian3(); var scratchCartesian3 = new Cartesian3(); var scratchCartesian4 = new Cartesian3(); function computeDepthQuad(ellipsoid, frameState) { - var radii = ellipsoid.radii; + var radii = Cartesian3.clone(ellipsoid.radii, scratchRadii); var p = frameState.camera.positionWC; + // Where did this magical number come from? It's how far a GroundPrimitive will be extruded below the surface + // of the Earth. This effectively pushes the depth plane farther from the camera so that classifications on + // 3D Tiles do not intersect the depth plane. This can be removed when depth testing is enabled by default. + radii.x -= 11000.0; + radii.y -= 11000.0; + radii.z -= 11000.0; + // Find the corresponding position in the scaled space of the ellipsoid. var q = Cartesian3.multiplyComponents(ellipsoid.oneOverRadii, p, scratchCartesian1); From d7426a873d672184ca8859bdcc900f42906758eb Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 28 Aug 2017 16:35:27 -0400 Subject: [PATCH 8/9] Update Sandcastle example from review. --- .../gallery/Classification Types.html | 34 +++++++++--------- .../gallery/Classification Types.jpg | Bin 20664 -> 20646 bytes 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Apps/Sandcastle/gallery/Classification Types.html b/Apps/Sandcastle/gallery/Classification Types.html index 2503a7c73889..f3bb082345a7 100644 --- a/Apps/Sandcastle/gallery/Classification Types.html +++ b/Apps/Sandcastle/gallery/Classification Types.html @@ -33,31 +33,31 @@ url : 'https://beta.cesium.com/api/assets/1458?access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIxYmJiNTAxOC1lOTg5LTQzN2EtODg1OC0zMWJjM2IxNGNlYmMiLCJpZCI6NDQsImFzc2V0cyI6WzE0NThdLCJpYXQiOjE0OTkyNjM4MjB9.1WKijRa-ILkmG6utrhDWX6rDgasjD7dZv-G5ZyCmkKg' })); -var rectanglePrimitive; - tileset.readyPromise.then(function() { var boundingSphere = tileset.boundingSphere; viewer.camera.viewBoundingSphere(boundingSphere, new Cesium.HeadingPitchRange(0.0, -0.5, boundingSphere.radius + 500.0)); viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - - var center = Cesium.Ellipsoid.WGS84.cartesianToCartographic(boundingSphere.center); - var offset = 0.0001; - var rectangle = new Cesium.Rectangle(center.longitude - offset, center.latitude - offset, center.longitude + offset, center.latitude + offset); - rectanglePrimitive = viewer.scene.primitives.add(new Cesium.GroundPrimitive({ - geometryInstances : new Cesium.GeometryInstance({ - geometry : new Cesium.RectangleGeometry({ - rectangle : rectangle - }), - attributes: { - color: Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 0.0, 0.0, 0.5)) - } - }), - classificationType : Cesium.ClassificationType.BOTH - })); }).otherwise(function(error) { throw(error); }); +var cartographics = [new Cesium.Cartographic(-1.3194369277314022, 0.6988062530900625), + new Cesium.Cartographic(-1.3193955980204217, 0.6988091578771254), + new Cesium.Cartographic(-1.3193931220959367, 0.698743632490865), + new Cesium.Cartographic(-1.3194358224045408, 0.6987471965556998)]; +var rectangle = Cesium.Rectangle.fromCartographicArray(cartographics); +var rectanglePrimitive = viewer.scene.primitives.add(new Cesium.GroundPrimitive({ + geometryInstances : new Cesium.GeometryInstance({ + geometry : new Cesium.RectangleGeometry({ + rectangle : rectangle + }), + attributes: { + color: Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 0.0, 0.0, 0.5)) + } + }), + classificationType : Cesium.ClassificationType.BOTH +})); + var options = [{ text : 'Classify Both', onselect : function() { diff --git a/Apps/Sandcastle/gallery/Classification Types.jpg b/Apps/Sandcastle/gallery/Classification Types.jpg index 8f1ca451c167c6f2df0a96f055dfc3d4260ded3f..22221ac484cacc8f36b05e2cea963ff372b3cba1 100644 GIT binary patch delta 19738 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%0A1pH*u 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%0A|i#$DHrxf--UJm04Y#_7je3sqf>?- zyxa2eh8e562a2>aqCJGaw}-|ivGM}PH~b+UA@Y@c!dVtyIL!DVakYW@wu~tvuh`K` zT5A5Z{{Z1X^5$A+?cJd{{ZRJclqpKSpLf24m=~``yaG_d<^}%V6^htrMCY7 zgl5anp9h1^Ffc$o4DpK6vi+BS5#0ERp|SW^`(Nr1Mv>fV2^NKHw;Ew#xvl1BRE;pW zIm2X?!{e@F`_3p+sUh zBQfCZAa3%B2m9I0V(8M2zR7*`-{m7{WAQa~_VqgboJ!d)@mIe~YWi+=Fn-BD1Ai>8 zE&ShwKegm`x}=UBr||8hGHDDjHoMIbMm-2sX-_}_CkHnB_BZ%*bsJmQd?fv^ZLXd+ zdpWPXEnqG0TXqo%SPL%f5H~DfbtbCbd`a*osBJD=_OkfXeR@$No=ZIoS++=s8&%hU zuF9&p`FAnrc_3!jitc&DIED*piB7>2(Herxd-AK7c+kBbuL>^}j2Y}+gANI!oChlVuE zt7v3J!xCK!s4NM=IqWKwzp}5w-7mw!fA~`W0JfcuqjMJ6E-tiPE*nogeShY1$O1+= z>^L1p4OzDFFNC~7uIlsKe%&7w^in*_fi#*1xoDb+Bxm5CCC+iyPfg@R4_!q=hFsmT>cE=pbfw@001G&aYCAu(_b*CS`pZ@?PX-^%9 zjMDbi7yY@4Z}0YddAEPkynkP^hr^L=6tnyv{kA8a3HX_h~?kAKCh-9K==k5E1m z@gxmw%a!}Z-gySm{;zsOGo0iQMTeuye`db=fBca(arnn8EJW_Vxrw*lp>MhC_!IbF z_BHrBsQ8NdeOuvQ?W3USPz9C16?s(peQYOI33Z(4^Jw^^MT>iyB3NGQf7GDB? zZfNdjXPz>2oixR70)G-ei#YemOb&MFNqgX>TpFpNuNgf=#ut1GY|c+ndIo8Mv~C?Kr;hhNg`(p+6*-237k* zU{9WO#Qo-&oe{OGyY;9zDjBVh565dNA9D;&za2*ksIaQGW$Y29} z!74PG(wf)KpZ@?PbUecrq~h@t(%VB4{{Z(FU+MKN{C)kIJ_LL+_#fC7~pNdqU5pO*gsXt=%K``X80^Sgt3^4oXy(uja5%x?r~PPo6}y$%Uk`w@!Bg-%+WvR zv>*5P{{XV0ypO74Kj+lH@D_bn_V!o*06{eW0Pr~f0GNNmv%j}(4(ieE7EL!uZ7Wd? zBLO1|iDik?vfM1cy8mv9)A|ot$Z78q-#1wtdZ-tiKxkVJViTC z3#6=FRKz@}&F{{SrW)C%)Y8|%7%j=m%KTUnOc z=6~Bn@YU*EUs@TB%*z7Yyy6($&Sm)-6LXb3AH<@t`u-wVsJTn+c3;bG$Iq?~$>WTT zMMvIO*P36*{{XytC&HiGN5>xp{tH@oKS)mx$8~9UE$7;FXc{9vHua_7sS-1l`N6jAtrd!Zw zxcCk6+r=NVwbrRFi24oZ_QXjI%Ii8jTAGAM+`AS+0-dFa$5vDwIiiZk`%e}8|9=3H zullo=HD^olf97`4{{X>2ekWqn{U^cjC57MHQaF4uZm5%O3eFceJbAbWjuVbs6Gi_3 z1rGS97PK`fwGRv%sH~*5wnXsdzmOV37n)f*6S6rrw_JqJQb9#O?Mzqm{zQMO*;oAe zUwi)mGFblr;G{nnW12to&jkmDDSse{4+~phtMBXhvUKPP{_560i9c%Jh(8%TEpy?$ zLsilZo~bIvkj0}#ZmGH5w+2&`JKiF258s#jtCEUOG{t{EAoL6m!eG8lYdF#9RewD z6kIYhY?LI7{{S(UmMgR@U;~qail}CIrnR5sYd#ms+Owp-_x@!m{{U}qiyjyFlc?$Q z-uOB7iz&v1a_Ql?9s}e`(cuenP)H@gDhW`8jFtmiTm7?sE&M3g?yOf(@MXp2+>3j3 z()e}>)6W5xHI0}8v53R~jDL0C*8?RKraJDEe`3D({$_5i`+WRa*Q{=B z-t)nR8>@pk2g6qCOBG-SM@1mVk?#J3K6mlY<428uXsK*2JV~n9%=&qhK_#t;Ryhe0Ywqbad!Cs z03rVXs~KFkq`vq5W;1@>Uly0cEu=-L_)-gL7D1S_7*<4ga_&}479TknK7{ewu3CQI zUl9B}W`o0;hJ*czEq}hnU^Ood+R1X(sy4#Y5J>aPYi=EZIX+?Mg2feI+PJ^x{DuCj zWmoiX6)T+gE$B1Od_?_~ ze1Gvr#&^2*v#sb6>N=50CpJ<%P~<8pD;R_U@~a-aoO+xTR)0@6#opZi0Fm2<;VhxX z{>6Rr{{SNV!bbVFz9WLurw2SR2=30$P*hKk?OvNZgX4)sfJb$a_lee>% z_S^WatLWEOXnr4B!F>wb&lR_Zp@n2c$pb1g_xtt7;PY{k0B&nR_?4*m z+u{mMdEyOz*HpUk4BC~;Y4O|J+uHr6(JfYcbt>CuX2@`UK^$@I=QL4U(9JPT-Ouv! z@;EVkEtNQO`!2oZ=jLbs0K>dIfByhKz7GEY!26&6MjN7vE4%wk6a3$T{{SPC{Zh(* M=hyyCFY`bD* Date: Mon, 28 Aug 2017 16:58:12 -0400 Subject: [PATCH 9/9] Update when depth plane is rendered. --- Source/Scene/DepthPlane.js | 10 +--------- Source/Scene/Scene.js | 7 ++++--- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/Source/Scene/DepthPlane.js b/Source/Scene/DepthPlane.js index e6c00c868577..8559baa6219a 100644 --- a/Source/Scene/DepthPlane.js +++ b/Source/Scene/DepthPlane.js @@ -50,23 +50,15 @@ define([ } var depthQuadScratch = FeatureDetection.supportsTypedArrays() ? new Float32Array(12) : []; - var scratchRadii = new Cartesian3(); var scratchCartesian1 = new Cartesian3(); var scratchCartesian2 = new Cartesian3(); var scratchCartesian3 = new Cartesian3(); var scratchCartesian4 = new Cartesian3(); function computeDepthQuad(ellipsoid, frameState) { - var radii = Cartesian3.clone(ellipsoid.radii, scratchRadii); + var radii = ellipsoid.radii; var p = frameState.camera.positionWC; - // Where did this magical number come from? It's how far a GroundPrimitive will be extruded below the surface - // of the Earth. This effectively pushes the depth plane farther from the camera so that classifications on - // 3D Tiles do not intersect the depth plane. This can be removed when depth testing is enabled by default. - radii.x -= 11000.0; - radii.y -= 11000.0; - radii.z -= 11000.0; - // Find the corresponding position in the scaled space of the ellipsoid. var q = Cartesian3.multiplyComponents(ellipsoid.oneOverRadii, p, scratchCartesian1); diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 2eaacf1baea6..2e649fa00944 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -1945,9 +1945,6 @@ define([ if (clearGlobeDepth) { clearDepth.execute(context, passState); - if (useDepthPlane) { - depthPlane.execute(context, passState); - } } us.updatePass(Pass.CESIUM_3D_TILE); @@ -1968,6 +1965,10 @@ define([ executeCommand(commands[j], scene, context, passState); } + if (clearGlobeDepth && useDepthPlane) { + depthPlane.execute(context, passState); + } + // Execute commands in order by pass up to the translucent pass. // Translucent geometry needs special handling (sorting/OIT). var startPass = Pass.CESIUM_3D_TILE_CLASSIFICATION + 1;