Skip to content

Commit 81a23c8

Browse files
committed
fix artifacts in 2D and morph
1 parent fa7075f commit 81a23c8

File tree

3 files changed

+51
-32
lines changed

3 files changed

+51
-32
lines changed

Source/Scene/GroundPolylinePrimitive.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -405,10 +405,10 @@ define([
405405

406406
// Check for use of v_width and v_polylineAngle in material shader
407407
// to determine whether these varyings should be active in the vertex shader.
408-
if (materialShaderSource.search(/varying\s+float\s+v_polylineAngle;/g) === -1) {
408+
if (materialShaderSource.search(/varying\s+float\s+v_polylineAngle;/g) !== -1) {
409409
vsDefines.push('ANGLE_VARYING');
410410
}
411-
if (materialShaderSource.search(/varying\s+float\s+v_width;/g) === -1) {
411+
if (materialShaderSource.search(/varying\s+float\s+v_width;/g) !== -1) {
412412
vsDefines.push('WIDTH_VARYING');
413413
}
414414
} else {
@@ -455,7 +455,7 @@ define([
455455
var colorProgramMorph = context.shaderCache.getDerivedShaderProgram(groundPolylinePrimitive._sp, 'MorphColor');
456456
if (!defined(colorProgramMorph)) {
457457
var vsColorMorph = new ShaderSource({
458-
defines : vsDefines,
458+
defines : vsDefines.concat(['MAX_TERRAIN_HEIGHT ' + ApproximateTerrainHeights._defaultMaxTerrainHeight.toFixed(1)]),
459459
sources : [vsMorph]
460460
});
461461

Source/Shaders/PolylineShadowVolumeFS.glsl

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ varying vec4 v_color;
1010

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

1616
// Discard for sky

Source/Shaders/PolylineShadowVolumeMorphVS.glsl

+47-28
Original file line numberDiff line numberDiff line change
@@ -42,56 +42,64 @@ void main()
4242
vec4 posRelativeToEye2D = czm_translateRelativeToEye(vec3(0.0, startHiLo2D.xy), vec3(0.0, startHiLo2D.zw));
4343
vec4 posRelativeToEye3D = czm_translateRelativeToEye(startHiAndForwardOffsetX.xyz, startLoAndForwardOffsetY.xyz);
4444
vec4 posRelativeToEye = czm_columbusViewMorph(posRelativeToEye2D, posRelativeToEye3D, czm_morphTime);
45-
vec3 ecPos2D = (czm_modelViewRelativeToEye * posRelativeToEye2D).xyz;
46-
vec3 ecPos3D = (czm_modelViewRelativeToEye * posRelativeToEye3D).xyz;
47-
vec3 ecStart = (czm_modelViewRelativeToEye * posRelativeToEye).xyz;
45+
vec3 posEc2D = (czm_modelViewRelativeToEye * posRelativeToEye2D).xyz;
46+
vec3 posEc3D = (czm_modelViewRelativeToEye * posRelativeToEye3D).xyz;
47+
vec3 startEC = (czm_modelViewRelativeToEye * posRelativeToEye).xyz;
4848

4949
// Start plane
5050
vec4 startPlane2D;
5151
vec4 startPlane3D;
5252
startPlane2D.xyz = czm_normal * vec3(0.0, startEndNormals2D.xy);
5353
startPlane3D.xyz = czm_normal * startNormalAndForwardOffsetZ.xyz;
54-
startPlane2D.w = -dot(startPlane2D.xyz, ecPos2D);
55-
startPlane3D.w = -dot(startPlane3D.xyz, ecPos3D);
54+
startPlane2D.w = -dot(startPlane2D.xyz, posEc2D);
55+
startPlane3D.w = -dot(startPlane3D.xyz, posEc3D);
5656

5757
// Right plane
5858
vec4 rightPlane2D;
5959
vec4 rightPlane3D;
6060
rightPlane2D.xyz = czm_normal * vec3(0.0, offsetAndRight2D.zw);
6161
rightPlane3D.xyz = czm_normal * rightNormalAndTextureCoordinateNormalizationY.xyz;
62-
rightPlane2D.w = -dot(rightPlane2D.xyz, ecPos2D);
63-
rightPlane3D.w = -dot(rightPlane3D.xyz, ecPos3D);
62+
rightPlane2D.w = -dot(rightPlane2D.xyz, posEc2D);
63+
rightPlane3D.w = -dot(rightPlane3D.xyz, posEc3D);
6464

6565
// End position
6666
posRelativeToEye2D = posRelativeToEye2D + vec4(0.0, offsetAndRight2D.xy, 0.0);
6767
posRelativeToEye3D = posRelativeToEye3D + vec4(startHiAndForwardOffsetX.w, startLoAndForwardOffsetY.w, startNormalAndForwardOffsetZ.w, 0.0);
6868
posRelativeToEye = czm_columbusViewMorph(posRelativeToEye2D, posRelativeToEye3D, czm_morphTime);
69-
ecPos2D = (czm_modelViewRelativeToEye * posRelativeToEye2D).xyz;
70-
ecPos3D = (czm_modelViewRelativeToEye * posRelativeToEye3D).xyz;
71-
vec3 ecEnd = (czm_modelViewRelativeToEye * posRelativeToEye).xyz;
69+
posEc2D = (czm_modelViewRelativeToEye * posRelativeToEye2D).xyz;
70+
posEc3D = (czm_modelViewRelativeToEye * posRelativeToEye3D).xyz;
71+
vec3 endEC = (czm_modelViewRelativeToEye * posRelativeToEye).xyz;
72+
vec3 forwardEc3D = czm_normal * normalize(vec3(startHiAndForwardOffsetX.w, startLoAndForwardOffsetY.w, startNormalAndForwardOffsetZ.w));
73+
vec3 forwardEc2D = czm_normal * normalize(vec3(0.0, offsetAndRight2D.xy));
7274

7375
// End plane
7476
vec4 endPlane2D;
7577
vec4 endPlane3D;
7678
endPlane2D.xyz = czm_normal * vec3(0.0, startEndNormals2D.zw);
7779
endPlane3D.xyz = czm_normal * endNormalAndTextureCoordinateNormalizationX.xyz;
78-
endPlane2D.w = -dot(endPlane2D.xyz, ecPos2D);
79-
endPlane3D.w = -dot(endPlane3D.xyz, ecPos3D);
80+
endPlane2D.w = -dot(endPlane2D.xyz, posEc2D);
81+
endPlane3D.w = -dot(endPlane3D.xyz, posEc3D);
8082

8183
// Forward direction
82-
v_forwardDirectionEC = normalize(ecEnd - ecStart);
84+
v_forwardDirectionEC = normalize(endEC - startEC);
8385

84-
v_texcoordNormalization_and_halfWidth.xy = mix(
85-
vec2(abs(texcoordNormalization2D.x), texcoordNormalization2D.y),
86-
vec2(abs(endNormalAndTextureCoordinateNormalizationX.w), rightNormalAndTextureCoordinateNormalizationY.w), czm_morphTime);
86+
vec2 cleanTexcoordNormalization2D;
87+
cleanTexcoordNormalization2D.x = abs(texcoordNormalization2D.x);
88+
cleanTexcoordNormalization2D.y = czm_branchFreeTernary(texcoordNormalization2D.y > 1.0, 0.0, abs(texcoordNormalization2D.y));
89+
vec2 cleanTexcoordNormalization3D;
90+
cleanTexcoordNormalization3D.x = abs(endNormalAndTextureCoordinateNormalizationX.w);
91+
cleanTexcoordNormalization3D.y = rightNormalAndTextureCoordinateNormalizationY.w;
92+
cleanTexcoordNormalization3D.y = czm_branchFreeTernary(cleanTexcoordNormalization3D.y > 1.0, 0.0, abs(cleanTexcoordNormalization3D.y));
93+
94+
v_texcoordNormalization_and_halfWidth.xy = mix(cleanTexcoordNormalization2D, cleanTexcoordNormalization3D, czm_morphTime);
8795

8896
#ifdef PER_INSTANCE_COLOR
8997
v_color = czm_batchTable_color(batchId);
9098
#else // PER_INSTANCE_COLOR
9199
// For computing texture coordinates
92100

93-
v_alignedPlaneDistances.x = -dot(v_forwardDirectionEC, ecStart);
94-
v_alignedPlaneDistances.y = -dot(-v_forwardDirectionEC, ecEnd);
101+
v_alignedPlaneDistances.x = -dot(v_forwardDirectionEC, startEC);
102+
v_alignedPlaneDistances.y = -dot(-v_forwardDirectionEC, endEC);
95103
#endif // PER_INSTANCE_COLOR
96104

97105
#ifdef WIDTH_VARYING
@@ -111,29 +119,41 @@ void main()
111119

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

129+
// Nudge the top vertex upwards to prevent flickering
130+
vec3 geodeticSurfaceNormal = normalize(cross(normalEC, forwardEc3D));
131+
geodeticSurfaceNormal *= float(0.0 <= rightNormalAndTextureCoordinateNormalizationY.w && rightNormalAndTextureCoordinateNormalizationY.w <= 1.0);
132+
geodeticSurfaceNormal *= MAX_TERRAIN_HEIGHT;
133+
positionEc3D.xyz += geodeticSurfaceNormal;
134+
121135
// Determine if this vertex is on the "left" or "right"
122136
normalEC *= sign(endNormalAndTextureCoordinateNormalizationX.w);
123137

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

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

151+
// Nudge the top vertex upwards to prevent flickering
152+
geodeticSurfaceNormal = normalize(cross(normalEC, forwardEc2D));
153+
geodeticSurfaceNormal *= float(0.0 <= texcoordNormalization2D.y && texcoordNormalization2D.y <= 1.0);
154+
geodeticSurfaceNormal *= MAX_TERRAIN_HEIGHT;
155+
positionEc2D.xyz += geodeticSurfaceNormal;
156+
137157
// Determine if this vertex is on the "left" or "right"
138158
normalEC *= sign(texcoordNormalization2D.x);
139159
#ifndef PER_INSTANCE_COLOR
@@ -143,11 +163,10 @@ void main()
143163

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

149168
// Blend for actual position
150-
gl_Position = czm_projection * mix(positionEC2D, positionEC3D, czm_morphTime);
169+
gl_Position = czm_projection * mix(positionEc2D, positionEc3D, czm_morphTime);
151170

152171
#ifdef ANGLE_VARYING
153172
// Approximate relative screen space direction of the line.

0 commit comments

Comments
 (0)