Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sensor Lighting #985

Merged
merged 4 commits into from
Jul 30, 2013
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 70 additions & 5 deletions Source/Scene/CustomSensorVolume.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ define([
'../Renderer/CommandLists',
'../Renderer/DrawCommand',
'../Renderer/createPickFragmentShaderSource',
'../Renderer/CullFace',
'./Material',
'../Shaders/SensorVolume',
'../Shaders/CustomSensorVolumeVS',
Expand All @@ -38,6 +39,7 @@ define([
CommandLists,
DrawCommand,
createPickFragmentShaderSource,
CullFace,
Material,
ShadersSensorVolume,
CustomSensorVolumeVS,
Expand Down Expand Up @@ -65,11 +67,22 @@ define([
this._pickIdThis = defaultValue(options._pickIdThis, this);

this._colorCommand = new DrawCommand();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably rename to indicate that this is the front-face pass.

this._backFaceColorCommand = new DrawCommand();
this._pickCommand = new DrawCommand();
this._backFacePickCommand = new DrawCommand();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does picking need separate back and front face passes? Can't this be done in one pass since we only care about the pick id (color), not the shading?

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;

/**
* <code>true</code> if this sensor will be shown; otherwise, <code>false</code>
Expand Down Expand Up @@ -207,6 +220,9 @@ define([
},
u_intersectionWidth : function() {
return that.intersectionWidth;
},
u_backFace : function() {
return 0.0;
}
};

Expand Down Expand Up @@ -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
Expand All @@ -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;
}
}

Expand All @@ -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') {
Expand All @@ -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);
Expand All @@ -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);
}

Expand Down
6 changes: 3 additions & 3 deletions Source/Shaders/CustomSensorVolumeFS.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the mix, and just let u_backFace be -1.0 or 1.0 and multiple it. It could use a better name.


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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Long-term, we should figure out a better solution than hard-coding values like 0.4 here. The problem is czm_phong uses "fake" light vectors in an attempt to ensure abstract objects are always lit for visibility, but, there are certain camera angles (particularly on translucent objects like sensor cones) where the diffuse light still falls to zero. So here, we've mapped [0.0, 1.0] to [0.4, 1.0] to emulate ambient light, preventing the color from reaching full black.

Ideally, as @mramato suggested in #925, there would be a scene-level ambient light setting, that would apply the above mix to all phong lighting in the scene using a user-supplied value.

}

bool isOnBoundary(float value, float epsilon)
Expand Down