From bea163cfc8761800fef9d58ebdfd7ace1d5192b3 Mon Sep 17 00:00:00 2001 From: Patrick Cozzi Date: Fri, 19 Jul 2013 15:51:10 -0400 Subject: [PATCH 1/9] Start of frustum debug --- Source/Scene/Scene.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 38338c2ebe97..ab726d93cd6d 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -75,6 +75,20 @@ define([ CreditDisplay) { "use strict"; + function createFrustumDebugFragmentShaderSource(fragmentShaderSource, color) { + var renamedFS = fragmentShaderSource.replace(/void\s+main\s*\(\s*(?:void)?\s*\)/g, 'void czm_old_main()'); + var pickMain = + 'void main() \n' + + '{ \n' + + ' czm_old_main(); \n' + + ' gl_FragColor.rgb *= vec3(1.0, 0.0, 0.0); \n' + + '}'; + + return renamedFS + '\n' + pickMain; + } + + /////////////////////////////////////////////////////////////////////////// + /** * The container for all 3D graphical objects and state in a Cesium virtual scene. Generally, * a scene is not created directly; instead, it is implicitly created by {@link CesiumWidget}. @@ -244,6 +258,11 @@ define([ */ this.debugCommandFilter = undefined; + /** + * DOC_TBA + */ + this.debugShowFrustums = false; + this._debugSphere = undefined; // initial guess at frustums. @@ -488,6 +507,10 @@ define([ return; } + if (debugShowFrustums) { + command.shaderProgram + } + command.execute(context, passState); if (command.debugShowBoundingVolume && (typeof command.boundingVolume !== 'undefined')) { From 246ef03b0597b08432acf9df8414f156a1be91cc Mon Sep 17 00:00:00 2001 From: Patrick Cozzi Date: Sat, 20 Jul 2013 12:40:57 -0400 Subject: [PATCH 2/9] Initial frustum debug --- Source/Renderer/DrawCommand.js | 5 +++ Source/Renderer/ShaderProgram.js | 28 ++++++++++++++ Source/Scene/Scene.js | 65 ++++++++++++++++++++++---------- 3 files changed, 79 insertions(+), 19 deletions(-) diff --git a/Source/Renderer/DrawCommand.js b/Source/Renderer/DrawCommand.js index 8807f54dbbfb..021ba564c7db 100644 --- a/Source/Renderer/DrawCommand.js +++ b/Source/Renderer/DrawCommand.js @@ -163,6 +163,11 @@ define(function() { * @see DrawCommand#boundingVolume */ this.debugShowBoundingVolume = false; + + /** + * @private + */ + this.debugOverlappingFrustums = 0; }; /** diff --git a/Source/Renderer/ShaderProgram.js b/Source/Renderer/ShaderProgram.js index 0d7e401e0769..f1bca60db510 100644 --- a/Source/Renderer/ShaderProgram.js +++ b/Source/Renderer/ShaderProgram.js @@ -2210,6 +2210,24 @@ define([ this._samplerUniforms = uniforms.samplerUniforms; this._automaticUniforms = partitionedUniforms.automaticUniforms; this._manualUniforms = partitionedUniforms.manualUniforms; + + /** + * DOC_TBA + * @readonly + */ + this.vertexShaderSource = vertexShaderSource; + + /** + * DOC_TBA + * @readonly + */ + this.fragmentShaderSource = fragmentShaderSource; + + /** + * DOC_TBA + * @readonly + */ + this.attributeLocations = findVertexAttributeLocations(gl, program, numberOfVertexAttributes); }; function extractShaderVersion(source) { @@ -2636,6 +2654,16 @@ define([ return attributes; } + function findVertexAttributeLocations(gl, program, numberOfAttributes) { + var attributeLocations = {}; + for ( var i = 0; i < numberOfAttributes; ++i) { + var attr = gl.getActiveAttrib(program, i); + attributeLocations[attr.name] = gl.getAttribLocation(program, attr.name); + } + + return attributeLocations; + } + function findUniforms(gl, program) { var allUniforms = {}; var uniforms = []; diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index ab726d93cd6d..dc113086b657 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -4,6 +4,7 @@ define([ '../Core/Color', '../Core/defaultValue', '../Core/destroyObject', + '../Core/defined', '../Core/GeographicProjection', '../Core/Ellipsoid', '../Core/Occluder', @@ -41,6 +42,7 @@ define([ Color, defaultValue, destroyObject, + defined, GeographicProjection, Ellipsoid, Occluder, @@ -75,20 +77,6 @@ define([ CreditDisplay) { "use strict"; - function createFrustumDebugFragmentShaderSource(fragmentShaderSource, color) { - var renamedFS = fragmentShaderSource.replace(/void\s+main\s*\(\s*(?:void)?\s*\)/g, 'void czm_old_main()'); - var pickMain = - 'void main() \n' + - '{ \n' + - ' czm_old_main(); \n' + - ' gl_FragColor.rgb *= vec3(1.0, 0.0, 0.0); \n' + - '}'; - - return renamedFS + '\n' + pickMain; - } - - /////////////////////////////////////////////////////////////////////////// - /** * The container for all 3D graphical objects and state in a Cesium virtual scene. Generally, * a scene is not created directly; instead, it is implicitly created by {@link CesiumWidget}. @@ -261,7 +249,8 @@ define([ /** * DOC_TBA */ - this.debugShowFrustums = false; + this.debugShowFrustums = true; +// this.debugShowFrustums = false; this._debugSphere = undefined; @@ -390,6 +379,10 @@ define([ } function insertIntoBin(scene, command, distance) { + if (scene.debugShowFrustums) { + command.debugOverlappingFrustums = 0; + } + var frustumCommandsList = scene._frustumCommandsList; var length = frustumCommandsList.length; for (var i = 0; i < length; ++i) { @@ -410,6 +403,10 @@ define([ // PERFORMANCE_IDEA: sort bins frustumCommands.commands[frustumCommands.index++] = command; + if (scene.debugShowFrustums) { + command.debugOverlappingFrustums |= (1 << i); + } + if (command.executeInClosestFrustum) { break; } @@ -502,16 +499,46 @@ define([ } } + function createFrustumDebugFragmentShaderSource(command) { + var fragmentShaderSource = command.shaderProgram.fragmentShaderSource; + var renamedFS = fragmentShaderSource.replace(/void\s+main\s*\(\s*(?:void)?\s*\)/g, 'void czm_frustumDebug_main()'); + + // Support up to three frustums. If a command overlaps all + // three, it's code is not changed. + var r = (command.debugOverlappingFrustums & (1 << 0)) ? '1.0' : '0.0'; + var g = (command.debugOverlappingFrustums & (1 << 1)) ? '1.0' : '0.0'; + var b = (command.debugOverlappingFrustums & (1 << 2)) ? '1.0' : '0.0'; + + var pickMain = + 'void main() \n' + + '{ \n' + + ' czm_frustumDebug_main(); \n' + + ' gl_FragColor.rgb *= vec3(' + r + ', ' + g + ', ' + b + '); \n' + + '}'; + + return renamedFS + '\n' + pickMain; + } + function executeCommand(command, scene, context, passState) { if ((typeof scene.debugCommandFilter !== 'undefined') && !scene.debugCommandFilter(command)) { return; } - if (debugShowFrustums) { - command.shaderProgram - } + if (!scene.debugShowFrustums) { + command.execute(context, passState); + } else { + if (defined(command.shaderProgram)) { + // Replace shader for frustum visualization + var sp = command.shaderProgram; + command.shaderProgram = context.getShaderCache().getShaderProgram( + sp.vertexShaderSource, createFrustumDebugFragmentShaderSource(command), sp.attributeLocations); - command.execute(context, passState); + command.execute(context, passState); + + command.shaderProgram.release(); + command.shaderProgram = sp; + } + } if (command.debugShowBoundingVolume && (typeof command.boundingVolume !== 'undefined')) { // Debug code to draw bounding volume for command. Not optimized! From 1872f3e2b57ffc62112c9c96766b78453e2afd8b Mon Sep 17 00:00:00 2001 From: Patrick Cozzi Date: Sun, 21 Jul 2013 14:19:23 -0700 Subject: [PATCH 3/9] Added debug for number of frustums a command is executed in --- Source/Scene/Scene.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index dc113086b657..59fc27859241 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -252,6 +252,17 @@ define([ this.debugShowFrustums = true; // this.debugShowFrustums = false; + /** + * DOC_TBA + */ + this.debugComputeFrustumsPerCommand = true; +// this.debugShowFrustumsPerCommand = false; + + this._debugFrustumsPerCommand = { + totalCommands : 0, + commandsInFrustums : [0, 0, 0, 0] + }; + this._debugSphere = undefined; // initial guess at frustums. @@ -385,6 +396,8 @@ define([ var frustumCommandsList = scene._frustumCommandsList; var length = frustumCommandsList.length; + var frustumCount = 0; + for (var i = 0; i < length; ++i) { var frustumCommands = frustumCommandsList[i]; var curNear = frustumCommands.near; @@ -407,10 +420,17 @@ define([ command.debugOverlappingFrustums |= (1 << i); } + ++frustumCount; + if (command.executeInClosestFrustum) { break; } } + + if (scene.debugComputeFrustumsPerCommand) { + ++scene._debugFrustumsPerCommand.totalCommands; + ++scene._debugFrustumsPerCommand.commandsInFrustums[frustumCount]; + } } var scratchCullingVolume = new CullingVolume(); @@ -424,6 +444,11 @@ define([ var direction = camera.getDirectionWC(); var position = camera.getPositionWC(); + if (scene.debugComputeFrustumsPerCommand) { + scene._debugFrustumsPerCommand.totalCommands = 0; + scene._debugFrustumsPerCommand.commandsInFrustums = [0, 0, 0, 0]; + } + var frustumCommandsList = scene._frustumCommandsList; var frustumsLength = frustumCommandsList.length; for (var n = 0; n < frustumsLength; ++n) { From d187d1fb0e5d4c4ebfe32c7488c953ab47a92d15 Mon Sep 17 00:00:00 2001 From: Patrick Cozzi Date: Thu, 15 Aug 2013 14:30:24 -0400 Subject: [PATCH 4/9] Fix bad merge --- Source/Scene/Scene.js | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index b35e160ace69..9a48485932af 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -5,7 +5,6 @@ define([ '../Core/defaultValue', '../Core/defined', '../Core/destroyObject', - '../Core/defined', '../Core/GeographicProjection', '../Core/Ellipsoid', '../Core/Occluder', @@ -44,7 +43,6 @@ define([ defaultValue, defined, destroyObject, - defined, GeographicProjection, Ellipsoid, Occluder, @@ -404,9 +402,9 @@ define([ command.debugOverlappingFrustums = 0; } + var frustumCount = 0; var frustumCommandsList = scene._frustumCommandsList; var length = frustumCommandsList.length; - var frustumCount = 0; for (var i = 0; i < length; ++i) { var frustumCommands = frustumCommandsList[i]; @@ -424,12 +422,24 @@ define([ // PERFORMANCE_IDEA: sort bins frustumCommands.commands[frustumCommands.index++] = command; + if (scene.debugShowFrustums) { + command.debugOverlappingFrustums |= (1 << i); + } + + ++frustumCount; + if (command.executeInClosestFrustum) { break; } } + + if (scene.debugComputeFrustumsPerCommand) { + ++scene._debugFrustumsPerCommand.totalCommands; + ++scene._debugFrustumsPerCommand.commandsInFrustums[frustumCount]; + } } +// TODO: remove this function? function insertIntoAllBins(scene, command) { var frustumCommandsList = scene._frustumCommandsList; var length = frustumCommandsList.length; @@ -439,21 +449,10 @@ define([ // PERFORMANCE_IDEA: sort bins frustumCommands.commands[frustumCommands.index++] = command; - if (scene.debugShowFrustums) { - command.debugOverlappingFrustums |= (1 << i); - } - - ++frustumCount; - if (command.executeInClosestFrustum) { break; } } - - if (scene.debugComputeFrustumsPerCommand) { - ++scene._debugFrustumsPerCommand.totalCommands; - ++scene._debugFrustumsPerCommand.commandsInFrustums[frustumCount]; - } } var scratchCullingVolume = new CullingVolume(); From c62c6941bd7579840090f1317ee02580a0297c61 Mon Sep 17 00:00:00 2001 From: Patrick Cozzi Date: Fri, 23 Aug 2013 11:45:29 -0400 Subject: [PATCH 5/9] Shader improvements for debug frustum --- CHANGES.md | 1 + Source/Renderer/DrawCommand.js | 2 ++ Source/Renderer/ShaderProgram.js | 30 ++++++++++++----------------- Source/Scene/Scene.js | 8 ++++++++ Specs/Renderer/ShaderProgramSpec.js | 9 +++++++++ 5 files changed, 32 insertions(+), 18 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 88d8da30caec..a985db9b8135 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -43,6 +43,7 @@ var geometry = BoxGeometry.createGeometry(box); * Added the ability to specify a `minimumTerrainLevel` and `maximumTerrainLevel` when constructing an `ImageryLayer`. The layer will only be shown for terrain tiles within the specified range. * Added `Math.setRandomNumberSeed` and `Math.nextRandomNumber` for generating repeatable random numbers. * Added `Color.fromRandom` to generate random and partially random colors. +* Added `Scene.debugShowFrustums` and `Scene.debugComputeFrustumsPerCommand` for rendering debugging. * Improved geometry batching performance by moving work to a web worker. * Improved `WallGeometry` to follow the curvature of the earth. * Fixed broken surface rendering in Columbus View when using the `EllipsoidTerrainProvider`. diff --git a/Source/Renderer/DrawCommand.js b/Source/Renderer/DrawCommand.js index 021ba564c7db..ea4a2089439b 100644 --- a/Source/Renderer/DrawCommand.js +++ b/Source/Renderer/DrawCommand.js @@ -166,6 +166,8 @@ define(function() { /** * @private + * + * Used for counting the number of frustums a command overlaps. */ this.debugOverlappingFrustums = 0; }; diff --git a/Source/Renderer/ShaderProgram.js b/Source/Renderer/ShaderProgram.js index 12e5d03c942e..cbf774d9474b 100644 --- a/Source/Renderer/ShaderProgram.js +++ b/Source/Renderer/ShaderProgram.js @@ -2282,22 +2282,26 @@ define([ this._manualUniforms = partitionedUniforms.manualUniforms; /** - * DOC_TBA + * GLSL source for the shader program's vertex shader. This is the version of + * the source provided when the shader program was created, not the final + * source provided to WebGL, which includes Cesium bulit-ins. + * + * @type {String} + * * @readonly */ this.vertexShaderSource = vertexShaderSource; /** - * DOC_TBA + * GLSL source for the shader program's fragment shader. This is the version of + * the source provided when the shader program was created, not the final + * source provided to WebGL, which includes Cesium bulit-ins. + * + * @type {String} + * * @readonly */ this.fragmentShaderSource = fragmentShaderSource; - - /** - * DOC_TBA - * @readonly - */ - this.attributeLocations = findVertexAttributeLocations(gl, program, numberOfVertexAttributes); }; function extractShaderVersion(source) { @@ -2520,16 +2524,6 @@ define([ return attributes; } - function findVertexAttributeLocations(gl, program, numberOfAttributes) { - var attributeLocations = {}; - for ( var i = 0; i < numberOfAttributes; ++i) { - var attr = gl.getActiveAttrib(program, i); - attributeLocations[attr.name] = gl.getAttribLocation(program, attr.name); - } - - return attributeLocations; - } - function findUniforms(gl, program) { var allUniforms = {}; var uniforms = []; diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 57d31f717cb1..753d07f3b049 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -573,6 +573,14 @@ define([ if (defined(command.shaderProgram)) { // Replace shader for frustum visualization var sp = command.shaderProgram; + var attributeLocations = {}; + var attributes = sp.getVertexAttributes(); + for (var a in attributes) { + if (attributes.hasOwnProperty(a)) { + attributeLocations[a] = attributes[a].index; + } + } + command.shaderProgram = context.getShaderCache().getShaderProgram( sp.vertexShaderSource, createFrustumDebugFragmentShaderSource(command), sp.attributeLocations); diff --git a/Specs/Renderer/ShaderProgramSpec.js b/Specs/Renderer/ShaderProgramSpec.js index 13ecb779436c..e88040e06ce3 100644 --- a/Specs/Renderer/ShaderProgramSpec.js +++ b/Specs/Renderer/ShaderProgramSpec.js @@ -40,6 +40,15 @@ defineSuite([ destroyContext(context); }); + it('has vertex and fragment shader source', function() { + var vs = 'void main() { gl_Position = vec4(1.0); }'; + var fs = 'void main() { gl_FragColor = vec4(1.0); }'; + sp = context.createShaderProgram(vs, fs); + + expect(sp.vertexShaderSource).toEqual(vs); + expect(sp.fragmentShaderSource).toEqual(fs); + }); + it('has a position vertex attribute', function() { var vs = 'attribute vec4 position; void main() { gl_Position = position; }'; var fs = 'void main() { gl_FragColor = vec4(1.0); }'; From a28765992a471d9060c5bdd6113dfb8cf164db1e Mon Sep 17 00:00:00 2001 From: Patrick Cozzi Date: Fri, 23 Aug 2013 13:42:34 -0400 Subject: [PATCH 6/9] debugShowFrustum test --- Source/Renderer/DrawCommand.js | 2 +- Source/Scene/Scene.js | 82 +++++++++++++-------------------- Specs/Scene/MultifrustumSpec.js | 24 +++++++--- 3 files changed, 51 insertions(+), 57 deletions(-) diff --git a/Source/Renderer/DrawCommand.js b/Source/Renderer/DrawCommand.js index ea4a2089439b..2bb96b57e5a9 100644 --- a/Source/Renderer/DrawCommand.js +++ b/Source/Renderer/DrawCommand.js @@ -167,7 +167,7 @@ define(function() { /** * @private * - * Used for counting the number of frustums a command overlaps. + * Used for to implement {@see Scene.debugShowFrustums}. */ this.debugOverlappingFrustums = 0; }; diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 753d07f3b049..6363a7910e66 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -245,14 +245,8 @@ define([ /** * DOC_TBA */ - this.debugShowFrustums = true; -// this.debugShowFrustums = false; - - /** - * DOC_TBA - */ - this.debugComputeFrustumsPerCommand = true; -// this.debugShowFrustumsPerCommand = false; +// this.debugShowFrustums = true; + this.debugShowFrustums = false; this._debugFrustumsPerCommand = { totalCommands : 0, @@ -420,37 +414,20 @@ define([ if (scene.debugShowFrustums) { command.debugOverlappingFrustums |= (1 << i); + ++frustumCount; } - ++frustumCount; - if (command.executeInClosestFrustum) { break; } } - if (scene.debugComputeFrustumsPerCommand) { + if (scene.debugShowFrustums) { ++scene._debugFrustumsPerCommand.totalCommands; ++scene._debugFrustumsPerCommand.commandsInFrustums[frustumCount]; } } -// TODO: remove this function? - function insertIntoAllBins(scene, command) { - var frustumCommandsList = scene._frustumCommandsList; - var length = frustumCommandsList.length; - for (var i = 0; i < length; ++i) { - var frustumCommands = frustumCommandsList[i]; - - // PERFORMANCE_IDEA: sort bins - frustumCommands.commands[frustumCommands.index++] = command; - - if (command.executeInClosestFrustum) { - break; - } - } - } - var scratchCullingVolume = new CullingVolume(); var distances = new Interval(); @@ -462,7 +439,7 @@ define([ var direction = camera.getDirectionWC(); var position = camera.getPositionWC(); - if (scene.debugComputeFrustumsPerCommand) { + if (scene.debugShowFrustums) { scene._debugFrustumsPerCommand.totalCommands = 0; scene._debugFrustumsPerCommand.commandsInFrustums = [0, 0, 0, 0]; } @@ -508,15 +485,16 @@ define([ distances = transformedBV.getPlaneDistances(position, direction, distances); near = Math.min(near, distances.start); far = Math.max(far, distances.stop); - - insertIntoBin(scene, command, distances); } else { // Clear commands don't need a bounding volume - just add the clear to all frustums. // If another command has no bounding volume, though, we need to use the camera's // worst-case near and far planes to avoid clipping something important. + distances.start = camera.frustum.near; + distances.stop = camera.frustum.far; undefBV = !(command instanceof ClearCommand); - insertIntoAllBins(scene, command); } + + insertIntoBin(scene, command, distances); } } @@ -562,6 +540,28 @@ define([ return renamedFS + '\n' + pickMain; } + function executeFrustumDebugCommand(command, context, passState) { + if (defined(command.shaderProgram)) { + // Replace shader for frustum visualization + var sp = command.shaderProgram; + var attributeLocations = {}; + var attributes = sp.getVertexAttributes(); + for (var a in attributes) { + if (attributes.hasOwnProperty(a)) { + attributeLocations[a] = attributes[a].index; + } + } + + command.shaderProgram = context.getShaderCache().getShaderProgram( + sp.vertexShaderSource, createFrustumDebugFragmentShaderSource(command), attributeLocations); + + command.execute(context, passState); + + command.shaderProgram.release(); + command.shaderProgram = sp; + } + } + function executeCommand(command, scene, context, passState) { if ((defined(scene.debugCommandFilter)) && !scene.debugCommandFilter(command)) { return; @@ -570,25 +570,7 @@ define([ if (!scene.debugShowFrustums) { command.execute(context, passState); } else { - if (defined(command.shaderProgram)) { - // Replace shader for frustum visualization - var sp = command.shaderProgram; - var attributeLocations = {}; - var attributes = sp.getVertexAttributes(); - for (var a in attributes) { - if (attributes.hasOwnProperty(a)) { - attributeLocations[a] = attributes[a].index; - } - } - - command.shaderProgram = context.getShaderCache().getShaderProgram( - sp.vertexShaderSource, createFrustumDebugFragmentShaderSource(command), sp.attributeLocations); - - command.execute(context, passState); - - command.shaderProgram.release(); - command.shaderProgram = sp; - } + executeFrustumDebugCommand(command, context, passState); } if (command.debugShowBoundingVolume && (defined(command.boundingVolume))) { diff --git a/Specs/Scene/MultifrustumSpec.js b/Specs/Scene/MultifrustumSpec.js index ecdd69d77c2c..6a62fc3c220b 100644 --- a/Specs/Scene/MultifrustumSpec.js +++ b/Specs/Scene/MultifrustumSpec.js @@ -182,6 +182,18 @@ defineSuite([ expect(context.readPixels()).toEqual([255, 255, 255, 255]); }); + it('renders primitive in last frustum with debugShowFrustums', function() { + createBillboards(); + var color = new Color(1.0, 1.0, 1.0, 0.0); + billboard0.setColor(color); + billboard1.setColor(color); + + scene.debugShowFrustums = true; + scene.initializeFrame(); + scene.render(); + expect(context.readPixels()).toEqual([0, 0, 255, 255]); + }); + function createPrimitive(bounded, closestFrustum) { bounded = defaultValue(bounded, true); closestFrustum = defaultValue(closestFrustum, false); @@ -196,12 +208,12 @@ defineSuite([ var that = this; this._um = { - u_color : function() { - return that.color; - }, - u_model : function() { - return that._modelMatrix; - } + u_color : function() { + return that.color; + }, + u_model : function() { + return that._modelMatrix; + } }; }; From 3ba7d7ec65508ea349aefc01df0b57fea56f8705 Mon Sep 17 00:00:00 2001 From: Patrick Cozzi Date: Fri, 23 Aug 2013 14:13:52 -0400 Subject: [PATCH 7/9] Fix frustum stats --- CHANGES.md | 2 +- Source/Scene/Scene.js | 16 ++++++++-------- Specs/Scene/MultifrustumSpec.js | 2 ++ 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index a985db9b8135..d2c03c5af6ed 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -43,7 +43,7 @@ var geometry = BoxGeometry.createGeometry(box); * Added the ability to specify a `minimumTerrainLevel` and `maximumTerrainLevel` when constructing an `ImageryLayer`. The layer will only be shown for terrain tiles within the specified range. * Added `Math.setRandomNumberSeed` and `Math.nextRandomNumber` for generating repeatable random numbers. * Added `Color.fromRandom` to generate random and partially random colors. -* Added `Scene.debugShowFrustums` and `Scene.debugComputeFrustumsPerCommand` for rendering debugging. +* Added `Scene.debugShowFrustums` and `Scene.debugFrustumStatistics` for rendering debugging. * Improved geometry batching performance by moving work to a web worker. * Improved `WallGeometry` to follow the curvature of the earth. * Fixed broken surface rendering in Columbus View when using the `EllipsoidTerrainProvider`. diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 6363a7910e66..1094d652e315 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -245,10 +245,12 @@ define([ /** * DOC_TBA */ -// this.debugShowFrustums = true; this.debugShowFrustums = false; - this._debugFrustumsPerCommand = { + /** + * DOC_TBA + */ + this.debugFrustumStatistics = { totalCommands : 0, commandsInFrustums : [0, 0, 0, 0] }; @@ -392,7 +394,6 @@ define([ command.debugOverlappingFrustums = 0; } - var frustumCount = 0; var frustumCommandsList = scene._frustumCommandsList; var length = frustumCommandsList.length; @@ -414,7 +415,7 @@ define([ if (scene.debugShowFrustums) { command.debugOverlappingFrustums |= (1 << i); - ++frustumCount; + ++scene.debugFrustumStatistics.commandsInFrustums[i]; } if (command.executeInClosestFrustum) { @@ -423,8 +424,7 @@ define([ } if (scene.debugShowFrustums) { - ++scene._debugFrustumsPerCommand.totalCommands; - ++scene._debugFrustumsPerCommand.commandsInFrustums[frustumCount]; + ++scene.debugFrustumStatistics.totalCommands; } } @@ -440,8 +440,8 @@ define([ var position = camera.getPositionWC(); if (scene.debugShowFrustums) { - scene._debugFrustumsPerCommand.totalCommands = 0; - scene._debugFrustumsPerCommand.commandsInFrustums = [0, 0, 0, 0]; + scene.debugFrustumStatistics.totalCommands = 0; + scene.debugFrustumStatistics.commandsInFrustums = [0, 0, 0, 0]; } var frustumCommandsList = scene._frustumCommandsList; diff --git a/Specs/Scene/MultifrustumSpec.js b/Specs/Scene/MultifrustumSpec.js index 6a62fc3c220b..9297672d25c0 100644 --- a/Specs/Scene/MultifrustumSpec.js +++ b/Specs/Scene/MultifrustumSpec.js @@ -192,6 +192,8 @@ defineSuite([ scene.initializeFrame(); scene.render(); expect(context.readPixels()).toEqual([0, 0, 255, 255]); + expect(scene.debugFrustumStatistics.totalCommands).toEqual(3); + expect(scene.debugFrustumStatistics.commandsInFrustums).toEqual([1, 1, 1, 0]); }); function createPrimitive(bounded, closestFrustum) { From 110bb2c41f0fbc45e7f1e749d09705ad82ba51ec Mon Sep 17 00:00:00 2001 From: Patrick Cozzi Date: Fri, 23 Aug 2013 14:25:48 -0400 Subject: [PATCH 8/9] Finished doc --- Source/Scene/Scene.js | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 1094d652e315..19cb098a0b98 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -243,17 +243,39 @@ define([ this.debugCommandFilter = undefined; /** - * DOC_TBA + * This property is for debugging only; it is not for production use. + *

+ * When true, commands are shaded based on the frustums they + * overlap. Commands in the closest frustum are tinted red, commands in + * the next closest are green, and commands in the farthest frustum are + * blue. If a command overlaps more than one frustum, the color components + * are combined, e.g., a command overlapping the first two frustums is tinted + * yellow. + *

+ * + * @type Boolean + * + * @default false */ this.debugShowFrustums = false; /** - * DOC_TBA + * This property is for debugging only; it is not for production use. + *

+ * When {@see Scene.debugShowFrustums} is true, this contains + * properties with statistics about the number of command execute per frustum. + * totalCommands is the total number of commands executed, ignoring + * overlap. commandsInFrustums is an array with the number of commands + * executed in each frustum. + *

+ * + * @type Object + * + * @default undefined + * + * @readonly */ - this.debugFrustumStatistics = { - totalCommands : 0, - commandsInFrustums : [0, 0, 0, 0] - }; + this.debugFrustumStatistics = undefined; this._debugSphere = undefined; @@ -440,8 +462,10 @@ define([ var position = camera.getPositionWC(); if (scene.debugShowFrustums) { - scene.debugFrustumStatistics.totalCommands = 0; - scene.debugFrustumStatistics.commandsInFrustums = [0, 0, 0, 0]; + scene.debugFrustumStatistics = { + totalCommands : 0, + commandsInFrustums : [0, 0, 0, 0] + }; } var frustumCommandsList = scene._frustumCommandsList; From 4a4ac0c3c69db47dd3bc810b3583efecd4390967 Mon Sep 17 00:00:00 2001 From: Patrick Cozzi Date: Mon, 26 Aug 2013 08:02:23 -0400 Subject: [PATCH 9/9] Improve frustum stats --- Source/Renderer/DrawCommand.js | 2 +- Source/Scene/Scene.js | 18 ++++++++++-------- Specs/Scene/MultifrustumSpec.js | 2 +- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Source/Renderer/DrawCommand.js b/Source/Renderer/DrawCommand.js index 2bb96b57e5a9..52e1cdb03aa6 100644 --- a/Source/Renderer/DrawCommand.js +++ b/Source/Renderer/DrawCommand.js @@ -167,7 +167,7 @@ define(function() { /** * @private * - * Used for to implement {@see Scene.debugShowFrustums}. + * Used to implement {@see Scene.debugShowFrustums}. */ this.debugOverlappingFrustums = 0; }; diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 19cb098a0b98..736a520fdf9f 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -265,8 +265,9 @@ define([ * When {@see Scene.debugShowFrustums} is true, this contains * properties with statistics about the number of command execute per frustum. * totalCommands is the total number of commands executed, ignoring - * overlap. commandsInFrustums is an array with the number of commands - * executed in each frustum. + * overlap. commandsInFrustums is an array with the number of times + * commands are executed redundantly, e.g., how many commands overlap two or + * three frustums. *

* * @type Object @@ -437,7 +438,6 @@ define([ if (scene.debugShowFrustums) { command.debugOverlappingFrustums |= (1 << i); - ++scene.debugFrustumStatistics.commandsInFrustums[i]; } if (command.executeInClosestFrustum) { @@ -446,6 +446,8 @@ define([ } if (scene.debugShowFrustums) { + var cf = scene.debugFrustumStatistics.commandsInFrustums; + cf[command.debugOverlappingFrustums] = defined(cf[command.debugOverlappingFrustums]) ? cf[command.debugOverlappingFrustums] + 1 : 1; ++scene.debugFrustumStatistics.totalCommands; } } @@ -464,13 +466,13 @@ define([ if (scene.debugShowFrustums) { scene.debugFrustumStatistics = { totalCommands : 0, - commandsInFrustums : [0, 0, 0, 0] + commandsInFrustums : {} }; } var frustumCommandsList = scene._frustumCommandsList; - var frustumsLength = frustumCommandsList.length; - for (var n = 0; n < frustumsLength; ++n) { + var numberOfFrustums = frustumCommandsList.length; + for (var n = 0; n < numberOfFrustums; ++n) { frustumCommandsList[n].index = 0; } @@ -537,8 +539,8 @@ define([ // last frame, else compute the new frustums and sort them by frustum again. var farToNearRatio = scene.farToNearRatio; var numFrustums = Math.ceil(Math.log(far / near) / Math.log(farToNearRatio)); - if (near !== Number.MAX_VALUE && (numFrustums !== frustumsLength || (frustumCommandsList.length !== 0 && - (near < frustumCommandsList[0].near || far > frustumCommandsList[frustumsLength - 1].far)))) { + if (near !== Number.MAX_VALUE && (numFrustums !== numberOfFrustums || (frustumCommandsList.length !== 0 && + (near < frustumCommandsList[0].near || far > frustumCommandsList[numberOfFrustums - 1].far)))) { updateFrustums(near, far, farToNearRatio, numFrustums, frustumCommandsList); createPotentiallyVisibleSet(scene, listName); } diff --git a/Specs/Scene/MultifrustumSpec.js b/Specs/Scene/MultifrustumSpec.js index 9297672d25c0..d7420557a63f 100644 --- a/Specs/Scene/MultifrustumSpec.js +++ b/Specs/Scene/MultifrustumSpec.js @@ -193,7 +193,7 @@ defineSuite([ scene.render(); expect(context.readPixels()).toEqual([0, 0, 255, 255]); expect(scene.debugFrustumStatistics.totalCommands).toEqual(3); - expect(scene.debugFrustumStatistics.commandsInFrustums).toEqual([1, 1, 1, 0]); + expect(scene.debugFrustumStatistics.commandsInFrustums).toEqual({ 1 : 1, 2 : 1, 4 : 1}); }); function createPrimitive(bounded, closestFrustum) {