deeptwins-cesium-engine 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Source/Core/defaultValue.js +20 -0
- package/Source/Shaders/BufferPointMaterialFS.js +30 -0
- package/Source/Shaders/BufferPointMaterialVS.js +60 -0
- package/Source/Shaders/BufferPolygonMaterialFS.js +15 -0
- package/Source/Shaders/BufferPolygonMaterialVS.js +41 -0
- package/Source/Shaders/BufferPolylineMaterialFS.js +15 -0
- package/Source/Shaders/BufferPolylineMaterialVS.js +65 -0
- package/Source/Shaders/CubeMapPanoramaVS.js +13 -0
- package/Source/Shaders/Model/ConstantLodStageFS.js +62 -0
- package/Source/Shaders/Model/ConstantLodStageVS.js +13 -0
- package/Source/Shaders/Model/EdgeDetectionStageFS.js +60 -0
- package/Source/Shaders/Model/EdgeVisibilityStageFS.js +70 -0
- package/Source/Shaders/Model/EdgeVisibilityStageVS.js +99 -0
- package/Source/Shaders/PrimitiveGaussianSplatFS.js +20 -0
- package/Source/Shaders/PrimitiveGaussianSplatVS.js +197 -0
- package/Source/Shaders/Voxels/IntersectPlane.js +82 -0
- package/Source/Shaders/Voxels/convertLocalToBoxUv.js +31 -0
- package/Source/Shaders/Voxels/convertLocalToCylinderUv.js +97 -0
- package/Source/Shaders/Voxels/convertLocalToEllipsoidUv.js +185 -0
- package/index.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the first parameter if it is defined, otherwise the second parameter.
|
|
3
|
+
*
|
|
4
|
+
* @param {*} a The object.
|
|
5
|
+
* @param {*} b The default value.
|
|
6
|
+
* @returns {*} Returns the first parameter if defined, otherwise the second parameter.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* param = Cesium.defaultValue(param, "default");
|
|
10
|
+
*/
|
|
11
|
+
function defaultValue(a, b) {
|
|
12
|
+
if (a !== undefined && a !== null) {
|
|
13
|
+
return a;
|
|
14
|
+
}
|
|
15
|
+
return b;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
defaultValue.EMPTY_OBJECT = Object.freeze({});
|
|
19
|
+
|
|
20
|
+
export default defaultValue;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
//This file is automatically rebuilt by the Cesium build process.
|
|
2
|
+
export default "in vec4 v_pickColor;\n\
|
|
3
|
+
in vec4 v_color;\n\
|
|
4
|
+
in vec4 v_outlineColor;\n\
|
|
5
|
+
in float v_innerRadiusFrac;\n\
|
|
6
|
+
\n\
|
|
7
|
+
void main()\n\
|
|
8
|
+
{\n\
|
|
9
|
+
// Distance between fragment and point center, 0 to 0.5.\n\
|
|
10
|
+
float distanceToCenter = length(gl_PointCoord - vec2(0.5));\n\
|
|
11
|
+
float delta = fwidth(distanceToCenter);\n\
|
|
12
|
+
\n\
|
|
13
|
+
float outerLimit = 0.5;\n\
|
|
14
|
+
float innerLimit = 0.5 * v_innerRadiusFrac;\n\
|
|
15
|
+
\n\
|
|
16
|
+
float outerAlpha = 1.0 - smoothstep(max(0.0, outerLimit - delta), outerLimit, distanceToCenter);\n\
|
|
17
|
+
float innerAlpha = 1.0 - smoothstep(innerLimit - delta, innerLimit, distanceToCenter);\n\
|
|
18
|
+
\n\
|
|
19
|
+
vec4 color = vec4(mix(v_outlineColor.rgb, v_color.rgb, innerAlpha), outerAlpha);\n\
|
|
20
|
+
color.a *= mix(v_outlineColor.a, v_color.a, innerAlpha);\n\
|
|
21
|
+
\n\
|
|
22
|
+
if (color.a < 0.005) // matches 0/255 and 1/255\n\
|
|
23
|
+
{\n\
|
|
24
|
+
discard;\n\
|
|
25
|
+
}\n\
|
|
26
|
+
\n\
|
|
27
|
+
out_FragColor = czm_gammaCorrect(color);\n\
|
|
28
|
+
czm_writeLogDepth();\n\
|
|
29
|
+
}\n\
|
|
30
|
+
";
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
//This file is automatically rebuilt by the Cesium build process.
|
|
2
|
+
export default "#ifdef USE_FLOAT64\n\
|
|
3
|
+
in vec3 positionHigh;\n\
|
|
4
|
+
in vec3 positionLow;\n\
|
|
5
|
+
#else\n\
|
|
6
|
+
in vec3 position;\n\
|
|
7
|
+
#endif\n\
|
|
8
|
+
in vec4 pickColor;\n\
|
|
9
|
+
in vec4 showPixelSizeColorAlpha;\n\
|
|
10
|
+
in vec3 outlineWidthColorAlpha;\n\
|
|
11
|
+
\n\
|
|
12
|
+
out vec4 v_pickColor;\n\
|
|
13
|
+
out vec4 v_color;\n\
|
|
14
|
+
out vec4 v_outlineColor;\n\
|
|
15
|
+
out float v_innerRadiusFrac;\n\
|
|
16
|
+
\n\
|
|
17
|
+
void main()\n\
|
|
18
|
+
{\n\
|
|
19
|
+
// Unpack attributes.\n\
|
|
20
|
+
float show = showPixelSizeColorAlpha.x;\n\
|
|
21
|
+
float pixelSize = showPixelSizeColorAlpha.y;\n\
|
|
22
|
+
vec4 color = czm_decodeRGB8(showPixelSizeColorAlpha.z);\n\
|
|
23
|
+
float alpha = showPixelSizeColorAlpha.w;\n\
|
|
24
|
+
float outlineWidth = outlineWidthColorAlpha.x;\n\
|
|
25
|
+
vec4 outlineColor = czm_decodeRGB8(outlineWidthColorAlpha.y);\n\
|
|
26
|
+
float outlineAlpha = outlineWidthColorAlpha.z;\n\
|
|
27
|
+
\n\
|
|
28
|
+
///////////////////////////////////////////////////////////////////////////\n\
|
|
29
|
+
\n\
|
|
30
|
+
float innerRadius = 0.5 * pixelSize * czm_pixelRatio;\n\
|
|
31
|
+
float outerRadius = (0.5 * pixelSize + outlineWidth) * czm_pixelRatio;\n\
|
|
32
|
+
\n\
|
|
33
|
+
///////////////////////////////////////////////////////////////////////////\n\
|
|
34
|
+
\n\
|
|
35
|
+
#ifdef USE_FLOAT64\n\
|
|
36
|
+
vec4 p = czm_translateRelativeToEye(positionHigh, positionLow);\n\
|
|
37
|
+
vec4 positionEC = czm_modelViewRelativeToEye * p;\n\
|
|
38
|
+
#else\n\
|
|
39
|
+
vec4 positionEC = czm_modelView * vec4(position, 1.0);\n\
|
|
40
|
+
#endif\n\
|
|
41
|
+
\n\
|
|
42
|
+
///////////////////////////////////////////////////////////////////////////\n\
|
|
43
|
+
\n\
|
|
44
|
+
gl_Position = czm_projection * positionEC;\n\
|
|
45
|
+
czm_vertexLogDepth();\n\
|
|
46
|
+
\n\
|
|
47
|
+
v_pickColor = pickColor / 255.0;\n\
|
|
48
|
+
\n\
|
|
49
|
+
v_color = color;\n\
|
|
50
|
+
v_color.a *= alpha * show;\n\
|
|
51
|
+
\n\
|
|
52
|
+
v_outlineColor = outlineColor;\n\
|
|
53
|
+
v_outlineColor.a *= outlineAlpha * show;\n\
|
|
54
|
+
\n\
|
|
55
|
+
v_innerRadiusFrac = innerRadius / outerRadius;\n\
|
|
56
|
+
\n\
|
|
57
|
+
gl_PointSize = 2.0 * outerRadius * show;\n\
|
|
58
|
+
gl_Position *= show;\n\
|
|
59
|
+
}\n\
|
|
60
|
+
";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//This file is automatically rebuilt by the Cesium build process.
|
|
2
|
+
export default "in vec4 v_pickColor;\n\
|
|
3
|
+
in vec4 v_color;\n\
|
|
4
|
+
\n\
|
|
5
|
+
void main()\n\
|
|
6
|
+
{\n\
|
|
7
|
+
if (v_color.a < 0.005) // matches 0/255 and 1/255\n\
|
|
8
|
+
{\n\
|
|
9
|
+
discard;\n\
|
|
10
|
+
}\n\
|
|
11
|
+
\n\
|
|
12
|
+
out_FragColor = czm_gammaCorrect(v_color);\n\
|
|
13
|
+
czm_writeLogDepth();\n\
|
|
14
|
+
}\n\
|
|
15
|
+
";
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
//This file is automatically rebuilt by the Cesium build process.
|
|
2
|
+
export default "#ifdef USE_FLOAT64\n\
|
|
3
|
+
in vec3 positionHigh;\n\
|
|
4
|
+
in vec3 positionLow;\n\
|
|
5
|
+
#else\n\
|
|
6
|
+
in vec3 position;\n\
|
|
7
|
+
#endif\n\
|
|
8
|
+
in vec4 pickColor;\n\
|
|
9
|
+
in vec3 showColorAlpha;\n\
|
|
10
|
+
\n\
|
|
11
|
+
out vec4 v_pickColor;\n\
|
|
12
|
+
out vec4 v_color;\n\
|
|
13
|
+
\n\
|
|
14
|
+
void main()\n\
|
|
15
|
+
{\n\
|
|
16
|
+
float show = showColorAlpha.x;\n\
|
|
17
|
+
vec4 color = czm_decodeRGB8(showColorAlpha.y);\n\
|
|
18
|
+
float alpha = showColorAlpha.z;\n\
|
|
19
|
+
\n\
|
|
20
|
+
///////////////////////////////////////////////////////////////////////////\n\
|
|
21
|
+
\n\
|
|
22
|
+
#ifdef USE_FLOAT64\n\
|
|
23
|
+
vec4 p = czm_translateRelativeToEye(positionHigh, positionLow);\n\
|
|
24
|
+
vec4 positionEC = czm_modelViewRelativeToEye * p;\n\
|
|
25
|
+
#else\n\
|
|
26
|
+
vec4 positionEC = czm_modelView * vec4(position, 1.0);\n\
|
|
27
|
+
#endif\n\
|
|
28
|
+
\n\
|
|
29
|
+
///////////////////////////////////////////////////////////////////////////\n\
|
|
30
|
+
\n\
|
|
31
|
+
gl_Position = czm_projection * positionEC;\n\
|
|
32
|
+
czm_vertexLogDepth();\n\
|
|
33
|
+
\n\
|
|
34
|
+
v_pickColor = pickColor / 255.0;\n\
|
|
35
|
+
\n\
|
|
36
|
+
v_color = color;\n\
|
|
37
|
+
v_color.a *= alpha * show;\n\
|
|
38
|
+
\n\
|
|
39
|
+
gl_Position *= show;\n\
|
|
40
|
+
}\n\
|
|
41
|
+
";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//This file is automatically rebuilt by the Cesium build process.
|
|
2
|
+
export default "in vec4 v_pickColor;\n\
|
|
3
|
+
in vec4 v_color;\n\
|
|
4
|
+
\n\
|
|
5
|
+
void main()\n\
|
|
6
|
+
{\n\
|
|
7
|
+
if (v_color.a < 0.005) // matches 0/255 and 1/255\n\
|
|
8
|
+
{\n\
|
|
9
|
+
discard;\n\
|
|
10
|
+
}\n\
|
|
11
|
+
\n\
|
|
12
|
+
out_FragColor = czm_gammaCorrect(v_color);\n\
|
|
13
|
+
czm_writeLogDepth();\n\
|
|
14
|
+
}\n\
|
|
15
|
+
";
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
//This file is automatically rebuilt by the Cesium build process.
|
|
2
|
+
export default "#ifdef USE_FLOAT64\n\
|
|
3
|
+
in vec3 positionHigh;\n\
|
|
4
|
+
in vec3 positionLow;\n\
|
|
5
|
+
in vec3 prevPositionHigh;\n\
|
|
6
|
+
in vec3 prevPositionLow;\n\
|
|
7
|
+
in vec3 nextPositionHigh;\n\
|
|
8
|
+
in vec3 nextPositionLow;\n\
|
|
9
|
+
#else\n\
|
|
10
|
+
in vec3 position;\n\
|
|
11
|
+
in vec3 prevPosition;\n\
|
|
12
|
+
in vec3 nextPosition;\n\
|
|
13
|
+
#endif\n\
|
|
14
|
+
in vec4 pickColor;\n\
|
|
15
|
+
in vec4 showColorWidthAndTexCoord;\n\
|
|
16
|
+
in float alpha;\n\
|
|
17
|
+
\n\
|
|
18
|
+
out vec4 v_pickColor;\n\
|
|
19
|
+
out vec4 v_color;\n\
|
|
20
|
+
out vec2 v_st;\n\
|
|
21
|
+
out float v_width;\n\
|
|
22
|
+
out float v_polylineAngle;\n\
|
|
23
|
+
\n\
|
|
24
|
+
void main()\n\
|
|
25
|
+
{\n\
|
|
26
|
+
float show = showColorWidthAndTexCoord.x;\n\
|
|
27
|
+
vec4 color = czm_decodeRGB8(showColorWidthAndTexCoord.y);\n\
|
|
28
|
+
float width = showColorWidthAndTexCoord.z;\n\
|
|
29
|
+
float texCoord = showColorWidthAndTexCoord.w;\n\
|
|
30
|
+
\n\
|
|
31
|
+
///////////////////////////////////////////////////////////////////////////\n\
|
|
32
|
+
\n\
|
|
33
|
+
bool usePrevious = texCoord == 1.0;\n\
|
|
34
|
+
float expandDir = gl_VertexID % 2 == 1 ? 1.0 : -1.0;\n\
|
|
35
|
+
float polylineAngle;\n\
|
|
36
|
+
\n\
|
|
37
|
+
#ifdef USE_FLOAT64\n\
|
|
38
|
+
vec4 positionEC = czm_translateRelativeToEye(positionHigh, positionLow);\n\
|
|
39
|
+
vec4 prevPositionEC = czm_translateRelativeToEye(prevPositionHigh, prevPositionLow);\n\
|
|
40
|
+
vec4 nextPositionEC = czm_translateRelativeToEye(nextPositionHigh, nextPositionLow);\n\
|
|
41
|
+
vec4 positionWC = getPolylineWindowCoordinates(positionEC, prevPositionEC, nextPositionEC, expandDir, width, usePrevious, polylineAngle);\n\
|
|
42
|
+
#else\n\
|
|
43
|
+
vec4 positionEC = czm_modelView * vec4(position, 1.0);\n\
|
|
44
|
+
vec4 prevPositionEC = czm_modelView * vec4(prevPosition, 1.0);\n\
|
|
45
|
+
vec4 nextPositionEC = czm_modelView * vec4(nextPosition, 1.0);\n\
|
|
46
|
+
// Positions are already in eye space; use the EC variant to skip the redundant transform.\n\
|
|
47
|
+
vec4 positionWC = getPolylineWindowCoordinatesEC(positionEC, prevPositionEC, nextPositionEC, expandDir, width, usePrevious, polylineAngle);\n\
|
|
48
|
+
#endif\n\
|
|
49
|
+
\n\
|
|
50
|
+
///////////////////////////////////////////////////////////////////////////\n\
|
|
51
|
+
\n\
|
|
52
|
+
gl_Position = czm_viewportOrthographic * positionWC * show;\n\
|
|
53
|
+
\n\
|
|
54
|
+
v_pickColor = pickColor / 255.0;\n\
|
|
55
|
+
\n\
|
|
56
|
+
v_color = color;\n\
|
|
57
|
+
v_color.a *= alpha / 255.0 * show;\n\
|
|
58
|
+
\n\
|
|
59
|
+
v_st.s = texCoord;\n\
|
|
60
|
+
v_st.t = czm_writeNonPerspective(clamp(expandDir, 0.0, 1.0), gl_Position.w);\n\
|
|
61
|
+
\n\
|
|
62
|
+
v_width = width;\n\
|
|
63
|
+
v_polylineAngle = polylineAngle;\n\
|
|
64
|
+
}\n\
|
|
65
|
+
";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//This file is automatically rebuilt by the Cesium build process.
|
|
2
|
+
export default "uniform mat3 u_cubeMapPanoramaTransform;\n\
|
|
3
|
+
\n\
|
|
4
|
+
in vec3 position;\n\
|
|
5
|
+
out vec3 v_texCoord;\n\
|
|
6
|
+
\n\
|
|
7
|
+
void main()\n\
|
|
8
|
+
{\n\
|
|
9
|
+
vec3 p = czm_viewRotation * (u_cubeMapPanoramaTransform * (czm_entireFrustum.y * position));\n\
|
|
10
|
+
gl_Position = czm_projection * vec4(p, 1.0);\n\
|
|
11
|
+
v_texCoord = position.xyz;\n\
|
|
12
|
+
}\n\
|
|
13
|
+
";
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
//This file is automatically rebuilt by the Cesium build process.
|
|
2
|
+
export default "#ifdef HAS_CONSTANT_LOD\n\
|
|
3
|
+
\n\
|
|
4
|
+
vec4 constantLodTextureLookup(sampler2D textureSampler, vec3 constantLodParams) {\n\
|
|
5
|
+
bool atMaxClamp = v_constantLodUvCustom.z >= constantLodParams.y;\n\
|
|
6
|
+
bool atMinClamp = v_constantLodUvCustom.z <= constantLodParams.x;\n\
|
|
7
|
+
bool atClampBoundary = atMaxClamp || atMinClamp;\n\
|
|
8
|
+
\n\
|
|
9
|
+
float effectiveDistance = atMaxClamp ? constantLodParams.y : \n\
|
|
10
|
+
(atMinClamp ? constantLodParams.x : v_constantLodUvCustom.z);\n\
|
|
11
|
+
\n\
|
|
12
|
+
float logDepth = log2(effectiveDistance);\n\
|
|
13
|
+
logDepth = clamp(logDepth, -10.0, 20.0);\n\
|
|
14
|
+
\n\
|
|
15
|
+
float f = fract(logDepth);\n\
|
|
16
|
+
float p = floor(logDepth);\n\
|
|
17
|
+
\n\
|
|
18
|
+
if (atClampBoundary) {\n\
|
|
19
|
+
float clampedP = ceil(logDepth);\n\
|
|
20
|
+
vec2 tc = v_constantLodUvCustom.xy / pow(2.0, clampedP) * constantLodParams.z;\n\
|
|
21
|
+
return texture(textureSampler, tc);\n\
|
|
22
|
+
}\n\
|
|
23
|
+
\n\
|
|
24
|
+
vec2 tc1 = v_constantLodUvCustom.xy / pow(2.0, p) * constantLodParams.z;\n\
|
|
25
|
+
vec2 tc2 = v_constantLodUvCustom.xy / pow(2.0, p + 1.0) * constantLodParams.z;\n\
|
|
26
|
+
return mix(texture(textureSampler, tc1), texture(textureSampler, tc2), f);\n\
|
|
27
|
+
}\n\
|
|
28
|
+
\n\
|
|
29
|
+
vec4 constantLodTextureLookup(sampler2D textureSampler, vec3 constantLodParams, mat3 textureTransform) {\n\
|
|
30
|
+
bool atMaxClamp = v_constantLodUvCustom.z >= constantLodParams.y;\n\
|
|
31
|
+
bool atMinClamp = v_constantLodUvCustom.z <= constantLodParams.x;\n\
|
|
32
|
+
bool atClampBoundary = atMaxClamp || atMinClamp;\n\
|
|
33
|
+
\n\
|
|
34
|
+
float effectiveDistance = atMaxClamp ? constantLodParams.y : \n\
|
|
35
|
+
(atMinClamp ? constantLodParams.x : v_constantLodUvCustom.z);\n\
|
|
36
|
+
\n\
|
|
37
|
+
float logDepth = log2(effectiveDistance);\n\
|
|
38
|
+
logDepth = clamp(logDepth, -10.0, 20.0);\n\
|
|
39
|
+
\n\
|
|
40
|
+
float f = fract(logDepth);\n\
|
|
41
|
+
float p = floor(logDepth);\n\
|
|
42
|
+
\n\
|
|
43
|
+
if (atClampBoundary) {\n\
|
|
44
|
+
float clampedP = ceil(logDepth);\n\
|
|
45
|
+
vec2 tc = v_constantLodUvCustom.xy / pow(2.0, clampedP) * constantLodParams.z;\n\
|
|
46
|
+
// Apply texture transform to the final texture coordinates\n\
|
|
47
|
+
tc = czm_computeTextureTransform(tc, textureTransform);\n\
|
|
48
|
+
return texture(textureSampler, tc);\n\
|
|
49
|
+
}\n\
|
|
50
|
+
\n\
|
|
51
|
+
vec2 tc1 = v_constantLodUvCustom.xy / pow(2.0, p) * constantLodParams.z;\n\
|
|
52
|
+
vec2 tc2 = v_constantLodUvCustom.xy / pow(2.0, p + 1.0) * constantLodParams.z;\n\
|
|
53
|
+
\n\
|
|
54
|
+
// Apply texture transform to both LOD texture coordinates before mixing\n\
|
|
55
|
+
tc1 = czm_computeTextureTransform(tc1, textureTransform);\n\
|
|
56
|
+
tc2 = czm_computeTextureTransform(tc2, textureTransform);\n\
|
|
57
|
+
\n\
|
|
58
|
+
return mix(texture(textureSampler, tc1), texture(textureSampler, tc2), f);\n\
|
|
59
|
+
}\n\
|
|
60
|
+
\n\
|
|
61
|
+
#endif\n\
|
|
62
|
+
";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//This file is automatically rebuilt by the Cesium build process.
|
|
2
|
+
export default "#ifdef HAS_CONSTANT_LOD\n\
|
|
3
|
+
// Extract model scale to compensate for minimumPixelSize scaling\n\
|
|
4
|
+
float modelScaleX = length(czm_model[0].xyz);\n\
|
|
5
|
+
float modelScaleY = length(czm_model[1].xyz);\n\
|
|
6
|
+
float modelScaleZ = length(czm_model[2].xyz);\n\
|
|
7
|
+
float modelScale = (modelScaleX + modelScaleY + modelScaleZ) / 3.0;\n\
|
|
8
|
+
\n\
|
|
9
|
+
// Transform model position through ENU but as direction only (w=0) to avoid position-dependent rotation\n\
|
|
10
|
+
vec3 enuDir = (u_constantLodWorldToEnu * czm_model * vec4(v_positionMC, 0.0)).xyz;\n\
|
|
11
|
+
v_constantLodUvCustom.xy = (enuDir.yx + u_constantLodOffset) / modelScale;\n\
|
|
12
|
+
v_constantLodUvCustom.z = u_constantLodDistance / modelScale;\n\
|
|
13
|
+
#endif";
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
//This file is automatically rebuilt by the Cesium build process.
|
|
2
|
+
export default "void edgeDetectionStage(inout vec4 color, inout FeatureIds featureIds) {\n\
|
|
3
|
+
if (u_isEdgePass) {\n\
|
|
4
|
+
return;\n\
|
|
5
|
+
}\n\
|
|
6
|
+
\n\
|
|
7
|
+
vec2 screenCoord = gl_FragCoord.xy / czm_viewport.zw;\n\
|
|
8
|
+
\n\
|
|
9
|
+
vec4 edgeColor = texture(czm_edgeColorTexture, screenCoord);\n\
|
|
10
|
+
vec4 edgeId = texture(czm_edgeIdTexture, screenCoord);\n\
|
|
11
|
+
\n\
|
|
12
|
+
// Packed window-space depth from edge pass (0..1)\n\
|
|
13
|
+
float edgeDepthWin = czm_unpackDepth(texture(czm_edgeDepthTexture, screenCoord));\n\
|
|
14
|
+
\n\
|
|
15
|
+
// Near / far for current frustum\n\
|
|
16
|
+
float n = czm_currentFrustum.x;\n\
|
|
17
|
+
float f = czm_currentFrustum.y;\n\
|
|
18
|
+
\n\
|
|
19
|
+
// geometry depth in eye coordinate\n\
|
|
20
|
+
vec4 geomEC = czm_windowToEyeCoordinates(gl_FragCoord);\n\
|
|
21
|
+
float geomDepthLinear = -geomEC.z;\n\
|
|
22
|
+
\n\
|
|
23
|
+
// Convert edge depth to linear depth\n\
|
|
24
|
+
float z_ndc_edge = edgeDepthWin * 2.0 - 1.0;\n\
|
|
25
|
+
float edgeDepthLinear = (2.0 * n * f) / (f + n - z_ndc_edge * (f - n));\n\
|
|
26
|
+
\n\
|
|
27
|
+
float d = abs(edgeDepthLinear - geomDepthLinear);\n\
|
|
28
|
+
\n\
|
|
29
|
+
// Adaptive epsilon using linear depth fwidth for robustness\n\
|
|
30
|
+
float pixelStepLinear = fwidth(geomDepthLinear);\n\
|
|
31
|
+
float rel = geomDepthLinear * 0.0005;\n\
|
|
32
|
+
float eps = max(n * 1e-4, max(pixelStepLinear * 1.5, rel));\n\
|
|
33
|
+
\n\
|
|
34
|
+
// If Edge isn't behind any geometry and the pixel has edge data\n\
|
|
35
|
+
if (d < eps && edgeId.r > 0.0) {\n\
|
|
36
|
+
#ifdef HAS_EDGE_FEATURE_ID\n\
|
|
37
|
+
float edgeFeatureId = edgeId.g;\n\
|
|
38
|
+
float currentFeatureId = float(featureIds.featureId_0);\n\
|
|
39
|
+
#endif\n\
|
|
40
|
+
float globeDepth = czm_unpackDepth(texture(czm_globeDepthTexture, screenCoord));\n\
|
|
41
|
+
// Background / sky / globe: always show edge\n\
|
|
42
|
+
bool isBackground = geomDepthLinear > globeDepth;\n\
|
|
43
|
+
bool drawEdge = isBackground;\n\
|
|
44
|
+
\n\
|
|
45
|
+
#ifdef HAS_EDGE_FEATURE_ID\n\
|
|
46
|
+
bool hasEdgeFeature = edgeFeatureId > 0.0;\n\
|
|
47
|
+
bool hasCurrentFeature = currentFeatureId > 0.0;\n\
|
|
48
|
+
bool featuresMatch = edgeFeatureId == currentFeatureId;\n\
|
|
49
|
+
\n\
|
|
50
|
+
drawEdge = drawEdge || !hasEdgeFeature || !hasCurrentFeature || featuresMatch;\n\
|
|
51
|
+
#else\n\
|
|
52
|
+
drawEdge = true;\n\
|
|
53
|
+
#endif\n\
|
|
54
|
+
\n\
|
|
55
|
+
if (drawEdge) {\n\
|
|
56
|
+
color = edgeColor;\n\
|
|
57
|
+
}\n\
|
|
58
|
+
}\n\
|
|
59
|
+
}\n\
|
|
60
|
+
";
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
//This file is automatically rebuilt by the Cesium build process.
|
|
2
|
+
export default "// CESIUM_REDIRECTED_COLOR_OUTPUT flag is used to avoid color attachment conflicts\n\
|
|
3
|
+
// when shaders are processed by different rendering pipelines (e.g., OIT).\n\
|
|
4
|
+
// Only declare MRT outputs when not in a derived shader context.\n\
|
|
5
|
+
#if defined(HAS_EDGE_VISIBILITY_MRT) && !defined(CESIUM_REDIRECTED_COLOR_OUTPUT)\n\
|
|
6
|
+
layout(location = 1) out vec4 out_id; // edge id / metadata\n\
|
|
7
|
+
layout(location = 2) out vec4 out_edgeDepth; // packed depth\n\
|
|
8
|
+
#endif\n\
|
|
9
|
+
\n\
|
|
10
|
+
void edgeVisibilityStage(inout vec4 color, inout FeatureIds featureIds)\n\
|
|
11
|
+
{\n\
|
|
12
|
+
#ifdef HAS_EDGE_VISIBILITY\n\
|
|
13
|
+
\n\
|
|
14
|
+
if (!u_isEdgePass) {\n\
|
|
15
|
+
return;\n\
|
|
16
|
+
}\n\
|
|
17
|
+
\n\
|
|
18
|
+
float edgeTypeInt = v_edgeType * 255.0;\n\
|
|
19
|
+
\n\
|
|
20
|
+
if (edgeTypeInt < 0.5) {\n\
|
|
21
|
+
discard;\n\
|
|
22
|
+
}\n\
|
|
23
|
+
\n\
|
|
24
|
+
if (edgeTypeInt > 0.5 && edgeTypeInt < 1.5) { // silhouette candidate\n\
|
|
25
|
+
// Silhouette check done in vertex shader\n\
|
|
26
|
+
// v_shouldDiscard will be > 0.5 if this edge should be discarded\n\
|
|
27
|
+
if (v_shouldDiscard > 0.5) {\n\
|
|
28
|
+
discard;\n\
|
|
29
|
+
}\n\
|
|
30
|
+
}\n\
|
|
31
|
+
\n\
|
|
32
|
+
vec4 finalColor = color;\n\
|
|
33
|
+
#ifdef HAS_EDGE_COLOR_ATTRIBUTE\n\
|
|
34
|
+
if (v_edgeColor.a >= 0.0) {\n\
|
|
35
|
+
finalColor = v_edgeColor;\n\
|
|
36
|
+
}\n\
|
|
37
|
+
#endif\n\
|
|
38
|
+
\n\
|
|
39
|
+
#ifdef HAS_LINE_PATTERN\n\
|
|
40
|
+
// Pattern is 16-bit, each bit represents visibility at that position\n\
|
|
41
|
+
const float maskLength = 16.0;\n\
|
|
42
|
+
\n\
|
|
43
|
+
// Get the relative position within the dash from 0 to 1\n\
|
|
44
|
+
float dashPosition = fract(v_lineCoord / maskLength);\n\
|
|
45
|
+
// Figure out the mask index\n\
|
|
46
|
+
float maskIndex = floor(dashPosition * maskLength);\n\
|
|
47
|
+
// Test the bit mask\n\
|
|
48
|
+
float maskTest = floor(u_linePattern / pow(2.0, maskIndex));\n\
|
|
49
|
+
\n\
|
|
50
|
+
// If bit is 0 (gap), discard the fragment (use < 1.0 for better numerical stability)\n\
|
|
51
|
+
if (mod(maskTest, 2.0) < 1.0) {\n\
|
|
52
|
+
discard;\n\
|
|
53
|
+
}\n\
|
|
54
|
+
#endif\n\
|
|
55
|
+
color = finalColor;\n\
|
|
56
|
+
\n\
|
|
57
|
+
#if defined(HAS_EDGE_VISIBILITY_MRT) && !defined(CESIUM_REDIRECTED_COLOR_OUTPUT)\n\
|
|
58
|
+
// Write edge metadata\n\
|
|
59
|
+
out_id = vec4(0.0);\n\
|
|
60
|
+
out_id.r = edgeTypeInt; // Edge type (0-3)\n\
|
|
61
|
+
#ifdef HAS_EDGE_FEATURE_ID\n\
|
|
62
|
+
out_id.g = float(featureIds.featureId_0); // Feature ID if available\n\
|
|
63
|
+
#else\n\
|
|
64
|
+
out_id.g = 0.0;\n\
|
|
65
|
+
#endif\n\
|
|
66
|
+
// Pack depth into separate MRT attachment\n\
|
|
67
|
+
out_edgeDepth = czm_packDepth(gl_FragCoord.z);\n\
|
|
68
|
+
#endif\n\
|
|
69
|
+
#endif\n\
|
|
70
|
+
}";
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
//This file is automatically rebuilt by the Cesium build process.
|
|
2
|
+
export default "#ifdef HAS_EDGE_VISIBILITY\n\
|
|
3
|
+
void edgeVisibilityStageVS() {\n\
|
|
4
|
+
if (!u_isEdgePass) {\n\
|
|
5
|
+
return;\n\
|
|
6
|
+
}\n\
|
|
7
|
+
\n\
|
|
8
|
+
v_edgeType = a_edgeType;\n\
|
|
9
|
+
v_faceNormalAView = czm_normal * a_faceNormalA;\n\
|
|
10
|
+
v_faceNormalBView = czm_normal * a_faceNormalB;\n\
|
|
11
|
+
v_edgeOffset = a_edgeOffset;\n\
|
|
12
|
+
\n\
|
|
13
|
+
// Silhouette detection: check both endpoints of the edge\n\
|
|
14
|
+
v_shouldDiscard = 0.0;\n\
|
|
15
|
+
float edgeTypeInt = a_edgeType * 255.0;\n\
|
|
16
|
+
if (edgeTypeInt > 0.5 && edgeTypeInt < 1.5) {\n\
|
|
17
|
+
vec3 normalA = normalize(v_faceNormalAView);\n\
|
|
18
|
+
vec3 normalB = normalize(v_faceNormalBView);\n\
|
|
19
|
+
const float perpTol = 2.5e-4;\n\
|
|
20
|
+
\n\
|
|
21
|
+
// Check at current vertex (first endpoint)\n\
|
|
22
|
+
vec4 currentPosEC = czm_modelView * vec4(v_positionMC, 1.0);\n\
|
|
23
|
+
vec3 toEye1 = normalize(-currentPosEC.xyz);\n\
|
|
24
|
+
float dotA1 = dot(normalA, toEye1);\n\
|
|
25
|
+
float dotB1 = dot(normalB, toEye1);\n\
|
|
26
|
+
\n\
|
|
27
|
+
// Check at other vertex (second endpoint)\n\
|
|
28
|
+
vec4 otherPosEC = czm_modelView * vec4(a_edgeOtherPos, 1.0);\n\
|
|
29
|
+
vec3 toEye2 = normalize(-otherPosEC.xyz);\n\
|
|
30
|
+
float dotA2 = dot(normalA, toEye2);\n\
|
|
31
|
+
float dotB2 = dot(normalB, toEye2);\n\
|
|
32
|
+
\n\
|
|
33
|
+
// Discard if EITHER endpoint is non-silhouette\n\
|
|
34
|
+
if (dotA1 * dotB1 > perpTol || dotA2 * dotB2 > perpTol) {\n\
|
|
35
|
+
v_shouldDiscard = 1.0;\n\
|
|
36
|
+
}\n\
|
|
37
|
+
}\n\
|
|
38
|
+
\n\
|
|
39
|
+
#ifdef HAS_EDGE_FEATURE_ID\n\
|
|
40
|
+
v_featureId_0 = a_edgeFeatureId;\n\
|
|
41
|
+
#endif\n\
|
|
42
|
+
\n\
|
|
43
|
+
#ifdef HAS_EDGE_COLOR_ATTRIBUTE\n\
|
|
44
|
+
v_edgeColor = a_edgeColor;\n\
|
|
45
|
+
#endif\n\
|
|
46
|
+
\n\
|
|
47
|
+
#ifdef HAS_LINE_PATTERN\n\
|
|
48
|
+
#ifdef HAS_EDGE_CUMULATIVE_DISTANCE\n\
|
|
49
|
+
v_lineCoord = a_edgeCumulativeDistance * u_pixelsPerWorld;\n\
|
|
50
|
+
#else\n\
|
|
51
|
+
vec4 currentClip = czm_modelViewProjection * vec4(v_positionMC, 1.0);\n\
|
|
52
|
+
vec2 currentScreen = ((currentClip.xy / currentClip.w) * 0.5 + 0.5) * czm_viewport.zw;\n\
|
|
53
|
+
\n\
|
|
54
|
+
vec4 otherClip = czm_modelViewProjection * vec4(a_edgeOtherPos, 1.0);\n\
|
|
55
|
+
vec2 otherScreen = ((otherClip.xy / otherClip.w) * 0.5 + 0.5) * czm_viewport.zw;\n\
|
|
56
|
+
vec2 windowDir = otherScreen - currentScreen;\n\
|
|
57
|
+
\n\
|
|
58
|
+
const float textureCoordinateBase = 8192.0;\n\
|
|
59
|
+
if (abs(windowDir.x) > abs(windowDir.y)) {\n\
|
|
60
|
+
v_lineCoord = textureCoordinateBase + currentScreen.x;\n\
|
|
61
|
+
} else {\n\
|
|
62
|
+
v_lineCoord = textureCoordinateBase + currentScreen.y;\n\
|
|
63
|
+
}\n\
|
|
64
|
+
#endif\n\
|
|
65
|
+
#endif\n\
|
|
66
|
+
\n\
|
|
67
|
+
// Expand vertex to form quad\n\
|
|
68
|
+
vec4 posClip = gl_Position;\n\
|
|
69
|
+
\n\
|
|
70
|
+
if (length(a_edgeOtherPos) > 0.0 && abs(a_edgeOffset) > 0.0) {\n\
|
|
71
|
+
vec4 currentClip = posClip;\n\
|
|
72
|
+
vec4 otherClip = czm_modelViewProjection * vec4(a_edgeOtherPos, 1.0);\n\
|
|
73
|
+
\n\
|
|
74
|
+
vec2 currentNDC = currentClip.xy / currentClip.w;\n\
|
|
75
|
+
vec2 otherNDC = otherClip.xy / otherClip.w;\n\
|
|
76
|
+
\n\
|
|
77
|
+
vec2 edgeDirNDC = otherNDC - currentNDC;\n\
|
|
78
|
+
\n\
|
|
79
|
+
// Ensure consistent edge direction\n\
|
|
80
|
+
if (edgeDirNDC.x < 0.0 || (abs(edgeDirNDC.x) < 0.001 && edgeDirNDC.y < 0.0)) {\n\
|
|
81
|
+
edgeDirNDC = -edgeDirNDC;\n\
|
|
82
|
+
}\n\
|
|
83
|
+
\n\
|
|
84
|
+
edgeDirNDC = normalize(edgeDirNDC);\n\
|
|
85
|
+
vec2 perpNDC = vec2(-edgeDirNDC.y, edgeDirNDC.x);\n\
|
|
86
|
+
\n\
|
|
87
|
+
// Convert line width from pixels to clip space\n\
|
|
88
|
+
float lineWidthPixels = u_lineWidth;\n\
|
|
89
|
+
vec2 viewportSize = czm_viewport.zw;\n\
|
|
90
|
+
vec2 clipPerPixel = (2.0 / viewportSize) * currentClip.w;\n\
|
|
91
|
+
vec2 offsetClip = perpNDC * lineWidthPixels * clipPerPixel * 0.5 * a_edgeOffset;\n\
|
|
92
|
+
\n\
|
|
93
|
+
posClip.xy += offsetClip;\n\
|
|
94
|
+
}\n\
|
|
95
|
+
\n\
|
|
96
|
+
gl_Position = posClip;\n\
|
|
97
|
+
}\n\
|
|
98
|
+
#endif\n\
|
|
99
|
+
";
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
//This file is automatically rebuilt by the Cesium build process.
|
|
2
|
+
export default "//\n\
|
|
3
|
+
// Fragment shader for Gaussian splats.\n\
|
|
4
|
+
// Renders a Gaussian splat within a quad, discarding fragments outside the unit circle.\n\
|
|
5
|
+
// Applies an approximate Gaussian falloff based on distance from the center and outputs\n\
|
|
6
|
+
// a color modulated by the alpha and Gaussian weight.\n\
|
|
7
|
+
//\n\
|
|
8
|
+
void main() {\n\
|
|
9
|
+
if (v_splitDirection < 0.0 && gl_FragCoord.x > czm_splitPosition) discard;\n\
|
|
10
|
+
if (v_splitDirection > 0.0 && gl_FragCoord.x < czm_splitPosition) discard;\n\
|
|
11
|
+
\n\
|
|
12
|
+
float A = -dot(v_vertPos, v_vertPos);\n\
|
|
13
|
+
if (A < -4.) {\n\
|
|
14
|
+
discard;\n\
|
|
15
|
+
}\n\
|
|
16
|
+
\n\
|
|
17
|
+
float B = exp(A * 4.) * v_splatColor.a ;\n\
|
|
18
|
+
out_FragColor = vec4(v_splatColor.rgb * B , B);\n\
|
|
19
|
+
}\n\
|
|
20
|
+
";
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
//This file is automatically rebuilt by the Cesium build process.
|
|
2
|
+
export default "//\n\
|
|
3
|
+
// Vertex shader for Gaussian splats.\n\
|
|
4
|
+
\n\
|
|
5
|
+
// The splats are rendered as quads in view space. Splat attributes are loaded from a texture with precomputed 3D covariance.\n\
|
|
6
|
+
\n\
|
|
7
|
+
// Passes local quad coordinates and color to the fragment shader for Gaussian evaluation. \n\
|
|
8
|
+
//\n\
|
|
9
|
+
// Discards splats outside the view frustum or with negligible screen size.\n\
|
|
10
|
+
//\n\
|
|
11
|
+
#if defined(HAS_SPHERICAL_HARMONICS)\n\
|
|
12
|
+
const uint coefficientCount[3] = uint[3](3u,8u,15u);\n\
|
|
13
|
+
const float SH_C1 = 0.48860251;\n\
|
|
14
|
+
const float SH_C2[5] = float[5](\n\
|
|
15
|
+
1.092548430,\n\
|
|
16
|
+
-1.09254843,\n\
|
|
17
|
+
0.315391565,\n\
|
|
18
|
+
-1.09254843,\n\
|
|
19
|
+
0.546274215\n\
|
|
20
|
+
);\n\
|
|
21
|
+
\n\
|
|
22
|
+
const float SH_C3[7] = float[7](\n\
|
|
23
|
+
-0.59004358,\n\
|
|
24
|
+
2.890611442,\n\
|
|
25
|
+
-0.45704579,\n\
|
|
26
|
+
0.373176332,\n\
|
|
27
|
+
-0.45704579,\n\
|
|
28
|
+
1.445305721,\n\
|
|
29
|
+
-0.59004358\n\
|
|
30
|
+
);\n\
|
|
31
|
+
\n\
|
|
32
|
+
//Retrieve SH coefficient. Currently RG32UI format\n\
|
|
33
|
+
uvec2 loadSHCoeff(uint splatID, int index) {\n\
|
|
34
|
+
ivec2 shTexSize = textureSize(u_sphericalHarmonicsTexture, 0);\n\
|
|
35
|
+
uint dims = coefficientCount[uint(u_sphericalHarmonicsDegree)-1u];\n\
|
|
36
|
+
uint splatsPerRow = uint(shTexSize.x) / dims;\n\
|
|
37
|
+
uint shIndex = (splatID%splatsPerRow) * dims + uint(index);\n\
|
|
38
|
+
ivec2 shPosCoord = ivec2(shIndex, splatID / splatsPerRow);\n\
|
|
39
|
+
return texelFetch(u_sphericalHarmonicsTexture, shPosCoord, 0).rg;\n\
|
|
40
|
+
}\n\
|
|
41
|
+
\n\
|
|
42
|
+
//Unpack RG32UI half float coefficients to vec3\n\
|
|
43
|
+
vec3 halfToVec3(uvec2 packed) {\n\
|
|
44
|
+
return vec3(unpackHalf2x16(packed.x), unpackHalf2x16(packed.y).x);\n\
|
|
45
|
+
}\n\
|
|
46
|
+
\n\
|
|
47
|
+
vec3 loadAndExpandSHCoeff(uint splatID, int index) {\n\
|
|
48
|
+
uvec2 coeff = loadSHCoeff(splatID, index);\n\
|
|
49
|
+
return halfToVec3(coeff);\n\
|
|
50
|
+
}\n\
|
|
51
|
+
\n\
|
|
52
|
+
vec3 evaluateSH(uint splatID, vec3 viewDir) {\n\
|
|
53
|
+
vec3 result = vec3(0.0);\n\
|
|
54
|
+
int coeffIndex = 0;\n\
|
|
55
|
+
float x = viewDir.x, y = viewDir.y, z = viewDir.z;\n\
|
|
56
|
+
\n\
|
|
57
|
+
if (u_sphericalHarmonicsDegree >= 1.) {\n\
|
|
58
|
+
vec3 sh1 = loadAndExpandSHCoeff(splatID, coeffIndex++);\n\
|
|
59
|
+
vec3 sh2 = loadAndExpandSHCoeff(splatID, coeffIndex++);\n\
|
|
60
|
+
vec3 sh3 = loadAndExpandSHCoeff(splatID, coeffIndex++);\n\
|
|
61
|
+
result += -SH_C1 * y * sh1 + SH_C1 * z * sh2 - SH_C1 * x * sh3;\n\
|
|
62
|
+
\n\
|
|
63
|
+
if (u_sphericalHarmonicsDegree >= 2.) {\n\
|
|
64
|
+
float xx = x * x;\n\
|
|
65
|
+
float yy = y * y;\n\
|
|
66
|
+
float zz = z * z;\n\
|
|
67
|
+
float xy = x * y;\n\
|
|
68
|
+
float yz = y * z;\n\
|
|
69
|
+
float xz = x * z;\n\
|
|
70
|
+
\n\
|
|
71
|
+
vec3 sh4 = loadAndExpandSHCoeff(splatID, coeffIndex++);\n\
|
|
72
|
+
vec3 sh5 = loadAndExpandSHCoeff(splatID, coeffIndex++);\n\
|
|
73
|
+
vec3 sh6 = loadAndExpandSHCoeff(splatID, coeffIndex++);\n\
|
|
74
|
+
vec3 sh7 = loadAndExpandSHCoeff(splatID, coeffIndex++);\n\
|
|
75
|
+
vec3 sh8 = loadAndExpandSHCoeff(splatID, coeffIndex++);\n\
|
|
76
|
+
result += SH_C2[0] * xy * sh4 +\n\
|
|
77
|
+
SH_C2[1] * yz * sh5 +\n\
|
|
78
|
+
SH_C2[2] * (2.0f * zz - xx - yy) * sh6 +\n\
|
|
79
|
+
SH_C2[3] * xz * sh7 +\n\
|
|
80
|
+
SH_C2[4] * (xx - yy) * sh8;\n\
|
|
81
|
+
\n\
|
|
82
|
+
if (u_sphericalHarmonicsDegree >= 3.) {\n\
|
|
83
|
+
vec3 sh9 = loadAndExpandSHCoeff(splatID, coeffIndex++);\n\
|
|
84
|
+
vec3 sh10 = loadAndExpandSHCoeff(splatID, coeffIndex++);\n\
|
|
85
|
+
vec3 sh11 = loadAndExpandSHCoeff(splatID, coeffIndex++);\n\
|
|
86
|
+
vec3 sh12 = loadAndExpandSHCoeff(splatID, coeffIndex++);\n\
|
|
87
|
+
vec3 sh13 = loadAndExpandSHCoeff(splatID, coeffIndex++);\n\
|
|
88
|
+
vec3 sh14 = loadAndExpandSHCoeff(splatID, coeffIndex++);\n\
|
|
89
|
+
vec3 sh15 = loadAndExpandSHCoeff(splatID, coeffIndex++);\n\
|
|
90
|
+
result += SH_C3[0] * y * (3.0f * xx - yy) * sh9 +\n\
|
|
91
|
+
SH_C3[1] * xy * z * sh10 +\n\
|
|
92
|
+
SH_C3[2] * y * (4.0f * zz - xx - yy) * sh11 +\n\
|
|
93
|
+
SH_C3[3] * z * (2.0f * zz - 3.0f * xx - 3.0f * yy) * sh12 +\n\
|
|
94
|
+
SH_C3[4] * x * (4.0f * zz - xx - yy) * sh13 +\n\
|
|
95
|
+
SH_C3[5] * z * (xx - yy) * sh14 +\n\
|
|
96
|
+
SH_C3[6] * x * (xx - 3.0f * yy) * sh15;\n\
|
|
97
|
+
}\n\
|
|
98
|
+
}\n\
|
|
99
|
+
}\n\
|
|
100
|
+
return result;\n\
|
|
101
|
+
}\n\
|
|
102
|
+
#endif\n\
|
|
103
|
+
\n\
|
|
104
|
+
// Transforms and projects splat covariance into screen space and extracts the major and minor axes of the Gaussian ellipsoid\n\
|
|
105
|
+
// which is used to calculate the vertex position in clip space.\n\
|
|
106
|
+
vec4 calcCovVectors(vec3 viewPos, mat3 Vrk) {\n\
|
|
107
|
+
vec4 t = vec4(viewPos, 1.0);\n\
|
|
108
|
+
vec2 focal = vec2(czm_projection[0][0] * czm_viewport.z, czm_projection[1][1] * czm_viewport.w);\n\
|
|
109
|
+
\n\
|
|
110
|
+
vec2 J1 = focal / t.z;\n\
|
|
111
|
+
vec2 J2 = -focal * vec2(t.x, t.y) / (t.z * t.z);\n\
|
|
112
|
+
mat3 J = mat3(\n\
|
|
113
|
+
J1.x, 0.0, J2.x,\n\
|
|
114
|
+
0.0, J1.y, J2.y,\n\
|
|
115
|
+
0.0, 0.0, 0.0\n\
|
|
116
|
+
);\n\
|
|
117
|
+
\n\
|
|
118
|
+
mat3 R = mat3(czm_modelView);\n\
|
|
119
|
+
\n\
|
|
120
|
+
//transform our covariance into view space\n\
|
|
121
|
+
//ensures orientation is correct\n\
|
|
122
|
+
mat3 Vrk_view = R * Vrk * transpose(R);\n\
|
|
123
|
+
mat3 cov = transpose(J) * Vrk_view * J;\n\
|
|
124
|
+
\n\
|
|
125
|
+
float diagonal1 = cov[0][0] + .3;\n\
|
|
126
|
+
float offDiagonal = cov[0][1];\n\
|
|
127
|
+
float diagonal2 = cov[1][1] + .3;\n\
|
|
128
|
+
\n\
|
|
129
|
+
float mid = 0.5 * (diagonal1 + diagonal2);\n\
|
|
130
|
+
float radius = length(vec2((diagonal1 - diagonal2) * 0.5, offDiagonal));\n\
|
|
131
|
+
float lambda1 = mid + radius;\n\
|
|
132
|
+
float lambda2 = max(mid - radius, 0.1);\n\
|
|
133
|
+
\n\
|
|
134
|
+
vec2 diagonalVector = normalize(vec2(offDiagonal, lambda1 - diagonal1));\n\
|
|
135
|
+
\n\
|
|
136
|
+
return vec4(\n\
|
|
137
|
+
min(sqrt(2.0 * lambda1), 1024.0) * diagonalVector,\n\
|
|
138
|
+
min(sqrt(2.0 * lambda2), 1024.0) * vec2(diagonalVector.y, -diagonalVector.x)\n\
|
|
139
|
+
);\n\
|
|
140
|
+
}\n\
|
|
141
|
+
\n\
|
|
142
|
+
highp vec4 discardVec = vec4(0.0, 0.0, 2.0, 1.0);\n\
|
|
143
|
+
\n\
|
|
144
|
+
void main() {\n\
|
|
145
|
+
uint texIdx = uint(a_splatIndex);\n\
|
|
146
|
+
// u_splatRowMask and u_splatRowShift encode the row width of the splat\n\
|
|
147
|
+
// attribute texture. The texture width is always maximumTextureSize, which\n\
|
|
148
|
+
// varies by GPU, so these are passed as uniforms rather than constants.\n\
|
|
149
|
+
// rowMask = maximumTextureSize/2 - 1\n\
|
|
150
|
+
// rowShift = log2(maximumTextureSize/2)\n\
|
|
151
|
+
uint rowMask = uint(u_splatRowMask);\n\
|
|
152
|
+
uint rowShift = uint(u_splatRowShift);\n\
|
|
153
|
+
ivec2 posCoord = ivec2(int((texIdx & rowMask) << 1), int(texIdx >> rowShift));\n\
|
|
154
|
+
vec4 splatPosition = vec4( uintBitsToFloat(uvec4(texelFetch(u_splatAttributeTexture, posCoord, 0))) );\n\
|
|
155
|
+
\n\
|
|
156
|
+
vec4 splatViewPos = czm_modelView * vec4(splatPosition.xyz, 1.0);\n\
|
|
157
|
+
vec4 clipPosition = czm_projection * splatViewPos;\n\
|
|
158
|
+
\n\
|
|
159
|
+
float clip = 1.2 * clipPosition.w;\n\
|
|
160
|
+
if (clipPosition.z < -clip || clipPosition.x < -clip || clipPosition.x > clip ||\n\
|
|
161
|
+
clipPosition.y < -clip || clipPosition.y > clip) {\n\
|
|
162
|
+
gl_Position = vec4(0.0, 0.0, 2.0, 1.0);\n\
|
|
163
|
+
return;\n\
|
|
164
|
+
}\n\
|
|
165
|
+
\n\
|
|
166
|
+
ivec2 covCoord = ivec2(int(((texIdx & rowMask) << 1) | 1u), int(texIdx >> rowShift));\n\
|
|
167
|
+
uvec4 covariance = uvec4(texelFetch(u_splatAttributeTexture, covCoord, 0));\n\
|
|
168
|
+
\n\
|
|
169
|
+
gl_Position = clipPosition;\n\
|
|
170
|
+
\n\
|
|
171
|
+
vec2 u1 = unpackHalf2x16(covariance.x) ;\n\
|
|
172
|
+
vec2 u2 = unpackHalf2x16(covariance.y);\n\
|
|
173
|
+
vec2 u3 = unpackHalf2x16(covariance.z);\n\
|
|
174
|
+
mat3 Vrk = mat3(u1.x, u1.y, u2.x, u1.y, u2.y, u3.x, u2.x, u3.x, u3.y);\n\
|
|
175
|
+
\n\
|
|
176
|
+
vec4 covVectors = calcCovVectors(splatViewPos.xyz, Vrk);\n\
|
|
177
|
+
\n\
|
|
178
|
+
if (dot(covVectors.xy, covVectors.xy) < 4.0 && dot(covVectors.zw, covVectors.zw) < 4.0) {\n\
|
|
179
|
+
gl_Position = discardVec;\n\
|
|
180
|
+
return;\n\
|
|
181
|
+
}\n\
|
|
182
|
+
\n\
|
|
183
|
+
vec2 corner = vec2((gl_VertexID << 1) & 2, gl_VertexID & 2) - 1.;\n\
|
|
184
|
+
\n\
|
|
185
|
+
gl_Position += vec4((corner.x * covVectors.xy + corner.y * covVectors.zw) / czm_viewport.zw * gl_Position.w, 0, 0);\n\
|
|
186
|
+
gl_Position.z = clamp(gl_Position.z, -abs(gl_Position.w), abs(gl_Position.w));\n\
|
|
187
|
+
\n\
|
|
188
|
+
v_vertPos = corner ;\n\
|
|
189
|
+
v_splatColor = vec4(covariance.w & 0xffu, (covariance.w >> 8) & 0xffu, (covariance.w >> 16) & 0xffu, (covariance.w >> 24) & 0xffu) / 255.0;\n\
|
|
190
|
+
#if defined(HAS_SPHERICAL_HARMONICS)\n\
|
|
191
|
+
vec4 splatWC = czm_inverseView * splatViewPos;\n\
|
|
192
|
+
vec3 viewDirModel = normalize(u_inverseModelRotation * (splatWC.xyz - u_cameraPositionWC.xyz));\n\
|
|
193
|
+
\n\
|
|
194
|
+
v_splatColor.rgb += evaluateSH(texIdx, viewDirModel).rgb;\n\
|
|
195
|
+
#endif\n\
|
|
196
|
+
v_splitDirection = u_splitDirection;\n\
|
|
197
|
+
}";
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
//This file is automatically rebuilt by the Cesium build process.
|
|
2
|
+
export default "// See IntersectionUtils.glsl for the definitions of Ray, Intersections, INF_HIT,\n\
|
|
3
|
+
// NO_HIT, setShapeIntersection\n\
|
|
4
|
+
\n\
|
|
5
|
+
/* Clipping plane defines (set in Scene/VoxelRenderResources.js)\n\
|
|
6
|
+
#define CLIPPING_PLANES_UNION\n\
|
|
7
|
+
#define CLIPPING_PLANES_COUNT\n\
|
|
8
|
+
#define CLIPPING_PLANES_INTERSECTION_INDEX\n\
|
|
9
|
+
*/\n\
|
|
10
|
+
\n\
|
|
11
|
+
uniform sampler2D u_clippingPlanesTexture;\n\
|
|
12
|
+
uniform mat4 u_clippingPlanesMatrix;\n\
|
|
13
|
+
\n\
|
|
14
|
+
// Plane is in Hessian Normal Form\n\
|
|
15
|
+
vec4 intersectPlane(in Ray ray, in vec4 plane) {\n\
|
|
16
|
+
vec3 n = plane.xyz; // normal\n\
|
|
17
|
+
float w = plane.w; // -dot(pointOnPlane, normal)\n\
|
|
18
|
+
\n\
|
|
19
|
+
float a = dot(ray.pos, n);\n\
|
|
20
|
+
float b = dot(ray.dir, n);\n\
|
|
21
|
+
float t = -(w + a) / b;\n\
|
|
22
|
+
\n\
|
|
23
|
+
return vec4(n, t);\n\
|
|
24
|
+
}\n\
|
|
25
|
+
\n\
|
|
26
|
+
#ifdef CLIPPING_PLANES\n\
|
|
27
|
+
void intersectClippingPlanes(in Ray ray, inout Intersections ix) {\n\
|
|
28
|
+
vec4 backSide = vec4(-ray.dir, -INF_HIT);\n\
|
|
29
|
+
vec4 farSide = vec4(ray.dir, +INF_HIT);\n\
|
|
30
|
+
RayShapeIntersection clippingVolume;\n\
|
|
31
|
+
\n\
|
|
32
|
+
#if (CLIPPING_PLANES_COUNT == 1)\n\
|
|
33
|
+
// Union and intersection are the same when there's one clipping plane, and the code\n\
|
|
34
|
+
// is more simplified.\n\
|
|
35
|
+
vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, 0);\n\
|
|
36
|
+
vec4 intersection = intersectPlane(ray, planeUv);\n\
|
|
37
|
+
bool reflects = dot(ray.dir, intersection.xyz) < 0.0;\n\
|
|
38
|
+
clippingVolume.entry = reflects ? backSide : intersection;\n\
|
|
39
|
+
clippingVolume.exit = reflects ? intersection : farSide;\n\
|
|
40
|
+
setShapeIntersection(ix, CLIPPING_PLANES_INTERSECTION_INDEX, clippingVolume);\n\
|
|
41
|
+
#elif defined(CLIPPING_PLANES_UNION)\n\
|
|
42
|
+
vec4 firstTransmission = vec4(ray.dir, +INF_HIT);\n\
|
|
43
|
+
vec4 lastReflection = vec4(-ray.dir, -INF_HIT);\n\
|
|
44
|
+
for (int i = 0; i < CLIPPING_PLANES_COUNT; i++) {\n\
|
|
45
|
+
vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, i);\n\
|
|
46
|
+
vec4 intersection = intersectPlane(ray, planeUv);\n\
|
|
47
|
+
if (dot(ray.dir, planeUv.xyz) > 0.0) {\n\
|
|
48
|
+
firstTransmission = intersection.w <= firstTransmission.w ? intersection : firstTransmission;\n\
|
|
49
|
+
} else {\n\
|
|
50
|
+
lastReflection = intersection.w >= lastReflection.w ? intersection : lastReflection;\n\
|
|
51
|
+
}\n\
|
|
52
|
+
}\n\
|
|
53
|
+
clippingVolume.entry = backSide;\n\
|
|
54
|
+
clippingVolume.exit = lastReflection;\n\
|
|
55
|
+
setShapeIntersection(ix, CLIPPING_PLANES_INTERSECTION_INDEX + 0, clippingVolume);\n\
|
|
56
|
+
clippingVolume.entry = firstTransmission;\n\
|
|
57
|
+
clippingVolume.exit = farSide;\n\
|
|
58
|
+
setShapeIntersection(ix, CLIPPING_PLANES_INTERSECTION_INDEX + 1, clippingVolume);\n\
|
|
59
|
+
#else // intersection\n\
|
|
60
|
+
vec4 lastTransmission = vec4(ray.dir, -INF_HIT);\n\
|
|
61
|
+
vec4 firstReflection = vec4(-ray.dir, +INF_HIT);\n\
|
|
62
|
+
for (int i = 0; i < CLIPPING_PLANES_COUNT; i++) {\n\
|
|
63
|
+
vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, i);\n\
|
|
64
|
+
vec4 intersection = intersectPlane(ray, planeUv);\n\
|
|
65
|
+
if (dot(ray.dir, planeUv.xyz) > 0.0) {\n\
|
|
66
|
+
lastTransmission = intersection.w > lastTransmission.w ? intersection : lastTransmission;\n\
|
|
67
|
+
} else {\n\
|
|
68
|
+
firstReflection = intersection.w < firstReflection.w ? intersection: firstReflection;\n\
|
|
69
|
+
}\n\
|
|
70
|
+
}\n\
|
|
71
|
+
if (lastTransmission.w < firstReflection.w) {\n\
|
|
72
|
+
clippingVolume.entry = lastTransmission;\n\
|
|
73
|
+
clippingVolume.exit = firstReflection;\n\
|
|
74
|
+
} else {\n\
|
|
75
|
+
clippingVolume.entry = vec4(-ray.dir, NO_HIT);\n\
|
|
76
|
+
clippingVolume.exit = vec4(ray.dir, NO_HIT);\n\
|
|
77
|
+
}\n\
|
|
78
|
+
setShapeIntersection(ix, CLIPPING_PLANES_INTERSECTION_INDEX, clippingVolume);\n\
|
|
79
|
+
#endif\n\
|
|
80
|
+
}\n\
|
|
81
|
+
#endif\n\
|
|
82
|
+
";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
//This file is automatically rebuilt by the Cesium build process.
|
|
2
|
+
export default "uniform vec3 u_boxLocalToShapeUvScale;\n\
|
|
3
|
+
\n\
|
|
4
|
+
uniform ivec4 u_cameraTileCoordinates;\n\
|
|
5
|
+
uniform vec3 u_cameraTileUv;\n\
|
|
6
|
+
uniform mat3 u_boxEcToXyz;\n\
|
|
7
|
+
\n\
|
|
8
|
+
mat3 convertLocalToShapeSpaceDerivative(in vec3 positionLocal) {\n\
|
|
9
|
+
// For BOX, local space = shape space, so the Jacobian is the identity matrix.\n\
|
|
10
|
+
return mat3(1.0);\n\
|
|
11
|
+
}\n\
|
|
12
|
+
\n\
|
|
13
|
+
vec3 scaleShapeUvToShapeSpace(in vec3 shapeUv) {\n\
|
|
14
|
+
return shapeUv / u_boxLocalToShapeUvScale;\n\
|
|
15
|
+
}\n\
|
|
16
|
+
\n\
|
|
17
|
+
vec3 convertEcToDeltaTile(in vec3 positionEC) {\n\
|
|
18
|
+
vec3 dPosition = u_boxEcToXyz * positionEC;\n\
|
|
19
|
+
return u_boxLocalToShapeUvScale * dPosition * float(1 << u_cameraTileCoordinates.w);\n\
|
|
20
|
+
}\n\
|
|
21
|
+
\n\
|
|
22
|
+
TileAndUvCoordinate getTileAndUvCoordinate(in vec3 positionEC) {\n\
|
|
23
|
+
vec3 deltaTileCoordinate = convertEcToDeltaTile(positionEC);\n\
|
|
24
|
+
vec3 tileUvSum = u_cameraTileUv + deltaTileCoordinate;\n\
|
|
25
|
+
ivec3 tileCoordinate = u_cameraTileCoordinates.xyz + ivec3(floor(tileUvSum));\n\
|
|
26
|
+
tileCoordinate = min(max(ivec3(0), tileCoordinate), ivec3((1 << u_cameraTileCoordinates.w) - 1));\n\
|
|
27
|
+
ivec3 tileCoordinateChange = tileCoordinate - u_cameraTileCoordinates.xyz;\n\
|
|
28
|
+
vec3 tileUv = clamp(tileUvSum - vec3(tileCoordinateChange), 0.0, 1.0);\n\
|
|
29
|
+
return TileAndUvCoordinate(ivec4(tileCoordinate, u_cameraTileCoordinates.w), tileUv);\n\
|
|
30
|
+
}\n\
|
|
31
|
+
";
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
//This file is automatically rebuilt by the Cesium build process.
|
|
2
|
+
export default "uniform vec3 u_cylinderLocalToShapeUvScale; // x = radius scale, y = angle scale, z = height scale\n\
|
|
3
|
+
uniform float u_cylinderShapeUvAngleRangeOrigin;\n\
|
|
4
|
+
uniform mat3 u_cylinderEcToRadialTangentUp;\n\
|
|
5
|
+
uniform ivec4 u_cameraTileCoordinates;\n\
|
|
6
|
+
uniform vec3 u_cameraTileUv;\n\
|
|
7
|
+
uniform vec3 u_cameraShapePosition; // (radial distance, angle, height) of camera in shape space\n\
|
|
8
|
+
\n\
|
|
9
|
+
mat3 convertLocalToShapeSpaceDerivative(in vec3 position) {\n\
|
|
10
|
+
vec3 radial = normalize(vec3(position.xy, 0.0));\n\
|
|
11
|
+
vec3 z = vec3(0.0, 0.0, 1.0);\n\
|
|
12
|
+
vec3 east = normalize(vec3(-position.y, position.x, 0.0));\n\
|
|
13
|
+
return mat3(radial, east / length(position.xy), z);\n\
|
|
14
|
+
}\n\
|
|
15
|
+
\n\
|
|
16
|
+
vec3 scaleShapeUvToShapeSpace(in vec3 shapeUv) {\n\
|
|
17
|
+
float radius = shapeUv.x / u_cylinderLocalToShapeUvScale.x;\n\
|
|
18
|
+
float angle = shapeUv.y * czm_twoPi / u_cylinderLocalToShapeUvScale.y;\n\
|
|
19
|
+
float height = shapeUv.z / u_cylinderLocalToShapeUvScale.z;\n\
|
|
20
|
+
\n\
|
|
21
|
+
return vec3(radius, angle, height);\n\
|
|
22
|
+
}\n\
|
|
23
|
+
\n\
|
|
24
|
+
/**\n\
|
|
25
|
+
* Computes the change in polar coordinates given a change in position.\n\
|
|
26
|
+
* @param {vec2} dPosition The change in position in Cartesian coordinates.\n\
|
|
27
|
+
* @param {float} cameraRadialDistance The radial distance of the camera from the origin.\n\
|
|
28
|
+
* @return {vec2} The change in polar coordinates (radial distance, angle).\n\
|
|
29
|
+
*/\n\
|
|
30
|
+
vec2 computePolarChange(in vec2 dPosition, in float cameraRadialDistance) {\n\
|
|
31
|
+
float dAngle = atan(dPosition.y, cameraRadialDistance + dPosition.x);\n\
|
|
32
|
+
// Find the direction of the radial axis at the output angle, in Cartesian coordinates\n\
|
|
33
|
+
vec2 outputRadialAxis = vec2(cos(dAngle), sin(dAngle));\n\
|
|
34
|
+
float sinHalfAngle = sin(dAngle / 2.0);\n\
|
|
35
|
+
float versine = 2.0 * sinHalfAngle * sinHalfAngle;\n\
|
|
36
|
+
float dRadial = dot(dPosition, outputRadialAxis) - cameraRadialDistance * versine;\n\
|
|
37
|
+
return vec2(dRadial, dAngle);\n\
|
|
38
|
+
}\n\
|
|
39
|
+
\n\
|
|
40
|
+
vec3 convertEcToDeltaShape(in vec3 positionEC) {\n\
|
|
41
|
+
// 1. Rotate to radial, tangent, and up coordinates\n\
|
|
42
|
+
vec3 rtu = u_cylinderEcToRadialTangentUp * positionEC;\n\
|
|
43
|
+
// 2. Compute change in angular and radial coordinates.\n\
|
|
44
|
+
vec2 dPolar = computePolarChange(rtu.xy, u_cameraShapePosition.x);\n\
|
|
45
|
+
return vec3(dPolar.xy, rtu.z);\n\
|
|
46
|
+
}\n\
|
|
47
|
+
\n\
|
|
48
|
+
vec3 convertEcToDeltaTile(in vec3 positionEC) {\n\
|
|
49
|
+
vec3 deltaShape = convertEcToDeltaShape(positionEC);\n\
|
|
50
|
+
// Convert to tileset coordinates in [0, 1]\n\
|
|
51
|
+
float dx = u_cylinderLocalToShapeUvScale.x * deltaShape.x;\n\
|
|
52
|
+
float dy = deltaShape.y / czm_twoPi;\n\
|
|
53
|
+
#if defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE)\n\
|
|
54
|
+
// Wrap to ensure dy is not crossing through the unoccupied angle range, where\n\
|
|
55
|
+
// angle to tile coordinate conversions would be more complicated\n\
|
|
56
|
+
float cameraUvAngle = (u_cameraShapePosition.y + czm_pi) / czm_twoPi;\n\
|
|
57
|
+
float cameraUvAngleShift = fract(cameraUvAngle - u_cylinderShapeUvAngleRangeOrigin);\n\
|
|
58
|
+
float rawOutputUvAngle = cameraUvAngleShift + dy;\n\
|
|
59
|
+
float rotation = floor(rawOutputUvAngle);\n\
|
|
60
|
+
dy -= rotation;\n\
|
|
61
|
+
#endif\n\
|
|
62
|
+
dy *= u_cylinderLocalToShapeUvScale.y;\n\
|
|
63
|
+
float dz = u_cylinderLocalToShapeUvScale.z * deltaShape.z;\n\
|
|
64
|
+
// Convert to tile coordinate changes\n\
|
|
65
|
+
return vec3(dx, dy, dz) * float(1 << u_cameraTileCoordinates.w);\n\
|
|
66
|
+
}\n\
|
|
67
|
+
\n\
|
|
68
|
+
TileAndUvCoordinate getTileAndUvCoordinate(in vec3 positionEC) {\n\
|
|
69
|
+
vec3 deltaTileCoordinate = convertEcToDeltaTile(positionEC);\n\
|
|
70
|
+
vec3 tileUvSum = u_cameraTileUv + deltaTileCoordinate;\n\
|
|
71
|
+
ivec3 tileCoordinate = u_cameraTileCoordinates.xyz + ivec3(floor(tileUvSum));\n\
|
|
72
|
+
int maxTileCoordinate = (1 << u_cameraTileCoordinates.w) - 1;\n\
|
|
73
|
+
tileCoordinate.x = min(max(0, tileCoordinate.x), maxTileCoordinate);\n\
|
|
74
|
+
tileCoordinate.z = min(max(0, tileCoordinate.z), maxTileCoordinate);\n\
|
|
75
|
+
#if (!defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE))\n\
|
|
76
|
+
ivec3 tileCoordinateChange = tileCoordinate - u_cameraTileCoordinates.xyz;\n\
|
|
77
|
+
if (tileCoordinate.y < 0) {\n\
|
|
78
|
+
tileCoordinate.y += (maxTileCoordinate + 1);\n\
|
|
79
|
+
} else if (tileCoordinate.y > maxTileCoordinate) {\n\
|
|
80
|
+
tileCoordinate.y -= (maxTileCoordinate + 1);\n\
|
|
81
|
+
}\n\
|
|
82
|
+
#else\n\
|
|
83
|
+
tileCoordinate.y = min(max(0, tileCoordinate.y), maxTileCoordinate);\n\
|
|
84
|
+
ivec3 tileCoordinateChange = tileCoordinate - u_cameraTileCoordinates.xyz;\n\
|
|
85
|
+
#endif\n\
|
|
86
|
+
vec3 tileUv = tileUvSum - vec3(tileCoordinateChange);\n\
|
|
87
|
+
tileUv.x = clamp(tileUv.x, 0.0, 1.0);\n\
|
|
88
|
+
#if (!defined(CYLINDER_HAS_SHAPE_BOUNDS_ANGLE))\n\
|
|
89
|
+
// If there is only one tile spanning 2*PI angle, the coordinate wraps around\n\
|
|
90
|
+
tileUv.y = (u_cameraTileCoordinates.w == 0) ? fract(tileUv.y) : clamp(tileUv.y, 0.0, 1.0);\n\
|
|
91
|
+
#else\n\
|
|
92
|
+
tileUv.y = clamp(tileUv.y, 0.0, 1.0);\n\
|
|
93
|
+
#endif\n\
|
|
94
|
+
tileUv.z = clamp(tileUv.z, 0.0, 1.0);\n\
|
|
95
|
+
return TileAndUvCoordinate(ivec4(tileCoordinate, u_cameraTileCoordinates.w), tileUv);\n\
|
|
96
|
+
}\n\
|
|
97
|
+
";
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
//This file is automatically rebuilt by the Cesium build process.
|
|
2
|
+
export default "/* Ellipsoid defines (set in Scene/VoxelEllipsoidShape.js)\n\
|
|
3
|
+
#define ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE\n\
|
|
4
|
+
#define ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE\n\
|
|
5
|
+
*/\n\
|
|
6
|
+
\n\
|
|
7
|
+
uniform vec3 u_cameraPositionCartographic; // (longitude, latitude, height) in radians and meters\n\
|
|
8
|
+
uniform vec2 u_ellipsoidCurvatureAtLatitude;\n\
|
|
9
|
+
uniform mat3 u_ellipsoidEcToEastNorthUp;\n\
|
|
10
|
+
uniform vec3 u_ellipsoidRadii;\n\
|
|
11
|
+
uniform vec2 u_evoluteScale; // (radii.x ^ 2 - radii.z ^ 2) * vec2(1.0, -1.0) / radii;\n\
|
|
12
|
+
uniform vec3 u_ellipsoidInverseRadiiSquared;\n\
|
|
13
|
+
#if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE)\n\
|
|
14
|
+
uniform float u_ellipsoidShapeUvLongitudeRangeOrigin;\n\
|
|
15
|
+
#endif\n\
|
|
16
|
+
uniform vec3 u_ellipsoidLocalToShapeUvScale; // x = longitude scale, y = latitude scale, z = height scale\n\
|
|
17
|
+
\n\
|
|
18
|
+
uniform ivec4 u_cameraTileCoordinates;\n\
|
|
19
|
+
uniform vec3 u_cameraTileUv;\n\
|
|
20
|
+
\n\
|
|
21
|
+
// robust iterative solution without trig functions\n\
|
|
22
|
+
// https://github.com/0xfaded/ellipse_demo/issues/1\n\
|
|
23
|
+
// https://stackoverflow.com/questions/22959698/distance-from-given-point-to-given-ellipse\n\
|
|
24
|
+
// Extended to return radius of curvature along with the point\n\
|
|
25
|
+
vec3 nearestPointAndRadiusOnEllipse(vec2 pos, vec2 radii) {\n\
|
|
26
|
+
vec2 p = abs(pos);\n\
|
|
27
|
+
vec2 inverseRadii = 1.0 / radii;\n\
|
|
28
|
+
\n\
|
|
29
|
+
// We describe the ellipse parametrically: v = radii * vec2(cos(t), sin(t))\n\
|
|
30
|
+
// but store the cos and sin of t in a vec2 for efficiency.\n\
|
|
31
|
+
// Initial guess: t = pi/4\n\
|
|
32
|
+
vec2 tTrigs = vec2(0.7071067811865476);\n\
|
|
33
|
+
// Initial guess of point on ellipsoid\n\
|
|
34
|
+
vec2 v = radii * tTrigs;\n\
|
|
35
|
+
// Center of curvature of the ellipse at v\n\
|
|
36
|
+
vec2 evolute = u_evoluteScale * tTrigs * tTrigs * tTrigs;\n\
|
|
37
|
+
\n\
|
|
38
|
+
const int iterations = 3;\n\
|
|
39
|
+
for (int i = 0; i < iterations; ++i) {\n\
|
|
40
|
+
// Find the (approximate) intersection of p - evolute with the ellipsoid.\n\
|
|
41
|
+
vec2 q = normalize(p - evolute) * length(v - evolute);\n\
|
|
42
|
+
// Update the estimate of t.\n\
|
|
43
|
+
tTrigs = (q + evolute) * inverseRadii;\n\
|
|
44
|
+
tTrigs = normalize(clamp(tTrigs, 0.0, 1.0));\n\
|
|
45
|
+
v = radii * tTrigs;\n\
|
|
46
|
+
evolute = u_evoluteScale * tTrigs * tTrigs * tTrigs;\n\
|
|
47
|
+
}\n\
|
|
48
|
+
\n\
|
|
49
|
+
return vec3(v * sign(pos), length(v - evolute));\n\
|
|
50
|
+
}\n\
|
|
51
|
+
\n\
|
|
52
|
+
mat3 convertLocalToShapeSpaceDerivative(in vec3 position) {\n\
|
|
53
|
+
vec3 east = normalize(vec3(-position.y, position.x, 0.0));\n\
|
|
54
|
+
\n\
|
|
55
|
+
// Convert the 3D position to a 2D position relative to the ellipse (radii.x, radii.z)\n\
|
|
56
|
+
// (assume radii.y == radii.x) and find the nearest point on the ellipse and its normal\n\
|
|
57
|
+
float distanceFromZAxis = length(position.xy);\n\
|
|
58
|
+
vec2 posEllipse = vec2(distanceFromZAxis, position.z);\n\
|
|
59
|
+
vec3 surfacePointAndRadius = nearestPointAndRadiusOnEllipse(posEllipse, u_ellipsoidRadii.xz);\n\
|
|
60
|
+
vec2 surfacePoint = surfacePointAndRadius.xy;\n\
|
|
61
|
+
\n\
|
|
62
|
+
vec2 normal2d = normalize(surfacePoint * u_ellipsoidInverseRadiiSquared.xz);\n\
|
|
63
|
+
vec3 north = vec3(-normal2d.y * normalize(position.xy), abs(normal2d.x));\n\
|
|
64
|
+
\n\
|
|
65
|
+
float heightSign = length(posEllipse) < length(surfacePoint) ? -1.0 : 1.0;\n\
|
|
66
|
+
float height = heightSign * length(posEllipse - surfacePoint);\n\
|
|
67
|
+
vec3 up = normalize(cross(east, north));\n\
|
|
68
|
+
\n\
|
|
69
|
+
return mat3(east / distanceFromZAxis, north / (surfacePointAndRadius.z + height), up);\n\
|
|
70
|
+
}\n\
|
|
71
|
+
\n\
|
|
72
|
+
vec3 scaleShapeUvToShapeSpace(in vec3 shapeUv) {\n\
|
|
73
|
+
// Convert from [0, 1] to radians [-pi, pi]\n\
|
|
74
|
+
float longitude = shapeUv.x * czm_twoPi;\n\
|
|
75
|
+
#if defined (ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE)\n\
|
|
76
|
+
longitude /= u_ellipsoidLocalToShapeUvScale.x;\n\
|
|
77
|
+
#endif\n\
|
|
78
|
+
\n\
|
|
79
|
+
// Convert from [0, 1] to radians [-pi/2, pi/2]\n\
|
|
80
|
+
float latitude = shapeUv.y * czm_pi;\n\
|
|
81
|
+
#if defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE)\n\
|
|
82
|
+
latitude /= u_ellipsoidLocalToShapeUvScale.y;\n\
|
|
83
|
+
#endif\n\
|
|
84
|
+
\n\
|
|
85
|
+
float height = shapeUv.z / u_ellipsoidLocalToShapeUvScale.z;\n\
|
|
86
|
+
\n\
|
|
87
|
+
return vec3(longitude, latitude, height);\n\
|
|
88
|
+
}\n\
|
|
89
|
+
\n\
|
|
90
|
+
vec3 convertEcToDeltaShape(in vec3 positionEC) {\n\
|
|
91
|
+
vec3 enu = u_ellipsoidEcToEastNorthUp * positionEC;\n\
|
|
92
|
+
\n\
|
|
93
|
+
// 1. Compute the change in longitude from the camera to the ENU point\n\
|
|
94
|
+
// First project the camera and ENU positions to the equatorial XY plane,\n\
|
|
95
|
+
// positioning the camera on the +x axis, so that enu.x projects along the +y axis\n\
|
|
96
|
+
float cosLatitude = cos(u_cameraPositionCartographic.y);\n\
|
|
97
|
+
float sinLatitude = sin(u_cameraPositionCartographic.y);\n\
|
|
98
|
+
float primeVerticalRadius = 1.0 / u_ellipsoidCurvatureAtLatitude.x;\n\
|
|
99
|
+
vec2 cameraXY = vec2((primeVerticalRadius + u_cameraPositionCartographic.z) * cosLatitude, 0.0);\n\
|
|
100
|
+
// Note precision loss in positionXY.x if length(enu) << length(cameraXY)\n\
|
|
101
|
+
vec2 positionXY = cameraXY + vec2(-enu.y * sinLatitude + enu.z * cosLatitude, enu.x);\n\
|
|
102
|
+
float dLongitude = atan(positionXY.y, positionXY.x);\n\
|
|
103
|
+
\n\
|
|
104
|
+
// 2. Find the longitude component of positionXY, by rotating about Z until the y component is zero.\n\
|
|
105
|
+
// Use the versine to compute the change in x directly from the change in angle:\n\
|
|
106
|
+
// versine(angle) = 2 * sin^2(angle/2)\n\
|
|
107
|
+
float sinHalfLongitude = sin(dLongitude / 2.0);\n\
|
|
108
|
+
float dx = length(positionXY) * 2.0 * sinHalfLongitude * sinHalfLongitude;\n\
|
|
109
|
+
// Rotate longitude component back to ENU North and Up, and remove from enu\n\
|
|
110
|
+
enu += vec3(-enu.x, -dx * sinLatitude, dx * cosLatitude);\n\
|
|
111
|
+
\n\
|
|
112
|
+
// 3. Compute the change in latitude from the camera to the ENU point.\n\
|
|
113
|
+
// First project the camera and ENU positions to the meridional ZX plane,\n\
|
|
114
|
+
// positioning the camera on the +Z axis, so that enu.y maps to the +X axis.\n\
|
|
115
|
+
float meridionalRadius = 1.0 / u_ellipsoidCurvatureAtLatitude.y;\n\
|
|
116
|
+
vec2 cameraZX = vec2(meridionalRadius + u_cameraPositionCartographic.z, 0.0);\n\
|
|
117
|
+
vec2 positionZX = cameraZX + vec2(enu.z, enu.y);\n\
|
|
118
|
+
float dLatitude = atan(positionZX.y, positionZX.x);\n\
|
|
119
|
+
\n\
|
|
120
|
+
// 4. Compute the change in height above the ellipsoid\n\
|
|
121
|
+
// Find the change in enu.z associated with rotating the point to the latitude of the camera\n\
|
|
122
|
+
float sinHalfLatitude = sin(dLatitude / 2.0);\n\
|
|
123
|
+
float dz = length(positionZX) * 2.0 * sinHalfLatitude * sinHalfLatitude;\n\
|
|
124
|
+
// The remaining change in enu.z is the change in height above the ellipsoid\n\
|
|
125
|
+
float dHeight = enu.z + dz;\n\
|
|
126
|
+
\n\
|
|
127
|
+
return vec3(dLongitude, dLatitude, dHeight);\n\
|
|
128
|
+
}\n\
|
|
129
|
+
\n\
|
|
130
|
+
vec3 convertEcToDeltaTile(in vec3 positionEC) {\n\
|
|
131
|
+
vec3 deltaShape = convertEcToDeltaShape(positionEC);\n\
|
|
132
|
+
// Convert to tileset coordinates in [0, 1]\n\
|
|
133
|
+
float dx = deltaShape.x / czm_twoPi;\n\
|
|
134
|
+
\n\
|
|
135
|
+
#if (defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE))\n\
|
|
136
|
+
// Wrap to ensure dx is not crossing through the unoccupied angle range, where\n\
|
|
137
|
+
// angle to tile coordinate conversions would be more complicated\n\
|
|
138
|
+
float cameraUvLongitude = (u_cameraPositionCartographic.x + czm_pi) / czm_twoPi;\n\
|
|
139
|
+
float cameraUvLongitudeShift = fract(cameraUvLongitude - u_ellipsoidShapeUvLongitudeRangeOrigin);\n\
|
|
140
|
+
float rawOutputUvLongitude = cameraUvLongitudeShift + dx;\n\
|
|
141
|
+
float rotation = floor(rawOutputUvLongitude);\n\
|
|
142
|
+
dx -= rotation;\n\
|
|
143
|
+
dx *= u_ellipsoidLocalToShapeUvScale.x;\n\
|
|
144
|
+
#endif\n\
|
|
145
|
+
\n\
|
|
146
|
+
float dy = deltaShape.y / czm_pi;\n\
|
|
147
|
+
#if (defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE))\n\
|
|
148
|
+
dy *= u_ellipsoidLocalToShapeUvScale.y;\n\
|
|
149
|
+
#endif\n\
|
|
150
|
+
\n\
|
|
151
|
+
float dz = u_ellipsoidLocalToShapeUvScale.z * deltaShape.z;\n\
|
|
152
|
+
// Convert to tile coordinate changes\n\
|
|
153
|
+
return vec3(dx, dy, dz) * float(1 << u_cameraTileCoordinates.w);\n\
|
|
154
|
+
}\n\
|
|
155
|
+
\n\
|
|
156
|
+
TileAndUvCoordinate getTileAndUvCoordinate(in vec3 positionEC) {\n\
|
|
157
|
+
vec3 deltaTileCoordinate = convertEcToDeltaTile(positionEC);\n\
|
|
158
|
+
vec3 tileUvSum = u_cameraTileUv + deltaTileCoordinate;\n\
|
|
159
|
+
ivec3 tileCoordinate = u_cameraTileCoordinates.xyz + ivec3(floor(tileUvSum));\n\
|
|
160
|
+
int maxTileCoordinate = (1 << u_cameraTileCoordinates.w) - 1;\n\
|
|
161
|
+
tileCoordinate.y = min(max(0, tileCoordinate.y), maxTileCoordinate);\n\
|
|
162
|
+
tileCoordinate.z = min(max(0, tileCoordinate.z), maxTileCoordinate);\n\
|
|
163
|
+
#if (!defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE))\n\
|
|
164
|
+
ivec3 tileCoordinateChange = tileCoordinate - u_cameraTileCoordinates.xyz;\n\
|
|
165
|
+
if (tileCoordinate.x < 0) {\n\
|
|
166
|
+
tileCoordinate.x += (maxTileCoordinate + 1);\n\
|
|
167
|
+
} else if (tileCoordinate.x > maxTileCoordinate) {\n\
|
|
168
|
+
tileCoordinate.x -= (maxTileCoordinate + 1);\n\
|
|
169
|
+
}\n\
|
|
170
|
+
#else\n\
|
|
171
|
+
tileCoordinate.x = min(max(0, tileCoordinate.x), maxTileCoordinate);\n\
|
|
172
|
+
ivec3 tileCoordinateChange = tileCoordinate - u_cameraTileCoordinates.xyz;\n\
|
|
173
|
+
#endif\n\
|
|
174
|
+
vec3 tileUv = tileUvSum - vec3(tileCoordinateChange);\n\
|
|
175
|
+
#if (!defined(ELLIPSOID_HAS_SHAPE_BOUNDS_LONGITUDE))\n\
|
|
176
|
+
// If there is only one tile spanning 2*PI angle, the coordinate wraps around\n\
|
|
177
|
+
tileUv.x = (u_cameraTileCoordinates.w == 0) ? fract(tileUv.x) : clamp(tileUv.x, 0.0, 1.0);\n\
|
|
178
|
+
#else\n\
|
|
179
|
+
tileUv.x = clamp(tileUv.x, 0.0, 1.0);\n\
|
|
180
|
+
#endif\n\
|
|
181
|
+
tileUv.y = clamp(tileUv.y, 0.0, 1.0);\n\
|
|
182
|
+
tileUv.z = clamp(tileUv.z, 0.0, 1.0);\n\
|
|
183
|
+
return TileAndUvCoordinate(ivec4(tileCoordinate, u_cameraTileCoordinates.w), tileUv);\n\
|
|
184
|
+
}\n\
|
|
185
|
+
";
|
package/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
globalThis.CESIUM_VERSION = "0.1.
|
|
1
|
+
globalThis.CESIUM_VERSION = "0.1.2";
|
|
2
2
|
export { default as AutomaticUniforms } from './Source/Renderer/AutomaticUniforms.js';
|
|
3
3
|
export { default as Buffer } from './Source/Renderer/Buffer.js';
|
|
4
4
|
export { default as BufferUsage } from './Source/Renderer/BufferUsage.js';
|