@cesium/engine 7.0.0 → 9.0.0

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.
Files changed (200) hide show
  1. package/Build/ThirdParty/Workers/z-worker-pako.js +1 -5
  2. package/Build/Workers/{chunk-7XEAYGZK.js → chunk-24YTYWNB.js} +10 -10
  3. package/Build/Workers/{chunk-IQBYFRVW.js → chunk-2632RVPI.js} +7 -7
  4. package/Build/Workers/chunk-2KACWKS4.js +501 -0
  5. package/Build/Workers/{chunk-QZAD5O7I.js → chunk-2XPLH3JY.js} +7 -7
  6. package/Build/Workers/{chunk-JY5YEZFA.js → chunk-2ZBL3MVO.js} +8 -8
  7. package/Build/Workers/{chunk-ZK5JOS3D.js → chunk-3NCVAGDA.js} +14 -14
  8. package/Build/Workers/{chunk-AR5DNBJ4.js → chunk-5R6VWLMH.js} +6 -6
  9. package/Build/Workers/{chunk-PTQQUQC3.js → chunk-5TIV3L26.js} +13 -13
  10. package/Build/Workers/{chunk-BZP4T2JJ.js → chunk-6WF3KIF5.js} +10 -10
  11. package/Build/Workers/{chunk-5WQ523AW.js → chunk-73FKKY52.js} +5 -5
  12. package/Build/Workers/{chunk-F6SE42BK.js → chunk-7COR472O.js} +15 -472
  13. package/Build/Workers/{chunk-72SANQJV.js → chunk-ADOVHYWO.js} +9 -5
  14. package/Build/Workers/{chunk-5YLJ77FF.js → chunk-BCU2LH5T.js} +12 -11
  15. package/Build/Workers/{chunk-4EBHOMFX.js → chunk-C3XBUYBO.js} +17 -17
  16. package/Build/Workers/{chunk-IX2JCCNM.js → chunk-C6OI26DR.js} +1 -1
  17. package/Build/Workers/{chunk-2HJWSU7B.js → chunk-CO35JNNE.js} +4 -4
  18. package/Build/Workers/{chunk-OVLG3FRS.js → chunk-DGDUKCJJ.js} +6 -6
  19. package/Build/Workers/{chunk-DTAIXKTO.js → chunk-DPUSFA7S.js} +6 -6
  20. package/Build/Workers/{chunk-R5X4OQT4.js → chunk-E6WXPSJS.js} +7 -7
  21. package/Build/Workers/{chunk-VK3EJHWI.js → chunk-EOXYZ34O.js} +2 -2
  22. package/Build/Workers/{chunk-RAEV7K66.js → chunk-EPKE7GE3.js} +5 -5
  23. package/Build/Workers/{chunk-GV56Q4LU.js → chunk-GFA4SMXV.js} +11 -11
  24. package/Build/Workers/{chunk-NKPBIX7F.js → chunk-GXUXEOE2.js} +1 -1
  25. package/Build/Workers/{chunk-NY3K4IM3.js → chunk-HBQPB6IH.js} +12 -12
  26. package/Build/Workers/{chunk-6HZQPRUS.js → chunk-I37B3MZ2.js} +1 -1
  27. package/Build/Workers/{chunk-VRGFV2UO.js → chunk-L4BW3RUA.js} +10 -10
  28. package/Build/Workers/{chunk-6VJVYK2V.js → chunk-LAQP3SCC.js} +2 -2
  29. package/Build/Workers/{chunk-PNBGBETF.js → chunk-LQJ5FFFR.js} +10 -10
  30. package/Build/Workers/{chunk-UAEW6HKG.js → chunk-M2AYBTNH.js} +13 -13
  31. package/Build/Workers/{chunk-YUCVWAY6.js → chunk-MWV7IZK4.js} +7 -7
  32. package/Build/Workers/{chunk-JXDC723O.js → chunk-N4KXMWQU.js} +2 -2
  33. package/Build/Workers/{chunk-XWXM2O2R.js → chunk-NP2GYYE5.js} +6 -6
  34. package/Build/Workers/{chunk-GEJTYLCO.js → chunk-NZWNZA6S.js} +5 -5
  35. package/Build/Workers/{chunk-LZGHD6NY.js → chunk-P2YAAMT2.js} +15 -15
  36. package/Build/Workers/{chunk-S6SKF6DT.js → chunk-P4XKB3QZ.js} +5 -5
  37. package/Build/Workers/{chunk-U2VCRRQW.js → chunk-PXB7T27O.js} +6 -6
  38. package/Build/Workers/{chunk-RV7ZYPFT.js → chunk-QCQUZGXI.js} +4 -4
  39. package/Build/Workers/{chunk-JJ4VBOQ3.js → chunk-QKBGRKKG.js} +4 -4
  40. package/Build/Workers/{chunk-ODW7WYM4.js → chunk-RMOEYCZW.js} +2 -2
  41. package/Build/Workers/{chunk-ZUA2UUNV.js → chunk-RSJXEO2A.js} +2 -2
  42. package/Build/Workers/{chunk-UDO6BFSF.js → chunk-RV7ZOSS6.js} +13 -13
  43. package/Build/Workers/{chunk-LZ7JIV3K.js → chunk-SE4PXOEA.js} +17 -17
  44. package/Build/Workers/{chunk-S4MAZ3SS.js → chunk-SS4ESNE3.js} +2 -2
  45. package/Build/Workers/{chunk-AIPU2VSX.js → chunk-TJBU6GML.js} +6 -6
  46. package/Build/Workers/{chunk-5M3U6ZMA.js → chunk-TZORKRNK.js} +1 -1
  47. package/Build/Workers/{chunk-MY3VNFGQ.js → chunk-VR5RBW52.js} +7 -7
  48. package/Build/Workers/{chunk-FP6GYBFX.js → chunk-WHUSTDIB.js} +10 -10
  49. package/Build/Workers/{chunk-5HDYHG3F.js → chunk-X2F6BEPY.js} +13 -13
  50. package/Build/Workers/{chunk-WZU2YLWG.js → chunk-X6XOMPWL.js} +3 -3
  51. package/Build/Workers/{chunk-UGK3FCDY.js → chunk-YDVSBWEO.js} +1 -1
  52. package/Build/Workers/{chunk-46UD5ABS.js → chunk-YV4H2Y7M.js} +4 -4
  53. package/Build/Workers/{chunk-WBQCVXR3.js → chunk-Z7FQLK6N.js} +4 -4
  54. package/Build/Workers/{chunk-L2ZN645J.js → chunk-ZNVSKMQ2.js} +6 -6
  55. package/Build/Workers/{chunk-JCNXK6EL.js → chunk-ZYPTP7GS.js} +11 -11
  56. package/Build/Workers/combineGeometry.js +24 -23
  57. package/Build/Workers/createBoxGeometry.js +18 -17
  58. package/Build/Workers/createBoxOutlineGeometry.js +16 -15
  59. package/Build/Workers/createCircleGeometry.js +26 -25
  60. package/Build/Workers/createCircleOutlineGeometry.js +19 -18
  61. package/Build/Workers/createCoplanarPolygonGeometry.js +33 -32
  62. package/Build/Workers/createCoplanarPolygonOutlineGeometry.js +31 -30
  63. package/Build/Workers/createCorridorGeometry.js +29 -28
  64. package/Build/Workers/createCorridorOutlineGeometry.js +28 -27
  65. package/Build/Workers/createCylinderGeometry.js +20 -19
  66. package/Build/Workers/createCylinderOutlineGeometry.js +18 -17
  67. package/Build/Workers/createEllipseGeometry.js +26 -25
  68. package/Build/Workers/createEllipseOutlineGeometry.js +19 -18
  69. package/Build/Workers/createEllipsoidGeometry.js +19 -18
  70. package/Build/Workers/createEllipsoidOutlineGeometry.js +18 -17
  71. package/Build/Workers/createFrustumGeometry.js +18 -17
  72. package/Build/Workers/createFrustumOutlineGeometry.js +18 -17
  73. package/Build/Workers/createGeometry.js +54 -33
  74. package/Build/Workers/createGroundPolylineGeometry.js +22 -21
  75. package/Build/Workers/createPlaneGeometry.js +16 -15
  76. package/Build/Workers/createPlaneOutlineGeometry.js +15 -14
  77. package/Build/Workers/createPolygonGeometry.js +33 -32
  78. package/Build/Workers/createPolygonOutlineGeometry.js +30 -29
  79. package/Build/Workers/createPolylineGeometry.js +25 -24
  80. package/Build/Workers/createPolylineVolumeGeometry.js +31 -30
  81. package/Build/Workers/createPolylineVolumeOutlineGeometry.js +27 -26
  82. package/Build/Workers/createRectangleGeometry.js +27 -26
  83. package/Build/Workers/createRectangleOutlineGeometry.js +20 -19
  84. package/Build/Workers/createSimplePolylineGeometry.js +23 -22
  85. package/Build/Workers/createSphereGeometry.js +19 -18
  86. package/Build/Workers/createSphereOutlineGeometry.js +18 -17
  87. package/Build/Workers/createTaskProcessorWorker.js +3 -3
  88. package/Build/Workers/createVectorTileClampedPolylines.js +14 -14
  89. package/Build/Workers/createVectorTileGeometries.js +24 -23
  90. package/Build/Workers/createVectorTilePoints.js +12 -12
  91. package/Build/Workers/createVectorTilePolygons.js +22 -21
  92. package/Build/Workers/createVectorTilePolylines.js +14 -14
  93. package/Build/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js +22 -21
  94. package/Build/Workers/createVerticesFromHeightmap.js +22 -21
  95. package/Build/Workers/createVerticesFromQuantizedTerrainMesh.js +19 -18
  96. package/Build/Workers/createWallGeometry.js +24 -23
  97. package/Build/Workers/createWallOutlineGeometry.js +23 -22
  98. package/Build/Workers/decodeDraco.js +11 -11
  99. package/Build/Workers/decodeGoogleEarthEnterprisePacket.js +5 -5
  100. package/Build/Workers/decodeI3S.js +601 -92
  101. package/Build/Workers/transcodeKTX2.js +7 -7
  102. package/Build/Workers/transferTypedArrayTest.js +1 -1
  103. package/Build/Workers/upsampleQuantizedTerrainMesh.js +22 -21
  104. package/Source/Core/Check.d.ts +127 -0
  105. package/Source/Core/Check.js +0 -1
  106. package/Source/Core/Ellipsoid.js +6 -0
  107. package/Source/Core/Geometry.js +1 -1
  108. package/Source/Core/IntersectionTests.js +6 -3
  109. package/Source/Core/Ion.js +1 -1
  110. package/Source/Core/PixelFormat.js +5 -0
  111. package/Source/Core/PolygonGeometry.js +1 -1
  112. package/Source/Core/Transforms.js +3 -0
  113. package/Source/Core/VerticalExaggeration.js +2 -1
  114. package/Source/Core/srgbToLinear.js +32 -0
  115. package/Source/DataSources/CzmlDataSource.js +51 -23
  116. package/Source/DataSources/DataSourceDisplay.js +27 -0
  117. package/Source/DataSources/Entity.js +20 -2
  118. package/Source/DataSources/GeometryUpdaterSet.js +114 -0
  119. package/Source/DataSources/GeometryVisualizer.js +19 -83
  120. package/Source/Renderer/Context.js +10 -0
  121. package/Source/Renderer/ContextLimits.js +2 -0
  122. package/Source/Renderer/demodernizeShader.js +4 -1
  123. package/Source/Scene/ArcGisMapService.js +1 -1
  124. package/Source/Scene/Axis.js +12 -7
  125. package/Source/Scene/Billboard.js +32 -0
  126. package/Source/Scene/BillboardCollection.js +1 -1
  127. package/Source/Scene/BingMapsImageryProvider.js +4 -0
  128. package/Source/Scene/Camera.js +46 -4
  129. package/Source/Scene/Cesium3DTilesVoxelProvider.js +2 -9
  130. package/Source/Scene/Cesium3DTileset.js +10 -7
  131. package/Source/Scene/Cesium3DTilesetBaseTraversal.js +2 -4
  132. package/Source/Scene/FrameState.js +5 -0
  133. package/Source/Scene/Globe.js +0 -67
  134. package/Source/Scene/GlobeTranslucencyState.js +1 -1
  135. package/Source/Scene/GltfPipeline/updateVersion.js +69 -68
  136. package/Source/Scene/I3SDataProvider.js +270 -53
  137. package/Source/Scene/I3SDecoder.js +8 -1
  138. package/Source/Scene/I3SFeature.js +2 -5
  139. package/Source/Scene/I3SField.js +136 -31
  140. package/Source/Scene/I3SGeometry.js +70 -2
  141. package/Source/Scene/I3SLayer.js +55 -10
  142. package/Source/Scene/I3SNode.js +175 -18
  143. package/Source/Scene/I3SStatistics.js +94 -0
  144. package/Source/Scene/I3SSublayer.js +176 -0
  145. package/Source/Scene/I3SSymbology.js +337 -0
  146. package/Source/Scene/KeyframeNode.js +1 -1
  147. package/Source/Scene/Label.js +33 -0
  148. package/Source/Scene/LabelCollection.js +2 -1
  149. package/Source/Scene/Model/pickModel.js +25 -7
  150. package/Source/Scene/PickFramebuffer.js +37 -2
  151. package/Source/Scene/Picking.js +113 -39
  152. package/Source/Scene/Primitive.js +6 -5
  153. package/Source/Scene/Scene.js +126 -42
  154. package/Source/Scene/ScreenSpaceCameraController.js +21 -7
  155. package/Source/Scene/SensorVolumePortionToDisplay.js +69 -0
  156. package/Source/Scene/SpatialNode.js +12 -19
  157. package/Source/Scene/StructuralMetadata.js +1 -1
  158. package/Source/Scene/VoxelBoxShape.js +67 -6
  159. package/Source/Scene/VoxelCell.js +273 -0
  160. package/Source/Scene/VoxelCylinderShape.js +117 -163
  161. package/Source/Scene/VoxelEllipsoidShape.js +255 -304
  162. package/Source/Scene/VoxelPrimitive.js +109 -15
  163. package/Source/Scene/VoxelRenderResources.js +12 -3
  164. package/Source/Scene/VoxelShape.js +7 -4
  165. package/Source/Scene/VoxelTraversal.js +76 -54
  166. package/Source/Scene/buildVoxelDrawCommands.js +23 -0
  167. package/Source/Scene/createGooglePhotorealistic3DTileset.js +1 -0
  168. package/Source/Scene/processVoxelProperties.js +3 -0
  169. package/Source/Shaders/Voxels/IntersectBox.glsl +21 -47
  170. package/Source/Shaders/Voxels/IntersectBox.js +21 -47
  171. package/Source/Shaders/Voxels/IntersectClippingPlanes.glsl +1 -1
  172. package/Source/Shaders/Voxels/IntersectClippingPlanes.js +1 -1
  173. package/Source/Shaders/Voxels/IntersectCylinder.glsl +76 -203
  174. package/Source/Shaders/Voxels/IntersectCylinder.js +76 -203
  175. package/Source/Shaders/Voxels/IntersectEllipsoid.glsl +220 -229
  176. package/Source/Shaders/Voxels/IntersectEllipsoid.js +220 -229
  177. package/Source/Shaders/Voxels/IntersectLongitude.glsl +102 -0
  178. package/Source/Shaders/Voxels/IntersectLongitude.js +104 -0
  179. package/Source/Shaders/Voxels/IntersectionUtils.glsl +33 -11
  180. package/Source/Shaders/Voxels/IntersectionUtils.js +33 -11
  181. package/Source/Shaders/Voxels/Megatexture.glsl +1 -2
  182. package/Source/Shaders/Voxels/Megatexture.js +1 -2
  183. package/Source/Shaders/Voxels/Octree.glsl +14 -9
  184. package/Source/Shaders/Voxels/Octree.js +14 -9
  185. package/Source/Shaders/Voxels/VoxelFS.glsl +128 -40
  186. package/Source/Shaders/Voxels/VoxelFS.js +128 -40
  187. package/Source/Shaders/Voxels/VoxelUtils.glsl +31 -0
  188. package/Source/Shaders/Voxels/VoxelUtils.js +33 -0
  189. package/Source/Shaders/Voxels/convertUvToBox.glsl +24 -3
  190. package/Source/Shaders/Voxels/convertUvToBox.js +24 -4
  191. package/Source/Shaders/Voxels/convertUvToCylinder.glsl +64 -40
  192. package/Source/Shaders/Voxels/convertUvToCylinder.js +64 -40
  193. package/Source/Shaders/Voxels/convertUvToEllipsoid.glsl +100 -91
  194. package/Source/Shaders/Voxels/convertUvToEllipsoid.js +100 -91
  195. package/Source/ThirdParty/Workers/z-worker-pako.js +1 -1
  196. package/Source/Workers/createGeometry.js +40 -11
  197. package/Source/Workers/decodeI3S.js +720 -94
  198. package/index.d.ts +542 -40
  199. package/index.js +75 -66
  200. package/package.json +2 -2
@@ -9,7 +9,11 @@
9
9
  // See Megatexture.glsl for the definition of accumulatePropertiesFromMegatexture
10
10
 
11
11
  #define STEP_COUNT_MAX 1000 // Harcoded value because GLSL doesn't like variable length loops
12
- #define ALPHA_ACCUM_MAX 0.98 // Must be > 0.0 and <= 1.0
12
+ #if defined(PICKING_VOXEL)
13
+ #define ALPHA_ACCUM_MAX 0.1
14
+ #else
15
+ #define ALPHA_ACCUM_MAX 0.98 // Must be > 0.0 and <= 1.0
16
+ #endif
13
17
 
14
18
  uniform mat3 u_transformDirectionViewToLocal;
15
19
  uniform vec3 u_cameraPositionUv;
@@ -19,27 +23,98 @@ uniform float u_stepSize;
19
23
  uniform vec4 u_pickColor;
20
24
  #endif
21
25
 
22
- #if defined(JITTER)
23
- float hash(vec2 p)
24
- {
25
- vec3 p3 = fract(vec3(p.xyx) * 50.0); // magic number = hashscale
26
- p3 += dot(p3, p3.yzx + 19.19);
27
- return fract((p3.x + p3.y) * p3.z);
26
+ vec3 getSampleSize(in int level) {
27
+ vec3 sampleCount = exp2(float(level)) * vec3(u_dimensions);
28
+ vec3 sampleSizeUv = 1.0 / sampleCount;
29
+ return scaleShapeUvToShapeSpace(sampleSizeUv);
28
30
  }
29
- #endif
30
31
 
31
- vec4 getStepSize(in SampleData sampleData, in Ray viewRay, in RayShapeIntersection shapeIntersection) {
32
- #if defined(SHAPE_BOX)
33
- Box voxelBox = constructVoxelBox(sampleData.tileCoords, sampleData.tileUv);
34
- RayShapeIntersection voxelIntersection = intersectBox(viewRay, voxelBox);
35
- vec4 entry = shapeIntersection.entry.w >= voxelIntersection.entry.w ? shapeIntersection.entry : voxelIntersection.entry;
36
- float exit = min(voxelIntersection.exit.w, shapeIntersection.exit.w);
37
- float dt = (exit - entry.w) * RAY_SCALE;
38
- return vec4(normalize(entry.xyz), dt);
39
- #else
40
- float dimAtLevel = pow(2.0, float(sampleData.tileCoords.w));
41
- return vec4(viewRay.dir, u_stepSize / dimAtLevel);
42
- #endif
32
+ #define MINIMUM_STEP_SCALAR (0.02)
33
+ #define SHIFT_FRACTION (0.001)
34
+
35
+ /**
36
+ * Given a coordinate within a tile, and sample spacings along a ray through
37
+ * the coordinate, find the distance to the points where the ray entered and
38
+ * exited the voxel cell, along with the surface normals at those points.
39
+ * The surface normals are returned in shape space coordinates.
40
+ */
41
+ RayShapeIntersection getVoxelIntersection(in vec3 tileUv, in vec3 sampleSizeAlongRay) {
42
+ vec3 voxelCoord = tileUv * vec3(u_dimensions);
43
+ vec3 directions = sign(sampleSizeAlongRay);
44
+ vec3 positiveDirections = max(directions, 0.0);
45
+ vec3 entryCoord = mix(ceil(voxelCoord), floor(voxelCoord), positiveDirections);
46
+ vec3 exitCoord = entryCoord + directions;
47
+
48
+ vec3 distanceFromEntry = -abs((entryCoord - voxelCoord) * sampleSizeAlongRay);
49
+ float lastEntry = maxComponent(distanceFromEntry);
50
+ bvec3 isLastEntry = equal(distanceFromEntry, vec3(lastEntry));
51
+ vec3 entryNormal = -1.0 * vec3(isLastEntry) * directions;
52
+ vec4 entry = vec4(entryNormal, lastEntry);
53
+
54
+ vec3 distanceToExit = abs((exitCoord - voxelCoord) * sampleSizeAlongRay);
55
+ float firstExit = minComponent(distanceToExit);
56
+ bvec3 isFirstExit = equal(distanceToExit, vec3(firstExit));
57
+ vec3 exitNormal = vec3(isFirstExit) * directions;
58
+ vec4 exit = vec4(exitNormal, firstExit);
59
+
60
+ return RayShapeIntersection(entry, exit);
61
+ }
62
+
63
+ vec4 getStepSize(in SampleData sampleData, in Ray viewRay, in RayShapeIntersection shapeIntersection, in mat3 jacobianT, in float currentT) {
64
+ // The Jacobian is computed in a space where the shape spans [-1, 1].
65
+ // But the ray is marched in a space where the shape fills [0, 1].
66
+ // So we need to scale the Jacobian by 2.
67
+ vec3 gradient = 2.0 * viewRay.rawDir * jacobianT;
68
+ vec3 sampleSizeAlongRay = getSampleSize(sampleData.tileCoords.w) / gradient;
69
+
70
+ RayShapeIntersection voxelIntersection = getVoxelIntersection(sampleData.tileUv, sampleSizeAlongRay);
71
+
72
+ // Transform normal from shape space to Cartesian space
73
+ vec3 voxelNormal = normalize(jacobianT * voxelIntersection.entry.xyz);
74
+ // Compare with the shape intersection, to choose the appropriate normal
75
+ vec4 voxelEntry = vec4(voxelNormal, currentT + voxelIntersection.entry.w);
76
+ vec4 entry = intersectionMax(shapeIntersection.entry, voxelEntry);
77
+
78
+ float fixedStep = minComponent(abs(sampleSizeAlongRay)) * u_stepSize;
79
+ float shift = fixedStep * SHIFT_FRACTION;
80
+ float dt = voxelIntersection.exit.w + shift;
81
+ if ((currentT + dt) > shapeIntersection.exit.w) {
82
+ // Stop at end of shape
83
+ dt = shapeIntersection.exit.w - currentT + shift;
84
+ }
85
+ float stepSize = clamp(dt, fixedStep * MINIMUM_STEP_SCALAR, fixedStep + shift);
86
+
87
+ return vec4(entry.xyz, stepSize);
88
+ }
89
+
90
+ vec2 packIntToVec2(int value) {
91
+ float shifted = float(value) / 255.0;
92
+ float lowBits = fract(shifted);
93
+ float highBits = floor(shifted) / 255.0;
94
+ return vec2(highBits, lowBits);
95
+ }
96
+
97
+ vec2 packFloatToVec2(float value) {
98
+ float lowBits = fract(value);
99
+ float highBits = floor(value) / 255.0;
100
+ return vec2(highBits, lowBits);
101
+ }
102
+
103
+ int getSampleIndex(in vec3 tileUv) {
104
+ ivec3 voxelDimensions = u_dimensions;
105
+ vec3 sampleCoordinate = tileUv * vec3(voxelDimensions);
106
+ // tileUv = 1.0 is a valid coordinate but sampleIndex = voxelDimensions is not.
107
+ // (tileUv = 1.0 corresponds to the last sample, at index = voxelDimensions - 1).
108
+ // Clamp to [0, voxelDimensions - 0.5) to avoid numerical error before flooring
109
+ vec3 maxCoordinate = vec3(voxelDimensions) - vec3(0.5);
110
+ sampleCoordinate = clamp(sampleCoordinate, vec3(0.0), maxCoordinate);
111
+ ivec3 sampleIndex = ivec3(floor(sampleCoordinate));
112
+ #if defined(PADDING)
113
+ voxelDimensions += u_paddingBefore + u_paddingAfter;
114
+ sampleIndex += u_paddingBefore;
115
+ #endif
116
+ // Convert to a 1D index for lookup in a 1D data array
117
+ return sampleIndex.x + voxelDimensions.x * (sampleIndex.y + voxelDimensions.y * sampleIndex.z);
43
118
  }
44
119
 
45
120
  void main()
@@ -50,11 +125,13 @@ void main()
50
125
  vec3 viewDirWorld = normalize(czm_inverseViewRotation * eyeDirection); // normalize again just in case
51
126
  vec3 viewDirUv = normalize(u_transformDirectionViewToLocal * eyeDirection); // normalize again just in case
52
127
  vec3 viewPosUv = u_cameraPositionUv;
53
- #if defined(SHAPE_BOX)
54
- vec3 dInv = 1.0 / viewDirUv;
55
- Ray viewRayUv = Ray(viewPosUv, viewDirUv, dInv);
128
+ #if defined(SHAPE_ELLIPSOID)
129
+ // viewDirUv has been scaled to a space where the ellipsoid is a sphere.
130
+ // Undo this scaling to get the raw direction.
131
+ vec3 rawDir = viewDirUv * u_ellipsoidRadiiUv;
132
+ Ray viewRayUv = Ray(viewPosUv, viewDirUv, rawDir);
56
133
  #else
57
- Ray viewRayUv = Ray(viewPosUv, viewDirUv);
134
+ Ray viewRayUv = Ray(viewPosUv, viewDirUv, viewDirUv);
58
135
  #endif
59
136
 
60
137
  Intersections ix;
@@ -65,20 +142,20 @@ void main()
65
142
  discard;
66
143
  }
67
144
 
68
- float currT = shapeIntersection.entry.w * RAY_SCALE;
145
+ float currentT = shapeIntersection.entry.w;
69
146
  float endT = shapeIntersection.exit.w;
70
- vec3 positionUv = viewPosUv + currT * viewDirUv;
71
- vec3 positionUvShapeSpace = convertUvToShapeUvSpace(positionUv);
147
+ vec3 positionUv = viewPosUv + currentT * viewDirUv;
148
+ PointJacobianT pointJacobian = convertUvToShapeUvSpaceDerivative(positionUv);
72
149
 
73
150
  // Traverse the tree from the start position
74
151
  TraversalData traversalData;
75
152
  SampleData sampleDatas[SAMPLE_COUNT];
76
- traverseOctreeFromBeginning(positionUvShapeSpace, traversalData, sampleDatas);
77
- vec4 step = getStepSize(sampleDatas[0], viewRayUv, shapeIntersection);
153
+ traverseOctreeFromBeginning(pointJacobian.point, traversalData, sampleDatas);
154
+ vec4 step = getStepSize(sampleDatas[0], viewRayUv, shapeIntersection, pointJacobian.jacobianT, currentT);
78
155
 
79
156
  #if defined(JITTER)
80
157
  float noise = hash(screenCoord); // [0,1]
81
- currT += noise * step.w;
158
+ currentT += noise * step.w;
82
159
  positionUv += noise * step.w * viewDirUv;
83
160
  #endif
84
161
 
@@ -87,7 +164,7 @@ void main()
87
164
  setStatistics(fragmentInput.metadata.statistics);
88
165
  #endif
89
166
 
90
- vec4 colorAccum =vec4(0.0);
167
+ vec4 colorAccum = vec4(0.0);
91
168
 
92
169
  for (int stepCount = 0; stepCount < STEP_COUNT_MAX; ++stepCount) {
93
170
  // Read properties from the megatexture based on the traversal state
@@ -96,12 +173,15 @@ void main()
96
173
  // Prepare the custom shader inputs
97
174
  copyPropertiesToMetadata(properties, fragmentInput.metadata);
98
175
  fragmentInput.voxel.positionUv = positionUv;
99
- fragmentInput.voxel.positionShapeUv = positionUvShapeSpace;
176
+ fragmentInput.voxel.positionShapeUv = pointJacobian.point;
100
177
  fragmentInput.voxel.positionUvLocal = sampleDatas[0].tileUv;
101
178
  fragmentInput.voxel.viewDirUv = viewDirUv;
102
179
  fragmentInput.voxel.viewDirWorld = viewDirWorld;
103
180
  fragmentInput.voxel.surfaceNormal = step.xyz;
104
181
  fragmentInput.voxel.travelDistance = step.w;
182
+ fragmentInput.voxel.stepCount = stepCount;
183
+ fragmentInput.voxel.tileIndex = sampleDatas[0].megatextureIndex;
184
+ fragmentInput.voxel.sampleIndex = getSampleIndex(sampleDatas[0].tileUv);
105
185
 
106
186
  // Run the custom shader
107
187
  czm_modelMaterial materialOutput;
@@ -128,11 +208,11 @@ void main()
128
208
  }
129
209
 
130
210
  // Keep raymarching
131
- currT += step.w;
132
- positionUv += step.w * viewDirUv;
211
+ currentT += step.w;
212
+ positionUv = viewPosUv + currentT * viewDirUv;
133
213
 
134
214
  // Check if there's more intersections.
135
- if (currT > endT) {
215
+ if (currentT > endT) {
136
216
  #if (INTERSECTION_COUNT == 1)
137
217
  break;
138
218
  #else
@@ -141,18 +221,18 @@ void main()
141
221
  break;
142
222
  } else {
143
223
  // Found another intersection. Resume raymarching there
144
- currT = shapeIntersection.entry.w * RAY_SCALE;
224
+ currentT = shapeIntersection.entry.w;
145
225
  endT = shapeIntersection.exit.w;
146
- positionUv = viewPosUv + currT * viewDirUv;
226
+ positionUv = viewPosUv + currentT * viewDirUv;
147
227
  }
148
228
  #endif
149
229
  }
150
230
 
151
231
  // Traverse the tree from the current ray position.
152
232
  // This is similar to traverseOctreeFromBeginning but is faster when the ray is in the same tile as the previous step.
153
- positionUvShapeSpace = convertUvToShapeUvSpace(positionUv);
154
- traverseOctreeFromExisting(positionUvShapeSpace, traversalData, sampleDatas);
155
- step = getStepSize(sampleDatas[0], viewRayUv, shapeIntersection);
233
+ pointJacobian = convertUvToShapeUvSpaceDerivative(positionUv);
234
+ traverseOctreeFromExisting(pointJacobian.point, traversalData, sampleDatas);
235
+ step = getStepSize(sampleDatas[0], viewRayUv, shapeIntersection, pointJacobian.jacobianT, currentT);
156
236
  }
157
237
 
158
238
  // Convert the alpha from [0,ALPHA_ACCUM_MAX] to [0,1]
@@ -164,6 +244,14 @@ void main()
164
244
  discard;
165
245
  }
166
246
  out_FragColor = u_pickColor;
247
+ #elif defined(PICKING_VOXEL)
248
+ // If alpha is 0.0 there is nothing to pick
249
+ if (colorAccum.a == 0.0) {
250
+ discard;
251
+ }
252
+ vec2 megatextureId = packIntToVec2(sampleDatas[0].megatextureIndex);
253
+ vec2 sampleIndex = packIntToVec2(getSampleIndex(sampleDatas[0].tileUv));
254
+ out_FragColor = vec4(megatextureId, sampleIndex);
167
255
  #else
168
256
  out_FragColor = colorAccum;
169
257
  #endif
@@ -10,7 +10,11 @@ export default "// See Intersection.glsl for the definition of intersectScene\n\
10
10
  // See Megatexture.glsl for the definition of accumulatePropertiesFromMegatexture\n\
11
11
  \n\
12
12
  #define STEP_COUNT_MAX 1000 // Harcoded value because GLSL doesn't like variable length loops\n\
13
- #define ALPHA_ACCUM_MAX 0.98 // Must be > 0.0 and <= 1.0\n\
13
+ #if defined(PICKING_VOXEL)\n\
14
+ #define ALPHA_ACCUM_MAX 0.1\n\
15
+ #else\n\
16
+ #define ALPHA_ACCUM_MAX 0.98 // Must be > 0.0 and <= 1.0\n\
17
+ #endif\n\
14
18
  \n\
15
19
  uniform mat3 u_transformDirectionViewToLocal;\n\
16
20
  uniform vec3 u_cameraPositionUv;\n\
@@ -20,27 +24,98 @@ uniform float u_stepSize;\n\
20
24
  uniform vec4 u_pickColor;\n\
21
25
  #endif\n\
22
26
  \n\
23
- #if defined(JITTER)\n\
24
- float hash(vec2 p)\n\
25
- {\n\
26
- vec3 p3 = fract(vec3(p.xyx) * 50.0); // magic number = hashscale\n\
27
- p3 += dot(p3, p3.yzx + 19.19);\n\
28
- return fract((p3.x + p3.y) * p3.z);\n\
27
+ vec3 getSampleSize(in int level) {\n\
28
+ vec3 sampleCount = exp2(float(level)) * vec3(u_dimensions);\n\
29
+ vec3 sampleSizeUv = 1.0 / sampleCount;\n\
30
+ return scaleShapeUvToShapeSpace(sampleSizeUv);\n\
29
31
  }\n\
30
- #endif\n\
31
32
  \n\
32
- vec4 getStepSize(in SampleData sampleData, in Ray viewRay, in RayShapeIntersection shapeIntersection) {\n\
33
- #if defined(SHAPE_BOX)\n\
34
- Box voxelBox = constructVoxelBox(sampleData.tileCoords, sampleData.tileUv);\n\
35
- RayShapeIntersection voxelIntersection = intersectBox(viewRay, voxelBox);\n\
36
- vec4 entry = shapeIntersection.entry.w >= voxelIntersection.entry.w ? shapeIntersection.entry : voxelIntersection.entry;\n\
37
- float exit = min(voxelIntersection.exit.w, shapeIntersection.exit.w);\n\
38
- float dt = (exit - entry.w) * RAY_SCALE;\n\
39
- return vec4(normalize(entry.xyz), dt);\n\
40
- #else\n\
41
- float dimAtLevel = pow(2.0, float(sampleData.tileCoords.w));\n\
42
- return vec4(viewRay.dir, u_stepSize / dimAtLevel);\n\
43
- #endif\n\
33
+ #define MINIMUM_STEP_SCALAR (0.02)\n\
34
+ #define SHIFT_FRACTION (0.001)\n\
35
+ \n\
36
+ /**\n\
37
+ * Given a coordinate within a tile, and sample spacings along a ray through\n\
38
+ * the coordinate, find the distance to the points where the ray entered and\n\
39
+ * exited the voxel cell, along with the surface normals at those points.\n\
40
+ * The surface normals are returned in shape space coordinates.\n\
41
+ */\n\
42
+ RayShapeIntersection getVoxelIntersection(in vec3 tileUv, in vec3 sampleSizeAlongRay) {\n\
43
+ vec3 voxelCoord = tileUv * vec3(u_dimensions);\n\
44
+ vec3 directions = sign(sampleSizeAlongRay);\n\
45
+ vec3 positiveDirections = max(directions, 0.0);\n\
46
+ vec3 entryCoord = mix(ceil(voxelCoord), floor(voxelCoord), positiveDirections);\n\
47
+ vec3 exitCoord = entryCoord + directions;\n\
48
+ \n\
49
+ vec3 distanceFromEntry = -abs((entryCoord - voxelCoord) * sampleSizeAlongRay);\n\
50
+ float lastEntry = maxComponent(distanceFromEntry);\n\
51
+ bvec3 isLastEntry = equal(distanceFromEntry, vec3(lastEntry));\n\
52
+ vec3 entryNormal = -1.0 * vec3(isLastEntry) * directions;\n\
53
+ vec4 entry = vec4(entryNormal, lastEntry);\n\
54
+ \n\
55
+ vec3 distanceToExit = abs((exitCoord - voxelCoord) * sampleSizeAlongRay);\n\
56
+ float firstExit = minComponent(distanceToExit);\n\
57
+ bvec3 isFirstExit = equal(distanceToExit, vec3(firstExit));\n\
58
+ vec3 exitNormal = vec3(isFirstExit) * directions;\n\
59
+ vec4 exit = vec4(exitNormal, firstExit);\n\
60
+ \n\
61
+ return RayShapeIntersection(entry, exit);\n\
62
+ }\n\
63
+ \n\
64
+ vec4 getStepSize(in SampleData sampleData, in Ray viewRay, in RayShapeIntersection shapeIntersection, in mat3 jacobianT, in float currentT) {\n\
65
+ // The Jacobian is computed in a space where the shape spans [-1, 1].\n\
66
+ // But the ray is marched in a space where the shape fills [0, 1].\n\
67
+ // So we need to scale the Jacobian by 2.\n\
68
+ vec3 gradient = 2.0 * viewRay.rawDir * jacobianT;\n\
69
+ vec3 sampleSizeAlongRay = getSampleSize(sampleData.tileCoords.w) / gradient;\n\
70
+ \n\
71
+ RayShapeIntersection voxelIntersection = getVoxelIntersection(sampleData.tileUv, sampleSizeAlongRay);\n\
72
+ \n\
73
+ // Transform normal from shape space to Cartesian space\n\
74
+ vec3 voxelNormal = normalize(jacobianT * voxelIntersection.entry.xyz);\n\
75
+ // Compare with the shape intersection, to choose the appropriate normal\n\
76
+ vec4 voxelEntry = vec4(voxelNormal, currentT + voxelIntersection.entry.w);\n\
77
+ vec4 entry = intersectionMax(shapeIntersection.entry, voxelEntry);\n\
78
+ \n\
79
+ float fixedStep = minComponent(abs(sampleSizeAlongRay)) * u_stepSize;\n\
80
+ float shift = fixedStep * SHIFT_FRACTION;\n\
81
+ float dt = voxelIntersection.exit.w + shift;\n\
82
+ if ((currentT + dt) > shapeIntersection.exit.w) {\n\
83
+ // Stop at end of shape\n\
84
+ dt = shapeIntersection.exit.w - currentT + shift;\n\
85
+ }\n\
86
+ float stepSize = clamp(dt, fixedStep * MINIMUM_STEP_SCALAR, fixedStep + shift);\n\
87
+ \n\
88
+ return vec4(entry.xyz, stepSize);\n\
89
+ }\n\
90
+ \n\
91
+ vec2 packIntToVec2(int value) {\n\
92
+ float shifted = float(value) / 255.0;\n\
93
+ float lowBits = fract(shifted);\n\
94
+ float highBits = floor(shifted) / 255.0;\n\
95
+ return vec2(highBits, lowBits);\n\
96
+ }\n\
97
+ \n\
98
+ vec2 packFloatToVec2(float value) {\n\
99
+ float lowBits = fract(value);\n\
100
+ float highBits = floor(value) / 255.0;\n\
101
+ return vec2(highBits, lowBits);\n\
102
+ }\n\
103
+ \n\
104
+ int getSampleIndex(in vec3 tileUv) {\n\
105
+ ivec3 voxelDimensions = u_dimensions;\n\
106
+ vec3 sampleCoordinate = tileUv * vec3(voxelDimensions);\n\
107
+ // tileUv = 1.0 is a valid coordinate but sampleIndex = voxelDimensions is not.\n\
108
+ // (tileUv = 1.0 corresponds to the last sample, at index = voxelDimensions - 1).\n\
109
+ // Clamp to [0, voxelDimensions - 0.5) to avoid numerical error before flooring\n\
110
+ vec3 maxCoordinate = vec3(voxelDimensions) - vec3(0.5);\n\
111
+ sampleCoordinate = clamp(sampleCoordinate, vec3(0.0), maxCoordinate);\n\
112
+ ivec3 sampleIndex = ivec3(floor(sampleCoordinate));\n\
113
+ #if defined(PADDING)\n\
114
+ voxelDimensions += u_paddingBefore + u_paddingAfter;\n\
115
+ sampleIndex += u_paddingBefore;\n\
116
+ #endif\n\
117
+ // Convert to a 1D index for lookup in a 1D data array\n\
118
+ return sampleIndex.x + voxelDimensions.x * (sampleIndex.y + voxelDimensions.y * sampleIndex.z);\n\
44
119
  }\n\
45
120
  \n\
46
121
  void main()\n\
@@ -51,11 +126,13 @@ void main()\n\
51
126
  vec3 viewDirWorld = normalize(czm_inverseViewRotation * eyeDirection); // normalize again just in case\n\
52
127
  vec3 viewDirUv = normalize(u_transformDirectionViewToLocal * eyeDirection); // normalize again just in case\n\
53
128
  vec3 viewPosUv = u_cameraPositionUv;\n\
54
- #if defined(SHAPE_BOX)\n\
55
- vec3 dInv = 1.0 / viewDirUv;\n\
56
- Ray viewRayUv = Ray(viewPosUv, viewDirUv, dInv);\n\
129
+ #if defined(SHAPE_ELLIPSOID)\n\
130
+ // viewDirUv has been scaled to a space where the ellipsoid is a sphere.\n\
131
+ // Undo this scaling to get the raw direction.\n\
132
+ vec3 rawDir = viewDirUv * u_ellipsoidRadiiUv;\n\
133
+ Ray viewRayUv = Ray(viewPosUv, viewDirUv, rawDir);\n\
57
134
  #else\n\
58
- Ray viewRayUv = Ray(viewPosUv, viewDirUv);\n\
135
+ Ray viewRayUv = Ray(viewPosUv, viewDirUv, viewDirUv);\n\
59
136
  #endif\n\
60
137
  \n\
61
138
  Intersections ix;\n\
@@ -66,20 +143,20 @@ void main()\n\
66
143
  discard;\n\
67
144
  }\n\
68
145
  \n\
69
- float currT = shapeIntersection.entry.w * RAY_SCALE;\n\
146
+ float currentT = shapeIntersection.entry.w;\n\
70
147
  float endT = shapeIntersection.exit.w;\n\
71
- vec3 positionUv = viewPosUv + currT * viewDirUv;\n\
72
- vec3 positionUvShapeSpace = convertUvToShapeUvSpace(positionUv);\n\
148
+ vec3 positionUv = viewPosUv + currentT * viewDirUv;\n\
149
+ PointJacobianT pointJacobian = convertUvToShapeUvSpaceDerivative(positionUv);\n\
73
150
  \n\
74
151
  // Traverse the tree from the start position\n\
75
152
  TraversalData traversalData;\n\
76
153
  SampleData sampleDatas[SAMPLE_COUNT];\n\
77
- traverseOctreeFromBeginning(positionUvShapeSpace, traversalData, sampleDatas);\n\
78
- vec4 step = getStepSize(sampleDatas[0], viewRayUv, shapeIntersection);\n\
154
+ traverseOctreeFromBeginning(pointJacobian.point, traversalData, sampleDatas);\n\
155
+ vec4 step = getStepSize(sampleDatas[0], viewRayUv, shapeIntersection, pointJacobian.jacobianT, currentT);\n\
79
156
  \n\
80
157
  #if defined(JITTER)\n\
81
158
  float noise = hash(screenCoord); // [0,1]\n\
82
- currT += noise * step.w;\n\
159
+ currentT += noise * step.w;\n\
83
160
  positionUv += noise * step.w * viewDirUv;\n\
84
161
  #endif\n\
85
162
  \n\
@@ -88,7 +165,7 @@ void main()\n\
88
165
  setStatistics(fragmentInput.metadata.statistics);\n\
89
166
  #endif\n\
90
167
  \n\
91
- vec4 colorAccum =vec4(0.0);\n\
168
+ vec4 colorAccum = vec4(0.0);\n\
92
169
  \n\
93
170
  for (int stepCount = 0; stepCount < STEP_COUNT_MAX; ++stepCount) {\n\
94
171
  // Read properties from the megatexture based on the traversal state\n\
@@ -97,12 +174,15 @@ void main()\n\
97
174
  // Prepare the custom shader inputs\n\
98
175
  copyPropertiesToMetadata(properties, fragmentInput.metadata);\n\
99
176
  fragmentInput.voxel.positionUv = positionUv;\n\
100
- fragmentInput.voxel.positionShapeUv = positionUvShapeSpace;\n\
177
+ fragmentInput.voxel.positionShapeUv = pointJacobian.point;\n\
101
178
  fragmentInput.voxel.positionUvLocal = sampleDatas[0].tileUv;\n\
102
179
  fragmentInput.voxel.viewDirUv = viewDirUv;\n\
103
180
  fragmentInput.voxel.viewDirWorld = viewDirWorld;\n\
104
181
  fragmentInput.voxel.surfaceNormal = step.xyz;\n\
105
182
  fragmentInput.voxel.travelDistance = step.w;\n\
183
+ fragmentInput.voxel.stepCount = stepCount;\n\
184
+ fragmentInput.voxel.tileIndex = sampleDatas[0].megatextureIndex;\n\
185
+ fragmentInput.voxel.sampleIndex = getSampleIndex(sampleDatas[0].tileUv);\n\
106
186
  \n\
107
187
  // Run the custom shader\n\
108
188
  czm_modelMaterial materialOutput;\n\
@@ -129,11 +209,11 @@ void main()\n\
129
209
  }\n\
130
210
  \n\
131
211
  // Keep raymarching\n\
132
- currT += step.w;\n\
133
- positionUv += step.w * viewDirUv;\n\
212
+ currentT += step.w;\n\
213
+ positionUv = viewPosUv + currentT * viewDirUv;\n\
134
214
  \n\
135
215
  // Check if there's more intersections.\n\
136
- if (currT > endT) {\n\
216
+ if (currentT > endT) {\n\
137
217
  #if (INTERSECTION_COUNT == 1)\n\
138
218
  break;\n\
139
219
  #else\n\
@@ -142,18 +222,18 @@ void main()\n\
142
222
  break;\n\
143
223
  } else {\n\
144
224
  // Found another intersection. Resume raymarching there\n\
145
- currT = shapeIntersection.entry.w * RAY_SCALE;\n\
225
+ currentT = shapeIntersection.entry.w;\n\
146
226
  endT = shapeIntersection.exit.w;\n\
147
- positionUv = viewPosUv + currT * viewDirUv;\n\
227
+ positionUv = viewPosUv + currentT * viewDirUv;\n\
148
228
  }\n\
149
229
  #endif\n\
150
230
  }\n\
151
231
  \n\
152
232
  // Traverse the tree from the current ray position.\n\
153
233
  // This is similar to traverseOctreeFromBeginning but is faster when the ray is in the same tile as the previous step.\n\
154
- positionUvShapeSpace = convertUvToShapeUvSpace(positionUv);\n\
155
- traverseOctreeFromExisting(positionUvShapeSpace, traversalData, sampleDatas);\n\
156
- step = getStepSize(sampleDatas[0], viewRayUv, shapeIntersection);\n\
234
+ pointJacobian = convertUvToShapeUvSpaceDerivative(positionUv);\n\
235
+ traverseOctreeFromExisting(pointJacobian.point, traversalData, sampleDatas);\n\
236
+ step = getStepSize(sampleDatas[0], viewRayUv, shapeIntersection, pointJacobian.jacobianT, currentT);\n\
157
237
  }\n\
158
238
  \n\
159
239
  // Convert the alpha from [0,ALPHA_ACCUM_MAX] to [0,1]\n\
@@ -165,6 +245,14 @@ void main()\n\
165
245
  discard;\n\
166
246
  }\n\
167
247
  out_FragColor = u_pickColor;\n\
248
+ #elif defined(PICKING_VOXEL)\n\
249
+ // If alpha is 0.0 there is nothing to pick\n\
250
+ if (colorAccum.a == 0.0) {\n\
251
+ discard;\n\
252
+ }\n\
253
+ vec2 megatextureId = packIntToVec2(sampleDatas[0].megatextureIndex);\n\
254
+ vec2 sampleIndex = packIntToVec2(getSampleIndex(sampleDatas[0].tileUv));\n\
255
+ out_FragColor = vec4(megatextureId, sampleIndex);\n\
168
256
  #else\n\
169
257
  out_FragColor = colorAccum;\n\
170
258
  #endif\n\
@@ -0,0 +1,31 @@
1
+ struct Ray {
2
+ vec3 pos;
3
+ vec3 dir;
4
+ vec3 rawDir;
5
+ };
6
+
7
+ #if defined(JITTER)
8
+ /**
9
+ * Generate a pseudo-random value for a given 2D screen coordinate.
10
+ * Similar to https://www.shadertoy.com/view/4djSRW with a modified hashscale.
11
+ */
12
+ float hash(vec2 p)
13
+ {
14
+ vec3 p3 = fract(vec3(p.xyx) * 50.0);
15
+ p3 += dot(p3, p3.yzx + 19.19);
16
+ return fract((p3.x + p3.y) * p3.z);
17
+ }
18
+ #endif
19
+
20
+ float minComponent(in vec3 v) {
21
+ return min(min(v.x, v.y), v.z);
22
+ }
23
+
24
+ float maxComponent(in vec3 v) {
25
+ return max(max(v.x, v.y), v.z);
26
+ }
27
+
28
+ struct PointJacobianT {
29
+ vec3 point;
30
+ mat3 jacobianT;
31
+ };
@@ -0,0 +1,33 @@
1
+ //This file is automatically rebuilt by the Cesium build process.
2
+ export default "struct Ray {\n\
3
+ vec3 pos;\n\
4
+ vec3 dir;\n\
5
+ vec3 rawDir;\n\
6
+ };\n\
7
+ \n\
8
+ #if defined(JITTER)\n\
9
+ /**\n\
10
+ * Generate a pseudo-random value for a given 2D screen coordinate.\n\
11
+ * Similar to https://www.shadertoy.com/view/4djSRW with a modified hashscale.\n\
12
+ */\n\
13
+ float hash(vec2 p)\n\
14
+ {\n\
15
+ vec3 p3 = fract(vec3(p.xyx) * 50.0);\n\
16
+ p3 += dot(p3, p3.yzx + 19.19);\n\
17
+ return fract((p3.x + p3.y) * p3.z);\n\
18
+ }\n\
19
+ #endif\n\
20
+ \n\
21
+ float minComponent(in vec3 v) {\n\
22
+ return min(min(v.x, v.y), v.z);\n\
23
+ }\n\
24
+ \n\
25
+ float maxComponent(in vec3 v) {\n\
26
+ return max(max(v.x, v.y), v.z);\n\
27
+ }\n\
28
+ \n\
29
+ struct PointJacobianT {\n\
30
+ vec3 point;\n\
31
+ mat3 jacobianT;\n\
32
+ };\n\
33
+ ";
@@ -7,14 +7,27 @@
7
7
  uniform vec3 u_boxUvToShapeUvTranslate;
8
8
  #endif
9
9
 
10
- vec3 convertUvToShapeUvSpace(in vec3 positionUv) {
10
+ PointJacobianT convertUvToShapeSpaceDerivative(in vec3 positionUv) {
11
+ // For BOX, UV space = shape space, so we can use positionUv as-is,
12
+ // and the Jacobian is the identity matrix, except that a step of 1
13
+ // only spans half the shape space [-1, 1], so the identity is scaled.
14
+ return PointJacobianT(positionUv, mat3(0.5));
15
+ }
16
+
17
+ vec3 convertShapeToShapeUvSpace(in vec3 positionShape) {
11
18
  #if defined(BOX_HAS_SHAPE_BOUNDS)
12
- return positionUv * u_boxUvToShapeUvScale + u_boxUvToShapeUvTranslate;
19
+ return positionShape * u_boxUvToShapeUvScale + u_boxUvToShapeUvTranslate;
13
20
  #else
14
- return positionUv;
21
+ return positionShape;
15
22
  #endif
16
23
  }
17
24
 
25
+ PointJacobianT convertUvToShapeUvSpaceDerivative(in vec3 positionUv) {
26
+ PointJacobianT pointJacobian = convertUvToShapeSpaceDerivative(positionUv);
27
+ pointJacobian.point = convertShapeToShapeUvSpace(pointJacobian.point);
28
+ return pointJacobian;
29
+ }
30
+
18
31
  vec3 convertShapeUvToUvSpace(in vec3 shapeUv) {
19
32
  #if defined(BOX_HAS_SHAPE_BOUNDS)
20
33
  return (shapeUv - u_boxUvToShapeUvTranslate) / u_boxUvToShapeUvScale;
@@ -22,3 +35,11 @@ vec3 convertShapeUvToUvSpace(in vec3 shapeUv) {
22
35
  return shapeUv;
23
36
  #endif
24
37
  }
38
+
39
+ vec3 scaleShapeUvToShapeSpace(in vec3 shapeUv) {
40
+ #if defined(BOX_HAS_SHAPE_BOUNDS)
41
+ return shapeUv / u_boxUvToShapeUvScale;
42
+ #else
43
+ return shapeUv;
44
+ #endif
45
+ }
@@ -8,14 +8,27 @@ export default "/* Box defines (set in Scene/VoxelBoxShape.js)\n\
8
8
  uniform vec3 u_boxUvToShapeUvTranslate;\n\
9
9
  #endif\n\
10
10
  \n\
11
- vec3 convertUvToShapeUvSpace(in vec3 positionUv) {\n\
11
+ PointJacobianT convertUvToShapeSpaceDerivative(in vec3 positionUv) {\n\
12
+ // For BOX, UV space = shape space, so we can use positionUv as-is,\n\
13
+ // and the Jacobian is the identity matrix, except that a step of 1\n\
14
+ // only spans half the shape space [-1, 1], so the identity is scaled.\n\
15
+ return PointJacobianT(positionUv, mat3(0.5));\n\
16
+ }\n\
17
+ \n\
18
+ vec3 convertShapeToShapeUvSpace(in vec3 positionShape) {\n\
12
19
  #if defined(BOX_HAS_SHAPE_BOUNDS)\n\
13
- return positionUv * u_boxUvToShapeUvScale + u_boxUvToShapeUvTranslate;\n\
20
+ return positionShape * u_boxUvToShapeUvScale + u_boxUvToShapeUvTranslate;\n\
14
21
  #else\n\
15
- return positionUv;\n\
22
+ return positionShape;\n\
16
23
  #endif\n\
17
24
  }\n\
18
25
  \n\
26
+ PointJacobianT convertUvToShapeUvSpaceDerivative(in vec3 positionUv) {\n\
27
+ PointJacobianT pointJacobian = convertUvToShapeSpaceDerivative(positionUv);\n\
28
+ pointJacobian.point = convertShapeToShapeUvSpace(pointJacobian.point);\n\
29
+ return pointJacobian;\n\
30
+ }\n\
31
+ \n\
19
32
  vec3 convertShapeUvToUvSpace(in vec3 shapeUv) {\n\
20
33
  #if defined(BOX_HAS_SHAPE_BOUNDS)\n\
21
34
  return (shapeUv - u_boxUvToShapeUvTranslate) / u_boxUvToShapeUvScale;\n\
@@ -23,4 +36,11 @@ vec3 convertShapeUvToUvSpace(in vec3 shapeUv) {\n\
23
36
  return shapeUv;\n\
24
37
  #endif\n\
25
38
  }\n\
26
- ";
39
+ \n\
40
+ vec3 scaleShapeUvToShapeSpace(in vec3 shapeUv) {\n\
41
+ #if defined(BOX_HAS_SHAPE_BOUNDS)\n\
42
+ return shapeUv / u_boxUvToShapeUvScale;\n\
43
+ #else\n\
44
+ return shapeUv;\n\
45
+ #endif\n\
46
+ }";