@cesium/engine 0.1.0 → 1.1.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 (217) hide show
  1. package/Build/Workers/{AttributeCompression-4589338a.js → AttributeCompression-b646d393.js} +1 -1
  2. package/Build/Workers/{AxisAlignedBoundingBox-bfb1234f.js → AxisAlignedBoundingBox-a4321399.js} +1 -1
  3. package/Build/Workers/{BoundingRectangle-7ffc2153.js → BoundingRectangle-80d8801f.js} +1 -1
  4. package/Build/Workers/{BoxGeometry-93f344a3.js → BoxGeometry-33c10a4f.js} +1 -1
  5. package/Build/Workers/{Color-0c5aaf47.js → Color-1bf9a6e0.js} +1 -1
  6. package/Build/Workers/{CoplanarPolygonGeometryLibrary-6597982a.js → CoplanarPolygonGeometryLibrary-5c5b981b.js} +1 -1
  7. package/Build/Workers/{CorridorGeometryLibrary-2119580e.js → CorridorGeometryLibrary-7cbae7a0.js} +1 -1
  8. package/Build/Workers/{CylinderGeometry-f9503c6d.js → CylinderGeometry-42740df0.js} +1 -1
  9. package/Build/Workers/{EllipseGeometry-fedf72d5.js → EllipseGeometry-49a3ac21.js} +1 -1
  10. package/Build/Workers/{EllipseGeometryLibrary-4ea68687.js → EllipseGeometryLibrary-b891b2f8.js} +1 -1
  11. package/Build/Workers/{EllipseOutlineGeometry-e2ae6a35.js → EllipseOutlineGeometry-fbd72e07.js} +1 -1
  12. package/Build/Workers/{EllipsoidGeodesic-16de63ea.js → EllipsoidGeodesic-98c62a56.js} +1 -1
  13. package/Build/Workers/{EllipsoidGeometry-95c0330e.js → EllipsoidGeometry-a351dba8.js} +1 -1
  14. package/Build/Workers/{EllipsoidOutlineGeometry-d6d2ceec.js → EllipsoidOutlineGeometry-3e8779bf.js} +1 -1
  15. package/Build/Workers/{EllipsoidRhumbLine-ae5e65e0.js → EllipsoidRhumbLine-19756602.js} +1 -1
  16. package/Build/Workers/{EllipsoidTangentPlane-bfc674bf.js → EllipsoidTangentPlane-cfb50678.js} +1 -1
  17. package/Build/Workers/{EncodedCartesian3-f473ea18.js → EncodedCartesian3-81f70735.js} +1 -1
  18. package/Build/Workers/{FrustumGeometry-3bf2e4eb.js → FrustumGeometry-c5754412.js} +1 -1
  19. package/Build/Workers/{GeometryAttribute-df5f473e.js → GeometryAttribute-0bfd05e8.js} +1 -1
  20. package/Build/Workers/{GeometryInstance-aa75b4cf.js → GeometryInstance-451dc1cd.js} +1 -1
  21. package/Build/Workers/{GeometryPipeline-f0e46c42.js → GeometryPipeline-0166905d.js} +1 -1
  22. package/Build/Workers/{IntersectionTests-9de29d51.js → IntersectionTests-a93d3de9.js} +1 -1
  23. package/Build/Workers/{Matrix2-ce637455.js → Matrix2-13178034.js} +4 -2
  24. package/Build/Workers/{Matrix3-4f4df527.js → Matrix3-315394f6.js} +2 -1
  25. package/Build/Workers/{OrientedBoundingBox-d3ff3d4d.js → OrientedBoundingBox-b450cb61.js} +5 -5
  26. package/Build/Workers/{Plane-b81241c2.js → Plane-900aa728.js} +1 -1
  27. package/Build/Workers/{PolygonGeometryLibrary-6f4937bb.js → PolygonGeometryLibrary-f918ac26.js} +1 -1
  28. package/Build/Workers/PolygonPipeline-f59a8f0a.js +1345 -0
  29. package/Build/Workers/{PolylinePipeline-2e2b015c.js → PolylinePipeline-d8e6bd9b.js} +1 -1
  30. package/Build/Workers/{PolylineVolumeGeometryLibrary-7ee1d449.js → PolylineVolumeGeometryLibrary-125d2edf.js} +1 -1
  31. package/Build/Workers/{PrimitivePipeline-a9b7aae0.js → PrimitivePipeline-0d7b5ed4.js} +1 -1
  32. package/Build/Workers/{RectangleGeometryLibrary-9aa6c8f6.js → RectangleGeometryLibrary-0768db63.js} +1 -1
  33. package/Build/Workers/{TerrainEncoding-b52dcfc5.js → TerrainEncoding-06470d7f.js} +1 -1
  34. package/Build/Workers/{Transforms-2f755df8.js → Transforms-26539bce.js} +97 -83
  35. package/Build/Workers/{WallGeometryLibrary-ab19a93d.js → WallGeometryLibrary-6167b0fc.js} +1 -1
  36. package/Build/Workers/{WebMercatorProjection-9f25de49.js → WebMercatorProjection-13a90d41.js} +1 -1
  37. package/Build/Workers/cesiumWorkerBootstrapper.js +25 -1
  38. package/Build/Workers/combineGeometry.js +1 -1
  39. package/Build/Workers/createBoxGeometry.js +1 -1
  40. package/Build/Workers/createBoxOutlineGeometry.js +1 -1
  41. package/Build/Workers/createCircleGeometry.js +1 -1
  42. package/Build/Workers/createCircleOutlineGeometry.js +1 -1
  43. package/Build/Workers/createCoplanarPolygonGeometry.js +1 -1
  44. package/Build/Workers/createCoplanarPolygonOutlineGeometry.js +1 -1
  45. package/Build/Workers/createCorridorGeometry.js +1 -1
  46. package/Build/Workers/createCorridorOutlineGeometry.js +1 -1
  47. package/Build/Workers/createCylinderGeometry.js +1 -1
  48. package/Build/Workers/createCylinderOutlineGeometry.js +1 -1
  49. package/Build/Workers/createEllipseGeometry.js +1 -1
  50. package/Build/Workers/createEllipseOutlineGeometry.js +1 -1
  51. package/Build/Workers/createEllipsoidGeometry.js +1 -1
  52. package/Build/Workers/createEllipsoidOutlineGeometry.js +1 -1
  53. package/Build/Workers/createFrustumGeometry.js +1 -1
  54. package/Build/Workers/createFrustumOutlineGeometry.js +1 -1
  55. package/Build/Workers/createGeometry.js +1 -1
  56. package/Build/Workers/createGroundPolylineGeometry.js +1 -1
  57. package/Build/Workers/createPlaneGeometry.js +1 -1
  58. package/Build/Workers/createPlaneOutlineGeometry.js +1 -1
  59. package/Build/Workers/createPolygonGeometry.js +1 -1
  60. package/Build/Workers/createPolygonOutlineGeometry.js +1 -1
  61. package/Build/Workers/createPolylineGeometry.js +1 -1
  62. package/Build/Workers/createPolylineVolumeGeometry.js +1 -1
  63. package/Build/Workers/createPolylineVolumeOutlineGeometry.js +1 -1
  64. package/Build/Workers/createRectangleGeometry.js +1 -1
  65. package/Build/Workers/createRectangleOutlineGeometry.js +1 -1
  66. package/Build/Workers/createSimplePolylineGeometry.js +1 -1
  67. package/Build/Workers/createSphereGeometry.js +1 -1
  68. package/Build/Workers/createSphereOutlineGeometry.js +1 -1
  69. package/Build/Workers/createVectorTileClampedPolylines.js +1 -1
  70. package/Build/Workers/createVectorTileGeometries.js +1 -1
  71. package/Build/Workers/createVectorTilePoints.js +1 -1
  72. package/Build/Workers/createVectorTilePolygons.js +1 -1
  73. package/Build/Workers/createVectorTilePolylines.js +1 -1
  74. package/Build/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js +1 -1
  75. package/Build/Workers/createVerticesFromHeightmap.js +7 -3
  76. package/Build/Workers/createVerticesFromQuantizedTerrainMesh.js +1 -1
  77. package/Build/Workers/createWallGeometry.js +1 -1
  78. package/Build/Workers/createWallOutlineGeometry.js +1 -1
  79. package/Build/Workers/decodeGoogleEarthEnterprisePacket.js +95 -76
  80. package/Build/Workers/decodeI3S.js +1 -1
  81. package/Build/Workers/package.js +25 -1
  82. package/Build/Workers/transferTypedArrayTest.js +25 -1
  83. package/Build/Workers/upsampleQuantizedTerrainMesh.js +1 -1
  84. package/README.md +9 -9
  85. package/Source/Core/EarthOrientationParameters.js +67 -63
  86. package/Source/Core/Ion.js +1 -1
  87. package/Source/Core/Matrix2.js +2 -1
  88. package/Source/Core/Matrix3.js +2 -1
  89. package/Source/Core/Matrix4.js +1 -0
  90. package/Source/Core/OrientedBoundingBox.js +4 -4
  91. package/Source/Core/S2Cell.js +3 -3
  92. package/Source/Core/Transforms.js +3 -7
  93. package/Source/DataSources/GpxDataSource.js +4 -6
  94. package/Source/DataSources/KmlDataSource.js +3 -5
  95. package/Source/Renderer/Context.js +230 -177
  96. package/Source/Renderer/Pass.js +3 -2
  97. package/Source/Scene/Cesium3DTileContentType.js +19 -0
  98. package/Source/Scene/Cesium3DTilesVoxelProvider.js +482 -0
  99. package/Source/Scene/Cesium3DTilesetMetadata.js +2 -2
  100. package/Source/Scene/ContentMetadata.js +2 -2
  101. package/Source/Scene/DerivedCommand.js +7 -0
  102. package/Source/Scene/Expression.js +1 -1
  103. package/Source/Scene/Globe.js +10 -0
  104. package/Source/Scene/GlobeSurfaceTileProvider.js +7 -0
  105. package/Source/Scene/GltfImageLoader.js +1 -1
  106. package/Source/Scene/GltfVertexBufferLoader.js +10 -2
  107. package/Source/Scene/GroupMetadata.js +2 -2
  108. package/Source/Scene/I3SDataProvider.js +2 -1
  109. package/Source/Scene/I3SFeature.js +1 -1
  110. package/Source/Scene/I3SLayer.js +64 -2
  111. package/Source/Scene/I3SNode.js +50 -6
  112. package/Source/Scene/ImplicitMetadataView.js +2 -2
  113. package/Source/Scene/ImplicitSubtreeCache.js +127 -0
  114. package/Source/Scene/ImplicitSubtreeMetadata.js +2 -2
  115. package/Source/Scene/ImplicitTileset.js +3 -2
  116. package/Source/Scene/KeyframeNode.js +47 -0
  117. package/Source/Scene/Megatexture.js +490 -0
  118. package/Source/Scene/MetadataClass.js +60 -25
  119. package/Source/Scene/MetadataClassProperty.js +132 -68
  120. package/Source/Scene/MetadataComponentType.js +78 -57
  121. package/Source/Scene/MetadataEnum.js +59 -23
  122. package/Source/Scene/MetadataEnumValue.js +49 -15
  123. package/Source/Scene/MetadataSchema.js +53 -24
  124. package/Source/Scene/MetadataSchemaLoader.js +2 -2
  125. package/Source/Scene/MetadataTableProperty.js +2 -2
  126. package/Source/Scene/MetadataType.js +6 -14
  127. package/Source/Scene/Model/GeoJsonLoader.js +1 -1
  128. package/Source/Scene/Model/Model.js +38 -6
  129. package/Source/Scene/Model/buildDrawCommand.js +19 -11
  130. package/Source/Scene/PointCloud.js +1 -1
  131. package/Source/Scene/PropertyAttribute.js +2 -2
  132. package/Source/Scene/PropertyAttributeProperty.js +2 -2
  133. package/Source/Scene/PropertyTable.js +2 -2
  134. package/Source/Scene/PropertyTexture.js +2 -2
  135. package/Source/Scene/PropertyTextureProperty.js +2 -2
  136. package/Source/Scene/ResourceCache.js +9 -1
  137. package/Source/Scene/ResourceCacheKey.js +9 -1
  138. package/Source/Scene/Scene.js +20 -50
  139. package/Source/Scene/SpatialNode.js +375 -0
  140. package/Source/Scene/StructuralMetadata.js +2 -2
  141. package/Source/Scene/TileMetadata.js +2 -2
  142. package/Source/Scene/TilesetMetadata.js +2 -2
  143. package/Source/Scene/VoxelBoxShape.js +527 -0
  144. package/Source/Scene/VoxelContent.js +169 -0
  145. package/Source/Scene/VoxelCylinderShape.js +937 -0
  146. package/Source/Scene/VoxelEllipsoidShape.js +937 -0
  147. package/Source/Scene/VoxelPrimitive.js +1919 -0
  148. package/Source/Scene/VoxelProvider.js +255 -0
  149. package/Source/Scene/VoxelRenderResources.js +224 -0
  150. package/Source/Scene/VoxelShape.js +152 -0
  151. package/Source/Scene/VoxelShapeType.js +105 -0
  152. package/Source/Scene/VoxelTraversal.js +1144 -0
  153. package/Source/Scene/buildVoxelDrawCommands.js +116 -0
  154. package/Source/Scene/parseBatchTable.js +18 -2
  155. package/Source/Scene/preprocess3DTileContent.js +8 -0
  156. package/Source/Scene/processVoxelProperties.js +455 -0
  157. package/Source/Shaders/BillboardCollectionVS.glsl +1 -1
  158. package/Source/Shaders/BillboardCollectionVS.js +1 -1
  159. package/Source/Shaders/Builtin/Constants/passOverlay.glsl +1 -1
  160. package/Source/Shaders/Builtin/Constants/passOverlay.js +1 -1
  161. package/Source/Shaders/Builtin/Constants/passVoxels.glsl +9 -0
  162. package/Source/Shaders/Builtin/Constants/passVoxels.js +11 -0
  163. package/Source/Shaders/Builtin/CzmBuiltins.js +2 -0
  164. package/Source/Shaders/Builtin/Functions/windowToEyeCoordinates.glsl +55 -43
  165. package/Source/Shaders/Builtin/Functions/windowToEyeCoordinates.js +55 -43
  166. package/Source/Shaders/GlobeFS.glsl +2 -1
  167. package/Source/Shaders/GlobeFS.js +2 -1
  168. package/Source/Shaders/PointPrimitiveCollectionVS.glsl +5 -2
  169. package/Source/Shaders/PointPrimitiveCollectionVS.js +5 -2
  170. package/Source/Shaders/Voxels/IntersectBox.glsl +79 -0
  171. package/Source/Shaders/Voxels/IntersectBox.js +81 -0
  172. package/Source/Shaders/Voxels/IntersectClippingPlanes.glsl +70 -0
  173. package/Source/Shaders/Voxels/IntersectClippingPlanes.js +72 -0
  174. package/Source/Shaders/Voxels/IntersectCylinder.glsl +273 -0
  175. package/Source/Shaders/Voxels/IntersectCylinder.js +275 -0
  176. package/Source/Shaders/Voxels/IntersectDepth.glsl +23 -0
  177. package/Source/Shaders/Voxels/IntersectDepth.js +25 -0
  178. package/Source/Shaders/Voxels/IntersectEllipsoid.glsl +337 -0
  179. package/Source/Shaders/Voxels/IntersectEllipsoid.js +339 -0
  180. package/Source/Shaders/Voxels/Intersection.glsl +54 -0
  181. package/Source/Shaders/Voxels/Intersection.js +56 -0
  182. package/Source/Shaders/Voxels/IntersectionUtils.glsl +151 -0
  183. package/Source/Shaders/Voxels/IntersectionUtils.js +153 -0
  184. package/Source/Shaders/Voxels/Megatexture.glsl +136 -0
  185. package/Source/Shaders/Voxels/Megatexture.js +138 -0
  186. package/Source/Shaders/Voxels/Octree.glsl +221 -0
  187. package/Source/Shaders/Voxels/Octree.js +223 -0
  188. package/Source/Shaders/Voxels/VoxelFS.glsl +150 -0
  189. package/Source/Shaders/Voxels/VoxelFS.js +152 -0
  190. package/Source/Shaders/Voxels/VoxelVS.glsl +11 -0
  191. package/Source/Shaders/Voxels/VoxelVS.js +13 -0
  192. package/Source/Shaders/Voxels/convertUvToBox.glsl +16 -0
  193. package/Source/Shaders/Voxels/convertUvToBox.js +18 -0
  194. package/Source/Shaders/Voxels/convertUvToCylinder.glsl +79 -0
  195. package/Source/Shaders/Voxels/convertUvToCylinder.js +81 -0
  196. package/Source/Shaders/Voxels/convertUvToEllipsoid.glsl +133 -0
  197. package/Source/Shaders/Voxels/convertUvToEllipsoid.js +135 -0
  198. package/Source/ThirdParty/Workers/draco_decoder_nodejs.js +100 -101
  199. package/Source/ThirdParty/Workers/pako_deflate.min.js +2 -2
  200. package/Source/ThirdParty/Workers/pako_inflate.min.js +2 -2
  201. package/Source/ThirdParty/draco_decoder.wasm +0 -0
  202. package/Source/Widget/CesiumWidget.js +1 -1
  203. package/index.d.ts +961 -56
  204. package/index.js +92 -60
  205. package/package.json +6 -4
  206. package/Build/ThirdParty/Workers/basis_transcoder.js +0 -2233
  207. package/Build/ThirdParty/Workers/draco_decoder_nodejs.js +0 -1872
  208. package/Build/ThirdParty/Workers/package.json +0 -1
  209. package/Build/ThirdParty/Workers/pako_deflate.min.js +0 -589
  210. package/Build/ThirdParty/Workers/pako_inflate.min.js +0 -798
  211. package/Build/ThirdParty/Workers/z-worker-pako.js +0 -503
  212. package/Build/ThirdParty/basis_transcoder.wasm +0 -0
  213. package/Build/ThirdParty/draco_decoder.wasm +0 -0
  214. package/Build/ThirdParty/google-earth-dbroot-parser.js +0 -8019
  215. package/Build/Widget/CesiumWidget.css +0 -120
  216. package/Build/Widget/lighter.css +0 -13
  217. package/Build/Workers/PolygonPipeline-774a8aaf.js +0 -1341
@@ -0,0 +1,221 @@
1
+ // These octree flags must be in sync with GpuOctreeFlag in VoxelTraversal.js
2
+ #define OCTREE_FLAG_INTERNAL 0
3
+ #define OCTREE_FLAG_LEAF 1
4
+ #define OCTREE_FLAG_PACKED_LEAF_FROM_PARENT 2
5
+
6
+ #define OCTREE_MAX_LEVELS 32 // Harcoded value because GLSL doesn't like variable length loops
7
+
8
+ uniform sampler2D u_octreeInternalNodeTexture;
9
+ uniform vec2 u_octreeInternalNodeTexelSizeUv;
10
+ uniform int u_octreeInternalNodeTilesPerRow;
11
+ uniform sampler2D u_octreeLeafNodeTexture;
12
+ uniform vec2 u_octreeLeafNodeTexelSizeUv;
13
+ uniform int u_octreeLeafNodeTilesPerRow;
14
+
15
+ uniform float u_stepSize;
16
+
17
+ struct OctreeNodeData {
18
+ int data;
19
+ int flag;
20
+ };
21
+
22
+ struct TraversalData {
23
+ float stepT;
24
+ ivec4 octreeCoords;
25
+ int parentOctreeIndex;
26
+ };
27
+
28
+ struct SampleData {
29
+ int megatextureIndex;
30
+ bool usingParentMegatextureIndex;
31
+ vec3 tileUv;
32
+ #if (SAMPLE_COUNT > 1)
33
+ float weight;
34
+ #endif
35
+ };
36
+
37
+ // Integer mod: For WebGL1 only
38
+ int intMod(in int a, in int b) {
39
+ return a - (b * (a / b));
40
+ }
41
+ int normU8_toInt(in float value) {
42
+ return int(value * 255.0);
43
+ }
44
+ int normU8x2_toInt(in vec2 value) {
45
+ return int(value.x * 255.0) + 256 * int(value.y * 255.0);
46
+ }
47
+ float normU8x2_toFloat(in vec2 value) {
48
+ return float(normU8x2_toInt(value)) / 65535.0;
49
+ }
50
+
51
+ OctreeNodeData getOctreeNodeData(in vec2 octreeUv) {
52
+ vec4 texData = texture2D(u_octreeInternalNodeTexture, octreeUv);
53
+
54
+ OctreeNodeData data;
55
+ data.data = normU8x2_toInt(texData.xy);
56
+ data.flag = normU8x2_toInt(texData.zw);
57
+ return data;
58
+ }
59
+
60
+ OctreeNodeData getOctreeChildData(in int parentOctreeIndex, in ivec3 childCoord) {
61
+ int childIndex = childCoord.z * 4 + childCoord.y * 2 + childCoord.x;
62
+ int octreeCoordX = intMod(parentOctreeIndex, u_octreeInternalNodeTilesPerRow) * 9 + 1 + childIndex;
63
+ int octreeCoordY = parentOctreeIndex / u_octreeInternalNodeTilesPerRow;
64
+ vec2 octreeUv = u_octreeInternalNodeTexelSizeUv * vec2(float(octreeCoordX) + 0.5, float(octreeCoordY) + 0.5);
65
+ return getOctreeNodeData(octreeUv);
66
+ }
67
+
68
+ int getOctreeParentIndex(in int octreeIndex) {
69
+ int octreeCoordX = intMod(octreeIndex, u_octreeInternalNodeTilesPerRow) * 9;
70
+ int octreeCoordY = octreeIndex / u_octreeInternalNodeTilesPerRow;
71
+ vec2 octreeUv = u_octreeInternalNodeTexelSizeUv * vec2(float(octreeCoordX) + 0.5, float(octreeCoordY) + 0.5);
72
+ vec4 parentData = texture2D(u_octreeInternalNodeTexture, octreeUv);
73
+ int parentOctreeIndex = normU8x2_toInt(parentData.xy);
74
+ return parentOctreeIndex;
75
+ }
76
+
77
+ /**
78
+ * Convert a position in the uv-space of the tileset bounding shape
79
+ * into the uv-space of a tile within the tileset
80
+ */
81
+ vec3 getTileUv(in vec3 shapePosition, in ivec4 octreeCoords) {
82
+ // TODO: use bit-shifting (only in WebGL2)
83
+ float dimAtLevel = pow(2.0, float(octreeCoords.w));
84
+ return shapePosition * dimAtLevel - vec3(octreeCoords.xyz);
85
+ }
86
+
87
+ void setSampleUv(in vec3 shapePosition, in ivec4 octreeCoords, inout SampleData sampleData) {
88
+ ivec4 sampleCoords = sampleData.usingParentMegatextureIndex
89
+ ? ivec4(octreeCoords.xyz / 2, octreeCoords.w - 1)
90
+ : octreeCoords;
91
+ sampleData.tileUv = getTileUv(shapePosition, sampleCoords);
92
+ }
93
+
94
+ void getOctreeLeafSampleData(in OctreeNodeData data, out SampleData sampleData) {
95
+ sampleData.megatextureIndex = data.data;
96
+ sampleData.usingParentMegatextureIndex = data.flag == OCTREE_FLAG_PACKED_LEAF_FROM_PARENT;
97
+ }
98
+
99
+ #if (SAMPLE_COUNT > 1)
100
+ void getOctreeLeafSampleDatas(in OctreeNodeData data, out SampleData sampleData0, out SampleData sampleData1) {
101
+ int leafIndex = data.data;
102
+ int leafNodeTexelCount = 2;
103
+ // Adding 0.5 moves to the center of the texel
104
+ float leafCoordXStart = float(intMod(leafIndex, u_octreeLeafNodeTilesPerRow) * leafNodeTexelCount) + 0.5;
105
+ float leafCoordY = float(leafIndex / u_octreeLeafNodeTilesPerRow) + 0.5;
106
+
107
+ vec2 leafUv0 = u_octreeLeafNodeTexelSizeUv * vec2(leafCoordXStart + 0.0, leafCoordY);
108
+ vec2 leafUv1 = u_octreeLeafNodeTexelSizeUv * vec2(leafCoordXStart + 1.0, leafCoordY);
109
+ vec4 leafData0 = texture2D(u_octreeLeafNodeTexture, leafUv0);
110
+ vec4 leafData1 = texture2D(u_octreeLeafNodeTexture, leafUv1);
111
+
112
+ float lerp = normU8x2_toFloat(leafData0.xy);
113
+
114
+ sampleData0.megatextureIndex = normU8x2_toInt(leafData1.xy);
115
+ sampleData1.megatextureIndex = normU8x2_toInt(leafData1.zw);
116
+ // TODO: this looks wrong? Should be comparing to OCTREE_FLAG_PACKED_LEAF_FROM_PARENT
117
+ sampleData0.usingParentMegatextureIndex = normU8_toInt(leafData0.z) == 1;
118
+ sampleData1.usingParentMegatextureIndex = normU8_toInt(leafData0.w) == 1;
119
+ sampleData0.weight = 1.0 - lerp;
120
+ sampleData1.weight = lerp;
121
+ }
122
+ #endif
123
+
124
+ void traverseOctreeDownwards(in vec3 shapePosition, inout TraversalData traversalData, out SampleData sampleDatas[SAMPLE_COUNT]) {
125
+ float sizeAtLevel = 1.0 / pow(2.0, float(traversalData.octreeCoords.w));
126
+ vec3 start = vec3(traversalData.octreeCoords.xyz) * sizeAtLevel;
127
+ vec3 end = start + vec3(sizeAtLevel);
128
+
129
+ for (int i = 0; i < OCTREE_MAX_LEVELS; ++i) {
130
+ // Find out which octree child contains the position
131
+ // 0 if before center, 1 if after
132
+ vec3 center = 0.5 * (start + end);
133
+ vec3 childCoord = step(center, shapePosition);
134
+
135
+ OctreeNodeData childData = getOctreeChildData(traversalData.parentOctreeIndex, ivec3(childCoord));
136
+
137
+ // Get octree coords for the next level down
138
+ ivec4 octreeCoords = traversalData.octreeCoords;
139
+ traversalData.octreeCoords = ivec4(octreeCoords.xyz * 2 + ivec3(childCoord), octreeCoords.w + 1);
140
+
141
+ if (childData.flag == OCTREE_FLAG_INTERNAL) {
142
+ // interior tile - keep going deeper
143
+ start = mix(start, center, childCoord);
144
+ end = mix(center, end, childCoord);
145
+ traversalData.parentOctreeIndex = childData.data;
146
+ } else {
147
+ // leaf tile - stop traversing
148
+ float dimAtLevel = pow(2.0, float(traversalData.octreeCoords.w));
149
+ traversalData.stepT = u_stepSize / dimAtLevel;
150
+ #if (SAMPLE_COUNT == 1)
151
+ getOctreeLeafSampleData(childData, sampleDatas[0]);
152
+ setSampleUv(shapePosition, traversalData.octreeCoords, sampleDatas[0]);
153
+ #else
154
+ getOctreeLeafSampleDatas(childData, sampleDatas[0], sampleDatas[1]);
155
+ setSampleUv(shapePosition, traversalData.octreeCoords, sampleDatas[0]);
156
+ setSampleUv(shapePosition, traversalData.octreeCoords, sampleDatas[1]);
157
+ #endif
158
+ return;
159
+ }
160
+ }
161
+ }
162
+
163
+ /**
164
+ * Transform a given position to an octree tile coordinate and a position within that tile,
165
+ * and find the corresponding megatexture index and texture coordinates
166
+ */
167
+ void traverseOctreeFromBeginning(in vec3 shapePosition, out TraversalData traversalData, out SampleData sampleDatas[SAMPLE_COUNT]) {
168
+ traversalData.octreeCoords = ivec4(0);
169
+ traversalData.parentOctreeIndex = 0;
170
+
171
+ OctreeNodeData rootData = getOctreeNodeData(vec2(0.0));
172
+ if (rootData.flag == OCTREE_FLAG_LEAF) {
173
+ // No child data, only the root tile has data
174
+ traversalData.stepT = u_stepSize;
175
+ #if (SAMPLE_COUNT == 1)
176
+ getOctreeLeafSampleData(rootData, sampleDatas[0]);
177
+ setSampleUv(shapePosition, traversalData.octreeCoords, sampleDatas[0]);
178
+ #else
179
+ getOctreeLeafSampleDatas(rootData, sampleDatas[0], sampleDatas[1]);
180
+ setSampleUv(shapePosition, traversalData.octreeCoords, sampleDatas[0]);
181
+ setSampleUv(shapePosition, traversalData.octreeCoords, sampleDatas[1]);
182
+ #endif
183
+ } else {
184
+ traverseOctreeDownwards(shapePosition, traversalData, sampleDatas);
185
+ }
186
+ }
187
+
188
+ bool inRange(in vec3 v, in vec3 minVal, in vec3 maxVal) {
189
+ return clamp(v, minVal, maxVal) == v;
190
+ }
191
+
192
+ bool insideTile(in vec3 shapePosition, in ivec4 octreeCoords) {
193
+ vec3 tileUv = getTileUv(shapePosition, octreeCoords);
194
+ bool inside = inRange(tileUv, vec3(0.0), vec3(1.0));
195
+ // Assume (!) the position is always inside the root tile.
196
+ return inside || octreeCoords.w == 0;
197
+ }
198
+
199
+ void traverseOctreeFromExisting(in vec3 shapePosition, inout TraversalData traversalData, inout SampleData sampleDatas[SAMPLE_COUNT]) {
200
+ if (insideTile(shapePosition, traversalData.octreeCoords)) {
201
+ for (int i = 0; i < SAMPLE_COUNT; i++) {
202
+ setSampleUv(shapePosition, traversalData.octreeCoords, sampleDatas[i]);
203
+ }
204
+ } else {
205
+ // Go up tree
206
+ for (int i = 0; i < OCTREE_MAX_LEVELS; ++i)
207
+ {
208
+ traversalData.octreeCoords.xyz /= 2;
209
+ traversalData.octreeCoords.w -= 1;
210
+
211
+ if (!insideTile(shapePosition, traversalData.octreeCoords)) {
212
+ traversalData.parentOctreeIndex = getOctreeParentIndex(traversalData.parentOctreeIndex);
213
+ } else {
214
+ break;
215
+ }
216
+ }
217
+
218
+ // Go down tree
219
+ traverseOctreeDownwards(shapePosition, traversalData, sampleDatas);
220
+ }
221
+ }
@@ -0,0 +1,223 @@
1
+ //This file is automatically rebuilt by the Cesium build process.
2
+ export default "// These octree flags must be in sync with GpuOctreeFlag in VoxelTraversal.js\n\
3
+ #define OCTREE_FLAG_INTERNAL 0\n\
4
+ #define OCTREE_FLAG_LEAF 1\n\
5
+ #define OCTREE_FLAG_PACKED_LEAF_FROM_PARENT 2\n\
6
+ \n\
7
+ #define OCTREE_MAX_LEVELS 32 // Harcoded value because GLSL doesn't like variable length loops\n\
8
+ \n\
9
+ uniform sampler2D u_octreeInternalNodeTexture;\n\
10
+ uniform vec2 u_octreeInternalNodeTexelSizeUv;\n\
11
+ uniform int u_octreeInternalNodeTilesPerRow;\n\
12
+ uniform sampler2D u_octreeLeafNodeTexture;\n\
13
+ uniform vec2 u_octreeLeafNodeTexelSizeUv;\n\
14
+ uniform int u_octreeLeafNodeTilesPerRow;\n\
15
+ \n\
16
+ uniform float u_stepSize;\n\
17
+ \n\
18
+ struct OctreeNodeData {\n\
19
+ int data;\n\
20
+ int flag;\n\
21
+ };\n\
22
+ \n\
23
+ struct TraversalData {\n\
24
+ float stepT;\n\
25
+ ivec4 octreeCoords;\n\
26
+ int parentOctreeIndex;\n\
27
+ };\n\
28
+ \n\
29
+ struct SampleData {\n\
30
+ int megatextureIndex;\n\
31
+ bool usingParentMegatextureIndex;\n\
32
+ vec3 tileUv;\n\
33
+ #if (SAMPLE_COUNT > 1)\n\
34
+ float weight;\n\
35
+ #endif\n\
36
+ };\n\
37
+ \n\
38
+ // Integer mod: For WebGL1 only\n\
39
+ int intMod(in int a, in int b) {\n\
40
+ return a - (b * (a / b));\n\
41
+ }\n\
42
+ int normU8_toInt(in float value) {\n\
43
+ return int(value * 255.0);\n\
44
+ }\n\
45
+ int normU8x2_toInt(in vec2 value) {\n\
46
+ return int(value.x * 255.0) + 256 * int(value.y * 255.0);\n\
47
+ }\n\
48
+ float normU8x2_toFloat(in vec2 value) {\n\
49
+ return float(normU8x2_toInt(value)) / 65535.0;\n\
50
+ }\n\
51
+ \n\
52
+ OctreeNodeData getOctreeNodeData(in vec2 octreeUv) {\n\
53
+ vec4 texData = texture2D(u_octreeInternalNodeTexture, octreeUv);\n\
54
+ \n\
55
+ OctreeNodeData data;\n\
56
+ data.data = normU8x2_toInt(texData.xy);\n\
57
+ data.flag = normU8x2_toInt(texData.zw);\n\
58
+ return data;\n\
59
+ }\n\
60
+ \n\
61
+ OctreeNodeData getOctreeChildData(in int parentOctreeIndex, in ivec3 childCoord) {\n\
62
+ int childIndex = childCoord.z * 4 + childCoord.y * 2 + childCoord.x;\n\
63
+ int octreeCoordX = intMod(parentOctreeIndex, u_octreeInternalNodeTilesPerRow) * 9 + 1 + childIndex;\n\
64
+ int octreeCoordY = parentOctreeIndex / u_octreeInternalNodeTilesPerRow;\n\
65
+ vec2 octreeUv = u_octreeInternalNodeTexelSizeUv * vec2(float(octreeCoordX) + 0.5, float(octreeCoordY) + 0.5);\n\
66
+ return getOctreeNodeData(octreeUv);\n\
67
+ }\n\
68
+ \n\
69
+ int getOctreeParentIndex(in int octreeIndex) {\n\
70
+ int octreeCoordX = intMod(octreeIndex, u_octreeInternalNodeTilesPerRow) * 9;\n\
71
+ int octreeCoordY = octreeIndex / u_octreeInternalNodeTilesPerRow;\n\
72
+ vec2 octreeUv = u_octreeInternalNodeTexelSizeUv * vec2(float(octreeCoordX) + 0.5, float(octreeCoordY) + 0.5);\n\
73
+ vec4 parentData = texture2D(u_octreeInternalNodeTexture, octreeUv);\n\
74
+ int parentOctreeIndex = normU8x2_toInt(parentData.xy);\n\
75
+ return parentOctreeIndex;\n\
76
+ }\n\
77
+ \n\
78
+ /**\n\
79
+ * Convert a position in the uv-space of the tileset bounding shape\n\
80
+ * into the uv-space of a tile within the tileset\n\
81
+ */\n\
82
+ vec3 getTileUv(in vec3 shapePosition, in ivec4 octreeCoords) {\n\
83
+ // TODO: use bit-shifting (only in WebGL2)\n\
84
+ float dimAtLevel = pow(2.0, float(octreeCoords.w));\n\
85
+ return shapePosition * dimAtLevel - vec3(octreeCoords.xyz);\n\
86
+ }\n\
87
+ \n\
88
+ void setSampleUv(in vec3 shapePosition, in ivec4 octreeCoords, inout SampleData sampleData) {\n\
89
+ ivec4 sampleCoords = sampleData.usingParentMegatextureIndex\n\
90
+ ? ivec4(octreeCoords.xyz / 2, octreeCoords.w - 1)\n\
91
+ : octreeCoords;\n\
92
+ sampleData.tileUv = getTileUv(shapePosition, sampleCoords);\n\
93
+ }\n\
94
+ \n\
95
+ void getOctreeLeafSampleData(in OctreeNodeData data, out SampleData sampleData) {\n\
96
+ sampleData.megatextureIndex = data.data;\n\
97
+ sampleData.usingParentMegatextureIndex = data.flag == OCTREE_FLAG_PACKED_LEAF_FROM_PARENT;\n\
98
+ }\n\
99
+ \n\
100
+ #if (SAMPLE_COUNT > 1)\n\
101
+ void getOctreeLeafSampleDatas(in OctreeNodeData data, out SampleData sampleData0, out SampleData sampleData1) {\n\
102
+ int leafIndex = data.data;\n\
103
+ int leafNodeTexelCount = 2;\n\
104
+ // Adding 0.5 moves to the center of the texel\n\
105
+ float leafCoordXStart = float(intMod(leafIndex, u_octreeLeafNodeTilesPerRow) * leafNodeTexelCount) + 0.5;\n\
106
+ float leafCoordY = float(leafIndex / u_octreeLeafNodeTilesPerRow) + 0.5;\n\
107
+ \n\
108
+ vec2 leafUv0 = u_octreeLeafNodeTexelSizeUv * vec2(leafCoordXStart + 0.0, leafCoordY);\n\
109
+ vec2 leafUv1 = u_octreeLeafNodeTexelSizeUv * vec2(leafCoordXStart + 1.0, leafCoordY);\n\
110
+ vec4 leafData0 = texture2D(u_octreeLeafNodeTexture, leafUv0);\n\
111
+ vec4 leafData1 = texture2D(u_octreeLeafNodeTexture, leafUv1);\n\
112
+ \n\
113
+ float lerp = normU8x2_toFloat(leafData0.xy);\n\
114
+ \n\
115
+ sampleData0.megatextureIndex = normU8x2_toInt(leafData1.xy);\n\
116
+ sampleData1.megatextureIndex = normU8x2_toInt(leafData1.zw);\n\
117
+ // TODO: this looks wrong? Should be comparing to OCTREE_FLAG_PACKED_LEAF_FROM_PARENT\n\
118
+ sampleData0.usingParentMegatextureIndex = normU8_toInt(leafData0.z) == 1;\n\
119
+ sampleData1.usingParentMegatextureIndex = normU8_toInt(leafData0.w) == 1;\n\
120
+ sampleData0.weight = 1.0 - lerp;\n\
121
+ sampleData1.weight = lerp;\n\
122
+ }\n\
123
+ #endif\n\
124
+ \n\
125
+ void traverseOctreeDownwards(in vec3 shapePosition, inout TraversalData traversalData, out SampleData sampleDatas[SAMPLE_COUNT]) {\n\
126
+ float sizeAtLevel = 1.0 / pow(2.0, float(traversalData.octreeCoords.w));\n\
127
+ vec3 start = vec3(traversalData.octreeCoords.xyz) * sizeAtLevel;\n\
128
+ vec3 end = start + vec3(sizeAtLevel);\n\
129
+ \n\
130
+ for (int i = 0; i < OCTREE_MAX_LEVELS; ++i) {\n\
131
+ // Find out which octree child contains the position\n\
132
+ // 0 if before center, 1 if after\n\
133
+ vec3 center = 0.5 * (start + end);\n\
134
+ vec3 childCoord = step(center, shapePosition);\n\
135
+ \n\
136
+ OctreeNodeData childData = getOctreeChildData(traversalData.parentOctreeIndex, ivec3(childCoord));\n\
137
+ \n\
138
+ // Get octree coords for the next level down\n\
139
+ ivec4 octreeCoords = traversalData.octreeCoords;\n\
140
+ traversalData.octreeCoords = ivec4(octreeCoords.xyz * 2 + ivec3(childCoord), octreeCoords.w + 1);\n\
141
+ \n\
142
+ if (childData.flag == OCTREE_FLAG_INTERNAL) {\n\
143
+ // interior tile - keep going deeper\n\
144
+ start = mix(start, center, childCoord);\n\
145
+ end = mix(center, end, childCoord);\n\
146
+ traversalData.parentOctreeIndex = childData.data;\n\
147
+ } else {\n\
148
+ // leaf tile - stop traversing\n\
149
+ float dimAtLevel = pow(2.0, float(traversalData.octreeCoords.w));\n\
150
+ traversalData.stepT = u_stepSize / dimAtLevel;\n\
151
+ #if (SAMPLE_COUNT == 1)\n\
152
+ getOctreeLeafSampleData(childData, sampleDatas[0]);\n\
153
+ setSampleUv(shapePosition, traversalData.octreeCoords, sampleDatas[0]);\n\
154
+ #else\n\
155
+ getOctreeLeafSampleDatas(childData, sampleDatas[0], sampleDatas[1]);\n\
156
+ setSampleUv(shapePosition, traversalData.octreeCoords, sampleDatas[0]);\n\
157
+ setSampleUv(shapePosition, traversalData.octreeCoords, sampleDatas[1]);\n\
158
+ #endif\n\
159
+ return;\n\
160
+ }\n\
161
+ }\n\
162
+ }\n\
163
+ \n\
164
+ /**\n\
165
+ * Transform a given position to an octree tile coordinate and a position within that tile,\n\
166
+ * and find the corresponding megatexture index and texture coordinates\n\
167
+ */\n\
168
+ void traverseOctreeFromBeginning(in vec3 shapePosition, out TraversalData traversalData, out SampleData sampleDatas[SAMPLE_COUNT]) {\n\
169
+ traversalData.octreeCoords = ivec4(0);\n\
170
+ traversalData.parentOctreeIndex = 0;\n\
171
+ \n\
172
+ OctreeNodeData rootData = getOctreeNodeData(vec2(0.0));\n\
173
+ if (rootData.flag == OCTREE_FLAG_LEAF) {\n\
174
+ // No child data, only the root tile has data\n\
175
+ traversalData.stepT = u_stepSize;\n\
176
+ #if (SAMPLE_COUNT == 1)\n\
177
+ getOctreeLeafSampleData(rootData, sampleDatas[0]);\n\
178
+ setSampleUv(shapePosition, traversalData.octreeCoords, sampleDatas[0]);\n\
179
+ #else\n\
180
+ getOctreeLeafSampleDatas(rootData, sampleDatas[0], sampleDatas[1]);\n\
181
+ setSampleUv(shapePosition, traversalData.octreeCoords, sampleDatas[0]);\n\
182
+ setSampleUv(shapePosition, traversalData.octreeCoords, sampleDatas[1]);\n\
183
+ #endif\n\
184
+ } else {\n\
185
+ traverseOctreeDownwards(shapePosition, traversalData, sampleDatas);\n\
186
+ }\n\
187
+ }\n\
188
+ \n\
189
+ bool inRange(in vec3 v, in vec3 minVal, in vec3 maxVal) {\n\
190
+ return clamp(v, minVal, maxVal) == v;\n\
191
+ }\n\
192
+ \n\
193
+ bool insideTile(in vec3 shapePosition, in ivec4 octreeCoords) {\n\
194
+ vec3 tileUv = getTileUv(shapePosition, octreeCoords);\n\
195
+ bool inside = inRange(tileUv, vec3(0.0), vec3(1.0));\n\
196
+ // Assume (!) the position is always inside the root tile.\n\
197
+ return inside || octreeCoords.w == 0;\n\
198
+ }\n\
199
+ \n\
200
+ void traverseOctreeFromExisting(in vec3 shapePosition, inout TraversalData traversalData, inout SampleData sampleDatas[SAMPLE_COUNT]) {\n\
201
+ if (insideTile(shapePosition, traversalData.octreeCoords)) {\n\
202
+ for (int i = 0; i < SAMPLE_COUNT; i++) {\n\
203
+ setSampleUv(shapePosition, traversalData.octreeCoords, sampleDatas[i]);\n\
204
+ }\n\
205
+ } else {\n\
206
+ // Go up tree\n\
207
+ for (int i = 0; i < OCTREE_MAX_LEVELS; ++i)\n\
208
+ {\n\
209
+ traversalData.octreeCoords.xyz /= 2;\n\
210
+ traversalData.octreeCoords.w -= 1;\n\
211
+ \n\
212
+ if (!insideTile(shapePosition, traversalData.octreeCoords)) {\n\
213
+ traversalData.parentOctreeIndex = getOctreeParentIndex(traversalData.parentOctreeIndex);\n\
214
+ } else {\n\
215
+ break;\n\
216
+ }\n\
217
+ }\n\
218
+ \n\
219
+ // Go down tree\n\
220
+ traverseOctreeDownwards(shapePosition, traversalData, sampleDatas);\n\
221
+ }\n\
222
+ }\n\
223
+ ";
@@ -0,0 +1,150 @@
1
+ // See Intersection.glsl for the definition of intersectScene
2
+ // See IntersectionUtils.glsl for the definition of nextIntersection
3
+ // See convertUvToBox.glsl, convertUvToCylinder.glsl, or convertUvToEllipsoid.glsl
4
+ // for the definition of convertUvToShapeUvSpace. The appropriate function is
5
+ // selected based on the VoxelPrimitive shape type, and added to the shader in
6
+ // Scene/VoxelRenderResources.js.
7
+ // See Octree.glsl for the definitions of TraversalData, SampleData,
8
+ // traverseOctreeFromBeginning, and traverseOctreeFromExisting
9
+ // See Megatexture.glsl for the definition of accumulatePropertiesFromMegatexture
10
+
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
13
+
14
+ uniform mat3 u_transformDirectionViewToLocal;
15
+ uniform vec3 u_cameraPositionUv;
16
+
17
+ #if defined(PICKING)
18
+ uniform vec4 u_pickColor;
19
+ #endif
20
+
21
+ #if defined(JITTER)
22
+ float hash(vec2 p)
23
+ {
24
+ vec3 p3 = fract(vec3(p.xyx) * 50.0); // magic number = hashscale
25
+ p3 += dot(p3, p3.yzx + 19.19);
26
+ return fract((p3.x + p3.y) * p3.z);
27
+ }
28
+ #endif
29
+
30
+ void main()
31
+ {
32
+ vec4 fragCoord = gl_FragCoord;
33
+ vec2 screenCoord = (fragCoord.xy - czm_viewport.xy) / czm_viewport.zw; // [0,1]
34
+ vec3 eyeDirection = normalize(czm_windowToEyeCoordinates(fragCoord).xyz);
35
+ vec3 viewDirWorld = normalize(czm_inverseViewRotation * eyeDirection); // normalize again just in case
36
+ vec3 viewDirUv = normalize(u_transformDirectionViewToLocal * eyeDirection); // normalize again just in case
37
+ vec3 viewPosUv = u_cameraPositionUv;
38
+
39
+ Intersections ix;
40
+ vec2 entryExitT = intersectScene(screenCoord, viewPosUv, viewDirUv, ix);
41
+
42
+ // Exit early if the scene was completely missed.
43
+ if (entryExitT.x == NO_HIT) {
44
+ discard;
45
+ }
46
+
47
+ float currT = entryExitT.x;
48
+ float endT = entryExitT.y;
49
+ vec3 positionUv = viewPosUv + currT * viewDirUv;
50
+ // TODO: is it possible for this to be out of bounds, and does it matter?
51
+ vec3 positionUvShapeSpace = convertUvToShapeUvSpace(positionUv);
52
+
53
+ // Traverse the tree from the start position
54
+ TraversalData traversalData;
55
+ SampleData sampleDatas[SAMPLE_COUNT];
56
+ traverseOctreeFromBeginning(positionUvShapeSpace, traversalData, sampleDatas);
57
+
58
+ // TODO:
59
+ // - jitter doesn't affect the first traversal?
60
+ // - jitter is always > 0?
61
+ // - jitter is only applied at one step?
62
+ #if defined(JITTER)
63
+ float noise = hash(screenCoord); // [0,1]
64
+ currT += noise * traversalData.stepT;
65
+ positionUv += noise * traversalData.stepT * viewDirUv;
66
+ #endif
67
+
68
+ FragmentInput fragmentInput;
69
+ #if defined(STATISTICS)
70
+ setStatistics(fragmentInput.metadata.statistics);
71
+ #endif
72
+
73
+ vec4 colorAccum =vec4(0.0);
74
+
75
+ for (int stepCount = 0; stepCount < STEP_COUNT_MAX; ++stepCount) {
76
+ // Read properties from the megatexture based on the traversal state
77
+ Properties properties = accumulatePropertiesFromMegatexture(sampleDatas);
78
+
79
+ // Prepare the custom shader inputs
80
+ copyPropertiesToMetadata(properties, fragmentInput.metadata);
81
+ fragmentInput.voxel.positionUv = positionUv;
82
+ fragmentInput.voxel.positionShapeUv = positionUvShapeSpace;
83
+ fragmentInput.voxel.positionUvLocal = sampleDatas[0].tileUv;
84
+ fragmentInput.voxel.viewDirUv = viewDirUv;
85
+ fragmentInput.voxel.viewDirWorld = viewDirWorld;
86
+ fragmentInput.voxel.travelDistance = traversalData.stepT;
87
+
88
+ // Run the custom shader
89
+ czm_modelMaterial materialOutput;
90
+ fragmentMain(fragmentInput, materialOutput);
91
+
92
+ // Sanitize the custom shader output
93
+ vec4 color = vec4(materialOutput.diffuse, materialOutput.alpha);
94
+ color.rgb = max(color.rgb, vec3(0.0));
95
+ color.a = clamp(color.a, 0.0, 1.0);
96
+
97
+ // Pre-multiplied alpha blend
98
+ colorAccum += (1.0 - colorAccum.a) * vec4(color.rgb * color.a, color.a);
99
+
100
+ // Stop traversing if the alpha has been fully saturated
101
+ if (colorAccum.a > ALPHA_ACCUM_MAX) {
102
+ colorAccum.a = ALPHA_ACCUM_MAX;
103
+ break;
104
+ }
105
+
106
+ if (traversalData.stepT == 0.0) {
107
+ // Shape is infinitely thin, no need to traverse further
108
+ break;
109
+ }
110
+
111
+ // Keep raymarching
112
+ currT += traversalData.stepT;
113
+ positionUv += traversalData.stepT * viewDirUv;
114
+
115
+ // Check if there's more intersections.
116
+ if (currT > endT) {
117
+ #if (INTERSECTION_COUNT == 1)
118
+ break;
119
+ #else
120
+ vec2 entryExitT = nextIntersection(ix);
121
+ if (entryExitT.x == NO_HIT) {
122
+ break;
123
+ } else {
124
+ // Found another intersection. Resume raymarching there
125
+ currT = entryExitT.x;
126
+ endT = entryExitT.y;
127
+ positionUv = viewPosUv + currT * viewDirUv;
128
+ }
129
+ #endif
130
+ }
131
+
132
+ // Traverse the tree from the current ray position.
133
+ // This is similar to traverseOctree but is faster when the ray is in the same tile as the previous step.
134
+ positionUvShapeSpace = convertUvToShapeUvSpace(positionUv);
135
+ traverseOctreeFromExisting(positionUvShapeSpace, traversalData, sampleDatas);
136
+ }
137
+
138
+ // Convert the alpha from [0,ALPHA_ACCUM_MAX] to [0,1]
139
+ colorAccum.a /= ALPHA_ACCUM_MAX;
140
+
141
+ #if defined(PICKING)
142
+ // If alpha is 0.0 there is nothing to pick
143
+ if (colorAccum.a == 0.0) {
144
+ discard;
145
+ }
146
+ gl_FragColor = u_pickColor;
147
+ #else
148
+ gl_FragColor = colorAccum;
149
+ #endif
150
+ }