From e3489c48689c2ba71f57f6806db07fdd5433b606 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 29 Jul 2013 15:36:51 -0400 Subject: [PATCH 1/3] Make sensors render in two passes: back face and front face. Also adds ambient light to sensors. --- Source/Scene/CustomSensorVolume.js | 75 ++++++++++++++++++++++-- Source/Shaders/CustomSensorVolumeFS.glsl | 6 +- 2 files changed, 73 insertions(+), 8 deletions(-) diff --git a/Source/Scene/CustomSensorVolume.js b/Source/Scene/CustomSensorVolume.js index ea0dd587b079..ca3c379a66c9 100644 --- a/Source/Scene/CustomSensorVolume.js +++ b/Source/Scene/CustomSensorVolume.js @@ -16,6 +16,7 @@ define([ '../Renderer/CommandLists', '../Renderer/DrawCommand', '../Renderer/createPickFragmentShaderSource', + '../Renderer/CullFace', './Material', '../Shaders/SensorVolume', '../Shaders/CustomSensorVolumeVS', @@ -38,6 +39,7 @@ define([ CommandLists, DrawCommand, createPickFragmentShaderSource, + CullFace, Material, ShadersSensorVolume, CustomSensorVolumeVS, @@ -65,11 +67,22 @@ define([ this._pickIdThis = defaultValue(options._pickIdThis, this); this._colorCommand = new DrawCommand(); + this._backFaceColorCommand = new DrawCommand(); this._pickCommand = new DrawCommand(); + this._backFacePickCommand = new DrawCommand(); this._commandLists = new CommandLists(); - this._colorCommand.primitiveType = this._pickCommand.primitiveType = PrimitiveType.TRIANGLES; - this._colorCommand.boundingVolume = this._pickCommand.boundingVolume = new BoundingSphere(); + this._colorCommand.primitiveType = PrimitiveType.TRIANGLES; + this._colorCommand.boundingVolume = new BoundingSphere(); + + this._backFaceColorCommand.primitiveType = this._colorCommand.primitiveType; + this._backFaceColorCommand.boundingVolume = this._colorCommand.boundingVolume; + + this._pickCommand.primitiveType = this._colorCommand.primitiveType; + this._pickCommand.boundingVolume = this._colorCommand.boundingVolume; + + this._backFacePickCommand.primitiveType = this._colorCommand.primitiveType; + this._backFacePickCommand.boundingVolume = this._colorCommand.boundingVolume; /** * true if this sensor will be shown; otherwise, false @@ -207,6 +220,9 @@ define([ }, u_intersectionWidth : function() { return that.intersectionWidth; + }, + u_backFace : function() { + return 0.0; } }; @@ -357,11 +373,33 @@ define([ enabled : !this.showThroughEllipsoid }, depthMask : false, - blending : BlendingState.ALPHA_BLEND + blending : BlendingState.ALPHA_BLEND, + cull : { + enabled : true, + face : CullFace.BACK + } }); this._colorCommand.renderState = rs; this._pickCommand.renderState = rs; + + rs = context.createRenderState({ + depthTest : { + // This would be better served by depth testing with a depth buffer that does not + // include the ellipsoid depth - or a g-buffer containing an ellipsoid mask + // so we can selectively depth test. + enabled : !this.showThroughEllipsoid + }, + depthMask : false, + blending : BlendingState.ALPHA_BLEND, + cull : { + enabled : true, + face : CullFace.FRONT + } + }); + + this._backFaceColorCommand.renderState = rs; + this._backFacePickCommand.renderState = rs; } // Recreate vertex buffer when directions change @@ -372,7 +410,10 @@ define([ var directions = this._directions; if (directions && (directions.length >= 3)) { - this._colorCommand.vertexArray = this._pickCommand.vertexArray = createVertexArray(this, context); + this._colorCommand.vertexArray = createVertexArray(this, context); + this._pickCommand.vertexArray = this._colorCommand.vertexArray; + this._backFaceColorCommand.vertexArray = this._colorCommand.vertexArray; + this._backFacePickCommand.vertexArray = this._colorCommand.vertexArray; } } @@ -381,14 +422,19 @@ define([ } var pass = frameState.passes; - this._colorCommand.modelMatrix = this._pickCommand.modelMatrix = this.modelMatrix; this._commandLists.removeAll(); + this._colorCommand.modelMatrix = this.modelMatrix; + this._pickCommand.modelMatrix = this._colorCommand.modelMatrix; + this._backFaceColorCommand.modelMatrix = this._colorCommand.modelMatrix; + this._backFacePickCommand.modelMatrix = this._colorCommand.modelMatrix; + var materialChanged = this._material !== this.material; this._material = this.material; if (pass.color) { var colorCommand = this._colorCommand; + var backFaceColorCommand = this._backFaceColorCommand; // Recompile shader when material changes if (materialChanged || typeof colorCommand.shaderProgram === 'undefined') { @@ -403,13 +449,21 @@ define([ colorCommand.shaderProgram = context.getShaderCache().replaceShaderProgram( colorCommand.shaderProgram, CustomSensorVolumeVS, fsSource, attributeIndices); colorCommand.uniformMap = combine([this._uniforms, this._material._uniforms], false, false); + + backFaceColorCommand.shaderProgram = colorCommand.shaderProgram; + backFaceColorCommand.uniformMap = combine([this._uniforms, this._material._uniforms], false, false); + backFaceColorCommand.uniformMap.u_backFace = function() { + return 1.0; + }; } + this._commandLists.colorList.push(backFaceColorCommand); this._commandLists.colorList.push(colorCommand); } if (pass.pick) { var pickCommand = this._pickCommand; + var backFacePickCommand = this._backFacePickCommand; if (typeof this._pickId === 'undefined') { this._pickId = context.createPickId(this._pickIdThis); @@ -434,8 +488,19 @@ define([ return that._pickId.color; } }], false, false); + + backFacePickCommand.shaderProgram = pickCommand.shaderProgram; + backFacePickCommand.uniformMap = combine([this._uniforms, this._material._uniforms, { + czm_pickColor : function() { + return that._pickId.color; + } + }], false, false); + backFacePickCommand.uniformMap.u_backFace = function() { + return 1.0; + }; } + this._commandLists.pickList.push(backFacePickCommand); this._commandLists.pickList.push(pickCommand); } diff --git a/Source/Shaders/CustomSensorVolumeFS.glsl b/Source/Shaders/CustomSensorVolumeFS.glsl index f08c85853295..ab9f86045d3b 100644 --- a/Source/Shaders/CustomSensorVolumeFS.glsl +++ b/Source/Shaders/CustomSensorVolumeFS.glsl @@ -6,6 +6,7 @@ uniform bool u_showIntersection; uniform bool u_showThroughEllipsoid; uniform float u_sensorRadius; +uniform float u_backFace; varying vec3 v_positionWC; varying vec3 v_positionEC; @@ -23,11 +24,10 @@ vec4 getColor(float sensorRadius, vec3 pointEC) materialInput.positionToEyeEC = positionToEyeEC; vec3 normalEC = normalize(v_normalEC); - normalEC = mix(normalEC, -normalEC, step(normalEC.z, 0.0)); // Normal facing viewer - materialInput.normalEC = normalEC; + materialInput.normalEC = mix(normalEC, -normalEC, u_backFace); czm_material material = czm_getMaterial(materialInput); - return czm_phong(normalize(positionToEyeEC), material); + return mix(czm_phong(normalize(positionToEyeEC), material), vec4(material.diffuse, material.alpha), 0.4); } bool isOnBoundary(float value, float epsilon) From a652f278366c5f6c425135dc6bf6b0f584931893 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 29 Jul 2013 15:58:42 -0400 Subject: [PATCH 2/3] Update based on review. --- Source/Scene/CustomSensorVolume.js | 92 +++++++++++------------- Source/Shaders/CustomSensorVolumeFS.glsl | 4 +- 2 files changed, 44 insertions(+), 52 deletions(-) diff --git a/Source/Scene/CustomSensorVolume.js b/Source/Scene/CustomSensorVolume.js index ca3c379a66c9..a6c600c83b0f 100644 --- a/Source/Scene/CustomSensorVolume.js +++ b/Source/Scene/CustomSensorVolume.js @@ -66,23 +66,19 @@ define([ this._pickId = undefined; this._pickIdThis = defaultValue(options._pickIdThis, this); - this._colorCommand = new DrawCommand(); + this._frontFaceColorCommand = new DrawCommand(); this._backFaceColorCommand = new DrawCommand(); this._pickCommand = new DrawCommand(); - this._backFacePickCommand = new DrawCommand(); this._commandLists = new CommandLists(); - this._colorCommand.primitiveType = PrimitiveType.TRIANGLES; - this._colorCommand.boundingVolume = new BoundingSphere(); + this._frontFaceColorCommand.primitiveType = PrimitiveType.TRIANGLES; + this._frontFaceColorCommand.boundingVolume = new BoundingSphere(); - this._backFaceColorCommand.primitiveType = this._colorCommand.primitiveType; - this._backFaceColorCommand.boundingVolume = this._colorCommand.boundingVolume; + this._backFaceColorCommand.primitiveType = this._frontFaceColorCommand.primitiveType; + this._backFaceColorCommand.boundingVolume = this._frontFaceColorCommand.boundingVolume; - this._pickCommand.primitiveType = this._colorCommand.primitiveType; - this._pickCommand.boundingVolume = this._colorCommand.boundingVolume; - - this._backFacePickCommand.primitiveType = this._colorCommand.primitiveType; - this._backFacePickCommand.boundingVolume = this._colorCommand.boundingVolume; + this._pickCommand.primitiveType = this._frontFaceColorCommand.primitiveType; + this._pickCommand.boundingVolume = this._frontFaceColorCommand.boundingVolume; /** * true if this sensor will be shown; otherwise, false @@ -221,8 +217,8 @@ define([ u_intersectionWidth : function() { return that.intersectionWidth; }, - u_backFace : function() { - return 0.0; + u_normalDirection : function() { + return 1.0; } }; @@ -278,7 +274,7 @@ define([ boundingVolumePositions.push(p); } - BoundingSphere.fromPoints(boundingVolumePositions, customSensorVolume._colorCommand.boundingVolume); + BoundingSphere.fromPoints(boundingVolumePositions, customSensorVolume._frontFaceColorCommand.boundingVolume); return positions; } @@ -362,7 +358,7 @@ define([ } // Initial render state creation - if ((this._showThroughEllipsoid !== this.showThroughEllipsoid) || (typeof this._colorCommand.renderState === 'undefined')) { + if ((this._showThroughEllipsoid !== this.showThroughEllipsoid) || (typeof this._frontFaceColorCommand.renderState === 'undefined')) { this._showThroughEllipsoid = this.showThroughEllipsoid; var rs = context.createRenderState({ @@ -380,8 +376,7 @@ define([ } }); - this._colorCommand.renderState = rs; - this._pickCommand.renderState = rs; + this._frontFaceColorCommand.renderState = rs; rs = context.createRenderState({ depthTest : { @@ -399,7 +394,18 @@ define([ }); this._backFaceColorCommand.renderState = rs; - this._backFacePickCommand.renderState = rs; + + rs = context.createRenderState({ + depthTest : { + // This would be better served by depth testing with a depth buffer that does not + // include the ellipsoid depth - or a g-buffer containing an ellipsoid mask + // so we can selectively depth test. + enabled : !this.showThroughEllipsoid + }, + depthMask : false, + blending : BlendingState.ALPHA_BLEND + }); + this._pickCommand.renderState = rs; } // Recreate vertex buffer when directions change @@ -410,34 +416,32 @@ define([ var directions = this._directions; if (directions && (directions.length >= 3)) { - this._colorCommand.vertexArray = createVertexArray(this, context); - this._pickCommand.vertexArray = this._colorCommand.vertexArray; - this._backFaceColorCommand.vertexArray = this._colorCommand.vertexArray; - this._backFacePickCommand.vertexArray = this._colorCommand.vertexArray; + this._frontFaceColorCommand.vertexArray = createVertexArray(this, context); + this._backFaceColorCommand.vertexArray = this._frontFaceColorCommand.vertexArray; + this._pickCommand.vertexArray = this._frontFaceColorCommand.vertexArray; } } - if (typeof this._colorCommand.vertexArray === 'undefined') { + if (typeof this._frontFaceColorCommand.vertexArray === 'undefined') { return; } var pass = frameState.passes; this._commandLists.removeAll(); - this._colorCommand.modelMatrix = this.modelMatrix; - this._pickCommand.modelMatrix = this._colorCommand.modelMatrix; - this._backFaceColorCommand.modelMatrix = this._colorCommand.modelMatrix; - this._backFacePickCommand.modelMatrix = this._colorCommand.modelMatrix; + this._frontFaceColorCommand.modelMatrix = this.modelMatrix; + this._backFaceColorCommand.modelMatrix = this._frontFaceColorCommand.modelMatrix; + this._pickCommand.modelMatrix = this._frontFaceColorCommand.modelMatrix; var materialChanged = this._material !== this.material; this._material = this.material; if (pass.color) { - var colorCommand = this._colorCommand; + var frontFaceColorCommand = this._frontFaceColorCommand; var backFaceColorCommand = this._backFaceColorCommand; // Recompile shader when material changes - if (materialChanged || typeof colorCommand.shaderProgram === 'undefined') { + if (materialChanged || typeof frontFaceColorCommand.shaderProgram === 'undefined') { var fsSource = '#line 0\n' + ShadersSensorVolume + @@ -446,24 +450,23 @@ define([ '#line 0\n' + CustomSensorVolumeFS; - colorCommand.shaderProgram = context.getShaderCache().replaceShaderProgram( - colorCommand.shaderProgram, CustomSensorVolumeVS, fsSource, attributeIndices); - colorCommand.uniformMap = combine([this._uniforms, this._material._uniforms], false, false); + frontFaceColorCommand.shaderProgram = context.getShaderCache().replaceShaderProgram( + frontFaceColorCommand.shaderProgram, CustomSensorVolumeVS, fsSource, attributeIndices); + frontFaceColorCommand.uniformMap = combine([this._uniforms, this._material._uniforms], false, false); - backFaceColorCommand.shaderProgram = colorCommand.shaderProgram; + backFaceColorCommand.shaderProgram = frontFaceColorCommand.shaderProgram; backFaceColorCommand.uniformMap = combine([this._uniforms, this._material._uniforms], false, false); - backFaceColorCommand.uniformMap.u_backFace = function() { - return 1.0; + backFaceColorCommand.uniformMap.u_normalDirection = function() { + return -1.0; }; } this._commandLists.colorList.push(backFaceColorCommand); - this._commandLists.colorList.push(colorCommand); + this._commandLists.colorList.push(frontFaceColorCommand); } if (pass.pick) { var pickCommand = this._pickCommand; - var backFacePickCommand = this._backFacePickCommand; if (typeof this._pickId === 'undefined') { this._pickId = context.createPickId(this._pickIdThis); @@ -488,19 +491,8 @@ define([ return that._pickId.color; } }], false, false); - - backFacePickCommand.shaderProgram = pickCommand.shaderProgram; - backFacePickCommand.uniformMap = combine([this._uniforms, this._material._uniforms, { - czm_pickColor : function() { - return that._pickId.color; - } - }], false, false); - backFacePickCommand.uniformMap.u_backFace = function() { - return 1.0; - }; } - this._commandLists.pickList.push(backFacePickCommand); this._commandLists.pickList.push(pickCommand); } @@ -522,8 +514,8 @@ define([ * @memberof CustomSensorVolume */ CustomSensorVolume.prototype.destroy = function() { - this._colorCommand.vertexArray = this._colorCommand.vertexArray && this._colorCommand.vertexArray.destroy(); - this._colorCommand.shaderProgram = this._colorCommand.shaderProgram && this._colorCommand.shaderProgram.release(); + this._frontFaceColorCommand.vertexArray = this._frontFaceColorCommand.vertexArray && this._frontFaceColorCommand.vertexArray.destroy(); + this._frontFaceColorCommand.shaderProgram = this._frontFaceColorCommand.shaderProgram && this._frontFaceColorCommand.shaderProgram.release(); this._pickCommand.shaderProgram = this._pickCommand.shaderProgram && this._pickCommand.shaderProgram.release(); this._pickId = this._pickId && this._pickId.destroy(); return destroyObject(this); diff --git a/Source/Shaders/CustomSensorVolumeFS.glsl b/Source/Shaders/CustomSensorVolumeFS.glsl index ab9f86045d3b..59ae691b48ba 100644 --- a/Source/Shaders/CustomSensorVolumeFS.glsl +++ b/Source/Shaders/CustomSensorVolumeFS.glsl @@ -6,7 +6,7 @@ uniform bool u_showIntersection; uniform bool u_showThroughEllipsoid; uniform float u_sensorRadius; -uniform float u_backFace; +uniform float u_normalDirection; varying vec3 v_positionWC; varying vec3 v_positionEC; @@ -24,7 +24,7 @@ vec4 getColor(float sensorRadius, vec3 pointEC) materialInput.positionToEyeEC = positionToEyeEC; vec3 normalEC = normalize(v_normalEC); - materialInput.normalEC = mix(normalEC, -normalEC, u_backFace); + materialInput.normalEC = u_normalDirection * normalEC; czm_material material = czm_getMaterial(materialInput); return mix(czm_phong(normalize(positionToEyeEC), material), vec4(material.diffuse, material.alpha), 0.4); From c38568a6a2ba26c62579d20c115c22966a561ae6 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 29 Jul 2013 17:49:03 -0400 Subject: [PATCH 3/3] Fix after merge. --- Source/Scene/CustomSensorVolume.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Source/Scene/CustomSensorVolume.js b/Source/Scene/CustomSensorVolume.js index a6c600c83b0f..f857d19ac8d4 100644 --- a/Source/Scene/CustomSensorVolume.js +++ b/Source/Scene/CustomSensorVolume.js @@ -73,12 +73,15 @@ define([ this._frontFaceColorCommand.primitiveType = PrimitiveType.TRIANGLES; this._frontFaceColorCommand.boundingVolume = new BoundingSphere(); + this._frontFaceColorCommand.owner = this; this._backFaceColorCommand.primitiveType = this._frontFaceColorCommand.primitiveType; this._backFaceColorCommand.boundingVolume = this._frontFaceColorCommand.boundingVolume; + this._backFaceColorCommand.owner = this; this._pickCommand.primitiveType = this._frontFaceColorCommand.primitiveType; this._pickCommand.boundingVolume = this._frontFaceColorCommand.boundingVolume; + this._pickCommand.owner = this; /** * true if this sensor will be shown; otherwise, false