@@ -42,56 +42,64 @@ void main()
42
42
vec4 posRelativeToEye2D = czm_translateRelativeToEye(vec3 (0.0 , startHiLo2D.xy), vec3 (0.0 , startHiLo2D.zw));
43
43
vec4 posRelativeToEye3D = czm_translateRelativeToEye(startHiAndForwardOffsetX.xyz, startLoAndForwardOffsetY.xyz);
44
44
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;
48
48
49
49
// Start plane
50
50
vec4 startPlane2D;
51
51
vec4 startPlane3D;
52
52
startPlane2D.xyz = czm_normal * vec3 (0.0 , startEndNormals2D.xy);
53
53
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 );
56
56
57
57
// Right plane
58
58
vec4 rightPlane2D;
59
59
vec4 rightPlane3D;
60
60
rightPlane2D.xyz = czm_normal * vec3 (0.0 , offsetAndRight2D.zw);
61
61
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 );
64
64
65
65
// End position
66
66
posRelativeToEye2D = posRelativeToEye2D + vec4 (0.0 , offsetAndRight2D.xy, 0.0 );
67
67
posRelativeToEye3D = posRelativeToEye3D + vec4 (startHiAndForwardOffsetX.w, startLoAndForwardOffsetY.w, startNormalAndForwardOffsetZ.w, 0.0 );
68
68
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));
72
74
73
75
// End plane
74
76
vec4 endPlane2D;
75
77
vec4 endPlane3D;
76
78
endPlane2D.xyz = czm_normal * vec3 (0.0 , startEndNormals2D.zw);
77
79
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 );
80
82
81
83
// Forward direction
82
- v_forwardDirectionEC = normalize (ecEnd - ecStart );
84
+ v_forwardDirectionEC = normalize (endEC - startEC );
83
85
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);
87
95
88
96
#ifdef PER_INSTANCE_COLOR
89
97
v_color = czm_batchTable_color(batchId);
90
98
#else // PER_INSTANCE_COLOR
91
99
// For computing texture coordinates
92
100
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 );
95
103
#endif // PER_INSTANCE_COLOR
96
104
97
105
#ifdef WIDTH_VARYING
@@ -111,29 +119,41 @@ void main()
111
119
112
120
// ****** 3D ******
113
121
// 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));
117
125
vec3 planeDirection = czm_branchFreeTernary(absStartPlaneDistance < absEndPlaneDistance, startPlane3D.xyz, endPlane3D.xyz);
118
126
vec3 upOrDown = normalize (cross (rightPlane3D.xyz, planeDirection)); // Points "up" for start plane, "down" at end plane.
119
127
vec3 normalEC = normalize (cross (planeDirection, upOrDown)); // In practice, the opposite seems to work too.
120
128
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
+
121
135
// Determine if this vertex is on the "left" or "right"
122
136
normalEC *= sign (endNormalAndTextureCoordinateNormalizationX.w);
123
137
124
138
// A "perfect" implementation would push along normals according to the angle against forward.
125
139
// 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)
127
141
128
142
// ****** 2D ******
129
143
// 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));
133
147
planeDirection = czm_branchFreeTernary(absStartPlaneDistance < absEndPlaneDistance, startPlane2D.xyz, endPlane2D.xyz);
134
148
upOrDown = normalize (cross (rightPlane2D.xyz, planeDirection)); // Points "up" for start plane, "down" at end plane.
135
149
normalEC = normalize (cross (planeDirection, upOrDown)); // In practice, the opposite seems to work too.
136
150
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
+
137
157
// Determine if this vertex is on the "left" or "right"
138
158
normalEC *= sign (texcoordNormalization2D.x);
139
159
#ifndef PER_INSTANCE_COLOR
@@ -143,11 +163,10 @@ void main()
143
163
144
164
// A "perfect" implementation would push along normals according to the angle against forward.
145
165
// 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)
148
167
149
168
// Blend for actual position
150
- gl_Position = czm_projection * mix (positionEC2D, positionEC3D , czm_morphTime);
169
+ gl_Position = czm_projection * mix (positionEc2D, positionEc3D , czm_morphTime);
151
170
152
171
#ifdef ANGLE_VARYING
153
172
// Approximate relative screen space direction of the line.
0 commit comments