Skip to content

Commit

Permalink
fix artifacts in 2D and morph
Browse files Browse the repository at this point in the history
  • Loading branch information
likangning93 committed Jun 11, 2018
1 parent fa7075f commit 81a23c8
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 32 deletions.
6 changes: 3 additions & 3 deletions Source/Scene/GroundPolylinePrimitive.js
Original file line number Diff line number Diff line change
Expand Up @@ -405,10 +405,10 @@ define([

// Check for use of v_width and v_polylineAngle in material shader
// to determine whether these varyings should be active in the vertex shader.
if (materialShaderSource.search(/varying\s+float\s+v_polylineAngle;/g) === -1) {
if (materialShaderSource.search(/varying\s+float\s+v_polylineAngle;/g) !== -1) {
vsDefines.push('ANGLE_VARYING');
}
if (materialShaderSource.search(/varying\s+float\s+v_width;/g) === -1) {
if (materialShaderSource.search(/varying\s+float\s+v_width;/g) !== -1) {
vsDefines.push('WIDTH_VARYING');
}
} else {
Expand Down Expand Up @@ -455,7 +455,7 @@ define([
var colorProgramMorph = context.shaderCache.getDerivedShaderProgram(groundPolylinePrimitive._sp, 'MorphColor');
if (!defined(colorProgramMorph)) {
var vsColorMorph = new ShaderSource({
defines : vsDefines,
defines : vsDefines.concat(['MAX_TERRAIN_HEIGHT ' + ApproximateTerrainHeights._defaultMaxTerrainHeight.toFixed(1)]),
sources : [vsMorph]
});

Expand Down
2 changes: 1 addition & 1 deletion Source/Shaders/PolylineShadowVolumeFS.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ varying vec4 v_color;

void main(void)
{
float logDepthOrDepth = czm_unpackDepth(texture2D(czm_globeDepthTexture, gl_FragCoord.xy / czm_viewport.zw));
float logDepthOrDepth = czm_branchFreeTernary(czm_sceneMode == czm_sceneMode2D, gl_FragCoord.z, czm_unpackDepth(texture2D(czm_globeDepthTexture, gl_FragCoord.xy / czm_viewport.zw)));
vec3 ecStart = vec3(v_endEcAndStartEcX.w, v_texcoordNormalizationAndStartEcYZ.zw);

// Discard for sky
Expand Down
75 changes: 47 additions & 28 deletions Source/Shaders/PolylineShadowVolumeMorphVS.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -42,56 +42,64 @@ void main()
vec4 posRelativeToEye2D = czm_translateRelativeToEye(vec3(0.0, startHiLo2D.xy), vec3(0.0, startHiLo2D.zw));
vec4 posRelativeToEye3D = czm_translateRelativeToEye(startHiAndForwardOffsetX.xyz, startLoAndForwardOffsetY.xyz);
vec4 posRelativeToEye = czm_columbusViewMorph(posRelativeToEye2D, posRelativeToEye3D, czm_morphTime);
vec3 ecPos2D = (czm_modelViewRelativeToEye * posRelativeToEye2D).xyz;
vec3 ecPos3D = (czm_modelViewRelativeToEye * posRelativeToEye3D).xyz;
vec3 ecStart = (czm_modelViewRelativeToEye * posRelativeToEye).xyz;
vec3 posEc2D = (czm_modelViewRelativeToEye * posRelativeToEye2D).xyz;
vec3 posEc3D = (czm_modelViewRelativeToEye * posRelativeToEye3D).xyz;
vec3 startEC = (czm_modelViewRelativeToEye * posRelativeToEye).xyz;

// Start plane
vec4 startPlane2D;
vec4 startPlane3D;
startPlane2D.xyz = czm_normal * vec3(0.0, startEndNormals2D.xy);
startPlane3D.xyz = czm_normal * startNormalAndForwardOffsetZ.xyz;
startPlane2D.w = -dot(startPlane2D.xyz, ecPos2D);
startPlane3D.w = -dot(startPlane3D.xyz, ecPos3D);
startPlane2D.w = -dot(startPlane2D.xyz, posEc2D);
startPlane3D.w = -dot(startPlane3D.xyz, posEc3D);

// Right plane
vec4 rightPlane2D;
vec4 rightPlane3D;
rightPlane2D.xyz = czm_normal * vec3(0.0, offsetAndRight2D.zw);
rightPlane3D.xyz = czm_normal * rightNormalAndTextureCoordinateNormalizationY.xyz;
rightPlane2D.w = -dot(rightPlane2D.xyz, ecPos2D);
rightPlane3D.w = -dot(rightPlane3D.xyz, ecPos3D);
rightPlane2D.w = -dot(rightPlane2D.xyz, posEc2D);
rightPlane3D.w = -dot(rightPlane3D.xyz, posEc3D);

// End position
posRelativeToEye2D = posRelativeToEye2D + vec4(0.0, offsetAndRight2D.xy, 0.0);
posRelativeToEye3D = posRelativeToEye3D + vec4(startHiAndForwardOffsetX.w, startLoAndForwardOffsetY.w, startNormalAndForwardOffsetZ.w, 0.0);
posRelativeToEye = czm_columbusViewMorph(posRelativeToEye2D, posRelativeToEye3D, czm_morphTime);
ecPos2D = (czm_modelViewRelativeToEye * posRelativeToEye2D).xyz;
ecPos3D = (czm_modelViewRelativeToEye * posRelativeToEye3D).xyz;
vec3 ecEnd = (czm_modelViewRelativeToEye * posRelativeToEye).xyz;
posEc2D = (czm_modelViewRelativeToEye * posRelativeToEye2D).xyz;
posEc3D = (czm_modelViewRelativeToEye * posRelativeToEye3D).xyz;
vec3 endEC = (czm_modelViewRelativeToEye * posRelativeToEye).xyz;
vec3 forwardEc3D = czm_normal * normalize(vec3(startHiAndForwardOffsetX.w, startLoAndForwardOffsetY.w, startNormalAndForwardOffsetZ.w));
vec3 forwardEc2D = czm_normal * normalize(vec3(0.0, offsetAndRight2D.xy));

// End plane
vec4 endPlane2D;
vec4 endPlane3D;
endPlane2D.xyz = czm_normal * vec3(0.0, startEndNormals2D.zw);
endPlane3D.xyz = czm_normal * endNormalAndTextureCoordinateNormalizationX.xyz;
endPlane2D.w = -dot(endPlane2D.xyz, ecPos2D);
endPlane3D.w = -dot(endPlane3D.xyz, ecPos3D);
endPlane2D.w = -dot(endPlane2D.xyz, posEc2D);
endPlane3D.w = -dot(endPlane3D.xyz, posEc3D);

// Forward direction
v_forwardDirectionEC = normalize(ecEnd - ecStart);
v_forwardDirectionEC = normalize(endEC - startEC);

v_texcoordNormalization_and_halfWidth.xy = mix(
vec2(abs(texcoordNormalization2D.x), texcoordNormalization2D.y),
vec2(abs(endNormalAndTextureCoordinateNormalizationX.w), rightNormalAndTextureCoordinateNormalizationY.w), czm_morphTime);
vec2 cleanTexcoordNormalization2D;
cleanTexcoordNormalization2D.x = abs(texcoordNormalization2D.x);
cleanTexcoordNormalization2D.y = czm_branchFreeTernary(texcoordNormalization2D.y > 1.0, 0.0, abs(texcoordNormalization2D.y));
vec2 cleanTexcoordNormalization3D;
cleanTexcoordNormalization3D.x = abs(endNormalAndTextureCoordinateNormalizationX.w);
cleanTexcoordNormalization3D.y = rightNormalAndTextureCoordinateNormalizationY.w;
cleanTexcoordNormalization3D.y = czm_branchFreeTernary(cleanTexcoordNormalization3D.y > 1.0, 0.0, abs(cleanTexcoordNormalization3D.y));

v_texcoordNormalization_and_halfWidth.xy = mix(cleanTexcoordNormalization2D, cleanTexcoordNormalization3D, czm_morphTime);

#ifdef PER_INSTANCE_COLOR
v_color = czm_batchTable_color(batchId);
#else // PER_INSTANCE_COLOR
// For computing texture coordinates

v_alignedPlaneDistances.x = -dot(v_forwardDirectionEC, ecStart);
v_alignedPlaneDistances.y = -dot(-v_forwardDirectionEC, ecEnd);
v_alignedPlaneDistances.x = -dot(v_forwardDirectionEC, startEC);
v_alignedPlaneDistances.y = -dot(-v_forwardDirectionEC, endEC);
#endif // PER_INSTANCE_COLOR

#ifdef WIDTH_VARYING
Expand All @@ -111,29 +119,41 @@ void main()

// ****** 3D ******
// Check distance to the end plane and start plane, pick the plane that is closer
vec4 positionEC3D = czm_modelViewRelativeToEye * czm_translateRelativeToEye(position3DHigh, position3DLow); // w = 1.0, see czm_computePosition
float absStartPlaneDistance = abs(czm_planeDistance(startPlane3D, positionEC3D.xyz));
float absEndPlaneDistance = abs(czm_planeDistance(endPlane3D, positionEC3D.xyz));
vec4 positionEc3D = czm_modelViewRelativeToEye * czm_translateRelativeToEye(position3DHigh, position3DLow); // w = 1.0, see czm_computePosition
float absStartPlaneDistance = abs(czm_planeDistance(startPlane3D, positionEc3D.xyz));
float absEndPlaneDistance = abs(czm_planeDistance(endPlane3D, positionEc3D.xyz));
vec3 planeDirection = czm_branchFreeTernary(absStartPlaneDistance < absEndPlaneDistance, startPlane3D.xyz, endPlane3D.xyz);
vec3 upOrDown = normalize(cross(rightPlane3D.xyz, planeDirection)); // Points "up" for start plane, "down" at end plane.
vec3 normalEC = normalize(cross(planeDirection, upOrDown)); // In practice, the opposite seems to work too.

// Nudge the top vertex upwards to prevent flickering
vec3 geodeticSurfaceNormal = normalize(cross(normalEC, forwardEc3D));
geodeticSurfaceNormal *= float(0.0 <= rightNormalAndTextureCoordinateNormalizationY.w && rightNormalAndTextureCoordinateNormalizationY.w <= 1.0);
geodeticSurfaceNormal *= MAX_TERRAIN_HEIGHT;
positionEc3D.xyz += geodeticSurfaceNormal;

// Determine if this vertex is on the "left" or "right"
normalEC *= sign(endNormalAndTextureCoordinateNormalizationX.w);

// A "perfect" implementation would push along normals according to the angle against forward.
// In practice, just pushing the normal out by halfWidth is sufficient for morph views.
positionEC3D.xyz += halfWidth * max(0.0, czm_metersPerPixel(positionEC3D)) * normalEC; // prevent artifacts when czm_metersPerPixel is negative (behind camera)
positionEc3D.xyz += halfWidth * max(0.0, czm_metersPerPixel(positionEc3D)) * normalEC; // prevent artifacts when czm_metersPerPixel is negative (behind camera)

// ****** 2D ******
// Check distance to the end plane and start plane, pick the plane that is closer
vec4 positionEC2D = czm_modelViewRelativeToEye * czm_translateRelativeToEye(position2DHigh.zxy, position2DLow.zxy); // w = 1.0, see czm_computePosition
absStartPlaneDistance = abs(czm_planeDistance(startPlane2D, positionEC2D.xyz));
absEndPlaneDistance = abs(czm_planeDistance(endPlane2D, positionEC2D.xyz));
vec4 positionEc2D = czm_modelViewRelativeToEye * czm_translateRelativeToEye(position2DHigh.zxy, position2DLow.zxy); // w = 1.0, see czm_computePosition
absStartPlaneDistance = abs(czm_planeDistance(startPlane2D, positionEc2D.xyz));
absEndPlaneDistance = abs(czm_planeDistance(endPlane2D, positionEc2D.xyz));
planeDirection = czm_branchFreeTernary(absStartPlaneDistance < absEndPlaneDistance, startPlane2D.xyz, endPlane2D.xyz);
upOrDown = normalize(cross(rightPlane2D.xyz, planeDirection)); // Points "up" for start plane, "down" at end plane.
normalEC = normalize(cross(planeDirection, upOrDown)); // In practice, the opposite seems to work too.

// Nudge the top vertex upwards to prevent flickering
geodeticSurfaceNormal = normalize(cross(normalEC, forwardEc2D));
geodeticSurfaceNormal *= float(0.0 <= texcoordNormalization2D.y && texcoordNormalization2D.y <= 1.0);
geodeticSurfaceNormal *= MAX_TERRAIN_HEIGHT;
positionEc2D.xyz += geodeticSurfaceNormal;

// Determine if this vertex is on the "left" or "right"
normalEC *= sign(texcoordNormalization2D.x);
#ifndef PER_INSTANCE_COLOR
Expand All @@ -143,11 +163,10 @@ void main()

// A "perfect" implementation would push along normals according to the angle against forward.
// In practice, just pushing the normal out by halfWidth is sufficient for morph views.
positionEC2D.xyz -= normalEC; // undo the unit length push
positionEC2D.xyz += halfWidth * max(0.0, czm_metersPerPixel(positionEC2D)) * normalEC; // prevent artifacts when czm_metersPerPixel is negative (behind camera)
positionEc2D.xyz += halfWidth * max(0.0, czm_metersPerPixel(positionEc2D)) * normalEC; // prevent artifacts when czm_metersPerPixel is negative (behind camera)

// Blend for actual position
gl_Position = czm_projection * mix(positionEC2D, positionEC3D, czm_morphTime);
gl_Position = czm_projection * mix(positionEc2D, positionEc3D, czm_morphTime);

#ifdef ANGLE_VARYING
// Approximate relative screen space direction of the line.
Expand Down

0 comments on commit 81a23c8

Please sign in to comment.