@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.
- package/Build/Workers/{AttributeCompression-4589338a.js → AttributeCompression-b646d393.js} +1 -1
- package/Build/Workers/{AxisAlignedBoundingBox-bfb1234f.js → AxisAlignedBoundingBox-a4321399.js} +1 -1
- package/Build/Workers/{BoundingRectangle-7ffc2153.js → BoundingRectangle-80d8801f.js} +1 -1
- package/Build/Workers/{BoxGeometry-93f344a3.js → BoxGeometry-33c10a4f.js} +1 -1
- package/Build/Workers/{Color-0c5aaf47.js → Color-1bf9a6e0.js} +1 -1
- package/Build/Workers/{CoplanarPolygonGeometryLibrary-6597982a.js → CoplanarPolygonGeometryLibrary-5c5b981b.js} +1 -1
- package/Build/Workers/{CorridorGeometryLibrary-2119580e.js → CorridorGeometryLibrary-7cbae7a0.js} +1 -1
- package/Build/Workers/{CylinderGeometry-f9503c6d.js → CylinderGeometry-42740df0.js} +1 -1
- package/Build/Workers/{EllipseGeometry-fedf72d5.js → EllipseGeometry-49a3ac21.js} +1 -1
- package/Build/Workers/{EllipseGeometryLibrary-4ea68687.js → EllipseGeometryLibrary-b891b2f8.js} +1 -1
- package/Build/Workers/{EllipseOutlineGeometry-e2ae6a35.js → EllipseOutlineGeometry-fbd72e07.js} +1 -1
- package/Build/Workers/{EllipsoidGeodesic-16de63ea.js → EllipsoidGeodesic-98c62a56.js} +1 -1
- package/Build/Workers/{EllipsoidGeometry-95c0330e.js → EllipsoidGeometry-a351dba8.js} +1 -1
- package/Build/Workers/{EllipsoidOutlineGeometry-d6d2ceec.js → EllipsoidOutlineGeometry-3e8779bf.js} +1 -1
- package/Build/Workers/{EllipsoidRhumbLine-ae5e65e0.js → EllipsoidRhumbLine-19756602.js} +1 -1
- package/Build/Workers/{EllipsoidTangentPlane-bfc674bf.js → EllipsoidTangentPlane-cfb50678.js} +1 -1
- package/Build/Workers/{EncodedCartesian3-f473ea18.js → EncodedCartesian3-81f70735.js} +1 -1
- package/Build/Workers/{FrustumGeometry-3bf2e4eb.js → FrustumGeometry-c5754412.js} +1 -1
- package/Build/Workers/{GeometryAttribute-df5f473e.js → GeometryAttribute-0bfd05e8.js} +1 -1
- package/Build/Workers/{GeometryInstance-aa75b4cf.js → GeometryInstance-451dc1cd.js} +1 -1
- package/Build/Workers/{GeometryPipeline-f0e46c42.js → GeometryPipeline-0166905d.js} +1 -1
- package/Build/Workers/{IntersectionTests-9de29d51.js → IntersectionTests-a93d3de9.js} +1 -1
- package/Build/Workers/{Matrix2-ce637455.js → Matrix2-13178034.js} +4 -2
- package/Build/Workers/{Matrix3-4f4df527.js → Matrix3-315394f6.js} +2 -1
- package/Build/Workers/{OrientedBoundingBox-d3ff3d4d.js → OrientedBoundingBox-b450cb61.js} +5 -5
- package/Build/Workers/{Plane-b81241c2.js → Plane-900aa728.js} +1 -1
- package/Build/Workers/{PolygonGeometryLibrary-6f4937bb.js → PolygonGeometryLibrary-f918ac26.js} +1 -1
- package/Build/Workers/PolygonPipeline-f59a8f0a.js +1345 -0
- package/Build/Workers/{PolylinePipeline-2e2b015c.js → PolylinePipeline-d8e6bd9b.js} +1 -1
- package/Build/Workers/{PolylineVolumeGeometryLibrary-7ee1d449.js → PolylineVolumeGeometryLibrary-125d2edf.js} +1 -1
- package/Build/Workers/{PrimitivePipeline-a9b7aae0.js → PrimitivePipeline-0d7b5ed4.js} +1 -1
- package/Build/Workers/{RectangleGeometryLibrary-9aa6c8f6.js → RectangleGeometryLibrary-0768db63.js} +1 -1
- package/Build/Workers/{TerrainEncoding-b52dcfc5.js → TerrainEncoding-06470d7f.js} +1 -1
- package/Build/Workers/{Transforms-2f755df8.js → Transforms-26539bce.js} +97 -83
- package/Build/Workers/{WallGeometryLibrary-ab19a93d.js → WallGeometryLibrary-6167b0fc.js} +1 -1
- package/Build/Workers/{WebMercatorProjection-9f25de49.js → WebMercatorProjection-13a90d41.js} +1 -1
- package/Build/Workers/cesiumWorkerBootstrapper.js +25 -1
- package/Build/Workers/combineGeometry.js +1 -1
- package/Build/Workers/createBoxGeometry.js +1 -1
- package/Build/Workers/createBoxOutlineGeometry.js +1 -1
- package/Build/Workers/createCircleGeometry.js +1 -1
- package/Build/Workers/createCircleOutlineGeometry.js +1 -1
- package/Build/Workers/createCoplanarPolygonGeometry.js +1 -1
- package/Build/Workers/createCoplanarPolygonOutlineGeometry.js +1 -1
- package/Build/Workers/createCorridorGeometry.js +1 -1
- package/Build/Workers/createCorridorOutlineGeometry.js +1 -1
- package/Build/Workers/createCylinderGeometry.js +1 -1
- package/Build/Workers/createCylinderOutlineGeometry.js +1 -1
- package/Build/Workers/createEllipseGeometry.js +1 -1
- package/Build/Workers/createEllipseOutlineGeometry.js +1 -1
- package/Build/Workers/createEllipsoidGeometry.js +1 -1
- package/Build/Workers/createEllipsoidOutlineGeometry.js +1 -1
- package/Build/Workers/createFrustumGeometry.js +1 -1
- package/Build/Workers/createFrustumOutlineGeometry.js +1 -1
- package/Build/Workers/createGeometry.js +1 -1
- package/Build/Workers/createGroundPolylineGeometry.js +1 -1
- package/Build/Workers/createPlaneGeometry.js +1 -1
- package/Build/Workers/createPlaneOutlineGeometry.js +1 -1
- package/Build/Workers/createPolygonGeometry.js +1 -1
- package/Build/Workers/createPolygonOutlineGeometry.js +1 -1
- package/Build/Workers/createPolylineGeometry.js +1 -1
- package/Build/Workers/createPolylineVolumeGeometry.js +1 -1
- package/Build/Workers/createPolylineVolumeOutlineGeometry.js +1 -1
- package/Build/Workers/createRectangleGeometry.js +1 -1
- package/Build/Workers/createRectangleOutlineGeometry.js +1 -1
- package/Build/Workers/createSimplePolylineGeometry.js +1 -1
- package/Build/Workers/createSphereGeometry.js +1 -1
- package/Build/Workers/createSphereOutlineGeometry.js +1 -1
- package/Build/Workers/createVectorTileClampedPolylines.js +1 -1
- package/Build/Workers/createVectorTileGeometries.js +1 -1
- package/Build/Workers/createVectorTilePoints.js +1 -1
- package/Build/Workers/createVectorTilePolygons.js +1 -1
- package/Build/Workers/createVectorTilePolylines.js +1 -1
- package/Build/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js +1 -1
- package/Build/Workers/createVerticesFromHeightmap.js +7 -3
- package/Build/Workers/createVerticesFromQuantizedTerrainMesh.js +1 -1
- package/Build/Workers/createWallGeometry.js +1 -1
- package/Build/Workers/createWallOutlineGeometry.js +1 -1
- package/Build/Workers/decodeGoogleEarthEnterprisePacket.js +95 -76
- package/Build/Workers/decodeI3S.js +1 -1
- package/Build/Workers/package.js +25 -1
- package/Build/Workers/transferTypedArrayTest.js +25 -1
- package/Build/Workers/upsampleQuantizedTerrainMesh.js +1 -1
- package/README.md +9 -9
- package/Source/Core/EarthOrientationParameters.js +67 -63
- package/Source/Core/Ion.js +1 -1
- package/Source/Core/Matrix2.js +2 -1
- package/Source/Core/Matrix3.js +2 -1
- package/Source/Core/Matrix4.js +1 -0
- package/Source/Core/OrientedBoundingBox.js +4 -4
- package/Source/Core/S2Cell.js +3 -3
- package/Source/Core/Transforms.js +3 -7
- package/Source/DataSources/GpxDataSource.js +4 -6
- package/Source/DataSources/KmlDataSource.js +3 -5
- package/Source/Renderer/Context.js +230 -177
- package/Source/Renderer/Pass.js +3 -2
- package/Source/Scene/Cesium3DTileContentType.js +19 -0
- package/Source/Scene/Cesium3DTilesVoxelProvider.js +482 -0
- package/Source/Scene/Cesium3DTilesetMetadata.js +2 -2
- package/Source/Scene/ContentMetadata.js +2 -2
- package/Source/Scene/DerivedCommand.js +7 -0
- package/Source/Scene/Expression.js +1 -1
- package/Source/Scene/Globe.js +10 -0
- package/Source/Scene/GlobeSurfaceTileProvider.js +7 -0
- package/Source/Scene/GltfImageLoader.js +1 -1
- package/Source/Scene/GltfVertexBufferLoader.js +10 -2
- package/Source/Scene/GroupMetadata.js +2 -2
- package/Source/Scene/I3SDataProvider.js +2 -1
- package/Source/Scene/I3SFeature.js +1 -1
- package/Source/Scene/I3SLayer.js +64 -2
- package/Source/Scene/I3SNode.js +50 -6
- package/Source/Scene/ImplicitMetadataView.js +2 -2
- package/Source/Scene/ImplicitSubtreeCache.js +127 -0
- package/Source/Scene/ImplicitSubtreeMetadata.js +2 -2
- package/Source/Scene/ImplicitTileset.js +3 -2
- package/Source/Scene/KeyframeNode.js +47 -0
- package/Source/Scene/Megatexture.js +490 -0
- package/Source/Scene/MetadataClass.js +60 -25
- package/Source/Scene/MetadataClassProperty.js +132 -68
- package/Source/Scene/MetadataComponentType.js +78 -57
- package/Source/Scene/MetadataEnum.js +59 -23
- package/Source/Scene/MetadataEnumValue.js +49 -15
- package/Source/Scene/MetadataSchema.js +53 -24
- package/Source/Scene/MetadataSchemaLoader.js +2 -2
- package/Source/Scene/MetadataTableProperty.js +2 -2
- package/Source/Scene/MetadataType.js +6 -14
- package/Source/Scene/Model/GeoJsonLoader.js +1 -1
- package/Source/Scene/Model/Model.js +38 -6
- package/Source/Scene/Model/buildDrawCommand.js +19 -11
- package/Source/Scene/PointCloud.js +1 -1
- package/Source/Scene/PropertyAttribute.js +2 -2
- package/Source/Scene/PropertyAttributeProperty.js +2 -2
- package/Source/Scene/PropertyTable.js +2 -2
- package/Source/Scene/PropertyTexture.js +2 -2
- package/Source/Scene/PropertyTextureProperty.js +2 -2
- package/Source/Scene/ResourceCache.js +9 -1
- package/Source/Scene/ResourceCacheKey.js +9 -1
- package/Source/Scene/Scene.js +20 -50
- package/Source/Scene/SpatialNode.js +375 -0
- package/Source/Scene/StructuralMetadata.js +2 -2
- package/Source/Scene/TileMetadata.js +2 -2
- package/Source/Scene/TilesetMetadata.js +2 -2
- package/Source/Scene/VoxelBoxShape.js +527 -0
- package/Source/Scene/VoxelContent.js +169 -0
- package/Source/Scene/VoxelCylinderShape.js +937 -0
- package/Source/Scene/VoxelEllipsoidShape.js +937 -0
- package/Source/Scene/VoxelPrimitive.js +1919 -0
- package/Source/Scene/VoxelProvider.js +255 -0
- package/Source/Scene/VoxelRenderResources.js +224 -0
- package/Source/Scene/VoxelShape.js +152 -0
- package/Source/Scene/VoxelShapeType.js +105 -0
- package/Source/Scene/VoxelTraversal.js +1144 -0
- package/Source/Scene/buildVoxelDrawCommands.js +116 -0
- package/Source/Scene/parseBatchTable.js +18 -2
- package/Source/Scene/preprocess3DTileContent.js +8 -0
- package/Source/Scene/processVoxelProperties.js +455 -0
- package/Source/Shaders/BillboardCollectionVS.glsl +1 -1
- package/Source/Shaders/BillboardCollectionVS.js +1 -1
- package/Source/Shaders/Builtin/Constants/passOverlay.glsl +1 -1
- package/Source/Shaders/Builtin/Constants/passOverlay.js +1 -1
- package/Source/Shaders/Builtin/Constants/passVoxels.glsl +9 -0
- package/Source/Shaders/Builtin/Constants/passVoxels.js +11 -0
- package/Source/Shaders/Builtin/CzmBuiltins.js +2 -0
- package/Source/Shaders/Builtin/Functions/windowToEyeCoordinates.glsl +55 -43
- package/Source/Shaders/Builtin/Functions/windowToEyeCoordinates.js +55 -43
- package/Source/Shaders/GlobeFS.glsl +2 -1
- package/Source/Shaders/GlobeFS.js +2 -1
- package/Source/Shaders/PointPrimitiveCollectionVS.glsl +5 -2
- package/Source/Shaders/PointPrimitiveCollectionVS.js +5 -2
- package/Source/Shaders/Voxels/IntersectBox.glsl +79 -0
- package/Source/Shaders/Voxels/IntersectBox.js +81 -0
- package/Source/Shaders/Voxels/IntersectClippingPlanes.glsl +70 -0
- package/Source/Shaders/Voxels/IntersectClippingPlanes.js +72 -0
- package/Source/Shaders/Voxels/IntersectCylinder.glsl +273 -0
- package/Source/Shaders/Voxels/IntersectCylinder.js +275 -0
- package/Source/Shaders/Voxels/IntersectDepth.glsl +23 -0
- package/Source/Shaders/Voxels/IntersectDepth.js +25 -0
- package/Source/Shaders/Voxels/IntersectEllipsoid.glsl +337 -0
- package/Source/Shaders/Voxels/IntersectEllipsoid.js +339 -0
- package/Source/Shaders/Voxels/Intersection.glsl +54 -0
- package/Source/Shaders/Voxels/Intersection.js +56 -0
- package/Source/Shaders/Voxels/IntersectionUtils.glsl +151 -0
- package/Source/Shaders/Voxels/IntersectionUtils.js +153 -0
- package/Source/Shaders/Voxels/Megatexture.glsl +136 -0
- package/Source/Shaders/Voxels/Megatexture.js +138 -0
- package/Source/Shaders/Voxels/Octree.glsl +221 -0
- package/Source/Shaders/Voxels/Octree.js +223 -0
- package/Source/Shaders/Voxels/VoxelFS.glsl +150 -0
- package/Source/Shaders/Voxels/VoxelFS.js +152 -0
- package/Source/Shaders/Voxels/VoxelVS.glsl +11 -0
- package/Source/Shaders/Voxels/VoxelVS.js +13 -0
- package/Source/Shaders/Voxels/convertUvToBox.glsl +16 -0
- package/Source/Shaders/Voxels/convertUvToBox.js +18 -0
- package/Source/Shaders/Voxels/convertUvToCylinder.glsl +79 -0
- package/Source/Shaders/Voxels/convertUvToCylinder.js +81 -0
- package/Source/Shaders/Voxels/convertUvToEllipsoid.glsl +133 -0
- package/Source/Shaders/Voxels/convertUvToEllipsoid.js +135 -0
- package/Source/ThirdParty/Workers/draco_decoder_nodejs.js +100 -101
- package/Source/ThirdParty/Workers/pako_deflate.min.js +2 -2
- package/Source/ThirdParty/Workers/pako_inflate.min.js +2 -2
- package/Source/ThirdParty/draco_decoder.wasm +0 -0
- package/Source/Widget/CesiumWidget.js +1 -1
- package/index.d.ts +961 -56
- package/index.js +92 -60
- package/package.json +6 -4
- package/Build/ThirdParty/Workers/basis_transcoder.js +0 -2233
- package/Build/ThirdParty/Workers/draco_decoder_nodejs.js +0 -1872
- package/Build/ThirdParty/Workers/package.json +0 -1
- package/Build/ThirdParty/Workers/pako_deflate.min.js +0 -589
- package/Build/ThirdParty/Workers/pako_inflate.min.js +0 -798
- package/Build/ThirdParty/Workers/z-worker-pako.js +0 -503
- package/Build/ThirdParty/basis_transcoder.wasm +0 -0
- package/Build/ThirdParty/draco_decoder.wasm +0 -0
- package/Build/ThirdParty/google-earth-dbroot-parser.js +0 -8019
- package/Build/Widget/CesiumWidget.css +0 -120
- package/Build/Widget/lighter.css +0 -13
- package/Build/Workers/PolygonPipeline-774a8aaf.js +0 -1341
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// Main intersection function for Voxel scenes.
|
|
2
|
+
// See IntersectBox.glsl, IntersectCylinder.glsl, or IntersectEllipsoid.glsl
|
|
3
|
+
// for the definition of intersectShape. The appropriate function is selected
|
|
4
|
+
// based on the VoxelPrimitive shape type, and added to the shader in
|
|
5
|
+
// Scene/VoxelRenderResources.js.
|
|
6
|
+
// See also IntersectClippingPlane.glsl and IntersectDepth.glsl.
|
|
7
|
+
// See IntersectionUtils.glsl for the definitions of Ray, NO_HIT,
|
|
8
|
+
// getIntersectionPair, initializeIntersections, nextIntersection.
|
|
9
|
+
|
|
10
|
+
/* Intersection defines (set in Scene/VoxelRenderResources.js)
|
|
11
|
+
#define INTERSECTION_COUNT ###
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
vec2 intersectScene(vec2 screenCoord, vec3 positionUv, vec3 directionUv, out Intersections ix) {
|
|
15
|
+
Ray ray = Ray(positionUv, directionUv);
|
|
16
|
+
|
|
17
|
+
// Do a ray-shape intersection to find the exact starting and ending points.
|
|
18
|
+
intersectShape(ray, ix);
|
|
19
|
+
|
|
20
|
+
// Exit early if the positive shape was completely missed or behind the ray.
|
|
21
|
+
vec2 entryExitT = getIntersectionPair(ix, 0);
|
|
22
|
+
if (entryExitT.x == NO_HIT) {
|
|
23
|
+
// Positive shape was completely missed - so exit early.
|
|
24
|
+
return vec2(NO_HIT);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Clipping planes
|
|
28
|
+
#if defined(CLIPPING_PLANES)
|
|
29
|
+
intersectClippingPlanes(ray, ix);
|
|
30
|
+
#endif
|
|
31
|
+
|
|
32
|
+
// Depth
|
|
33
|
+
#if defined(DEPTH_TEST)
|
|
34
|
+
intersectDepth(screenCoord, ray, ix);
|
|
35
|
+
#endif
|
|
36
|
+
|
|
37
|
+
// Find the first intersection that's in front of the ray
|
|
38
|
+
#if (INTERSECTION_COUNT > 1)
|
|
39
|
+
initializeIntersections(ix);
|
|
40
|
+
for (int i = 0; i < INTERSECTION_COUNT; ++i) {
|
|
41
|
+
entryExitT = nextIntersection(ix);
|
|
42
|
+
if (entryExitT.y > 0.0) {
|
|
43
|
+
// Set start to 0.0 when ray is inside the shape.
|
|
44
|
+
entryExitT.x = max(entryExitT.x, 0.0);
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
#else
|
|
49
|
+
// Set start to 0.0 when ray is inside the shape.
|
|
50
|
+
entryExitT.x = max(entryExitT.x, 0.0);
|
|
51
|
+
#endif
|
|
52
|
+
|
|
53
|
+
return entryExitT;
|
|
54
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
//This file is automatically rebuilt by the Cesium build process.
|
|
2
|
+
export default "// Main intersection function for Voxel scenes.\n\
|
|
3
|
+
// See IntersectBox.glsl, IntersectCylinder.glsl, or IntersectEllipsoid.glsl\n\
|
|
4
|
+
// for the definition of intersectShape. The appropriate function is selected\n\
|
|
5
|
+
// based on the VoxelPrimitive shape type, and added to the shader in\n\
|
|
6
|
+
// Scene/VoxelRenderResources.js.\n\
|
|
7
|
+
// See also IntersectClippingPlane.glsl and IntersectDepth.glsl.\n\
|
|
8
|
+
// See IntersectionUtils.glsl for the definitions of Ray, NO_HIT,\n\
|
|
9
|
+
// getIntersectionPair, initializeIntersections, nextIntersection.\n\
|
|
10
|
+
\n\
|
|
11
|
+
/* Intersection defines (set in Scene/VoxelRenderResources.js)\n\
|
|
12
|
+
#define INTERSECTION_COUNT ###\n\
|
|
13
|
+
*/\n\
|
|
14
|
+
\n\
|
|
15
|
+
vec2 intersectScene(vec2 screenCoord, vec3 positionUv, vec3 directionUv, out Intersections ix) {\n\
|
|
16
|
+
Ray ray = Ray(positionUv, directionUv);\n\
|
|
17
|
+
\n\
|
|
18
|
+
// Do a ray-shape intersection to find the exact starting and ending points.\n\
|
|
19
|
+
intersectShape(ray, ix);\n\
|
|
20
|
+
\n\
|
|
21
|
+
// Exit early if the positive shape was completely missed or behind the ray.\n\
|
|
22
|
+
vec2 entryExitT = getIntersectionPair(ix, 0);\n\
|
|
23
|
+
if (entryExitT.x == NO_HIT) {\n\
|
|
24
|
+
// Positive shape was completely missed - so exit early.\n\
|
|
25
|
+
return vec2(NO_HIT);\n\
|
|
26
|
+
}\n\
|
|
27
|
+
\n\
|
|
28
|
+
// Clipping planes\n\
|
|
29
|
+
#if defined(CLIPPING_PLANES)\n\
|
|
30
|
+
intersectClippingPlanes(ray, ix);\n\
|
|
31
|
+
#endif\n\
|
|
32
|
+
\n\
|
|
33
|
+
// Depth\n\
|
|
34
|
+
#if defined(DEPTH_TEST)\n\
|
|
35
|
+
intersectDepth(screenCoord, ray, ix);\n\
|
|
36
|
+
#endif\n\
|
|
37
|
+
\n\
|
|
38
|
+
// Find the first intersection that's in front of the ray\n\
|
|
39
|
+
#if (INTERSECTION_COUNT > 1)\n\
|
|
40
|
+
initializeIntersections(ix);\n\
|
|
41
|
+
for (int i = 0; i < INTERSECTION_COUNT; ++i) {\n\
|
|
42
|
+
entryExitT = nextIntersection(ix);\n\
|
|
43
|
+
if (entryExitT.y > 0.0) {\n\
|
|
44
|
+
// Set start to 0.0 when ray is inside the shape.\n\
|
|
45
|
+
entryExitT.x = max(entryExitT.x, 0.0);\n\
|
|
46
|
+
break;\n\
|
|
47
|
+
}\n\
|
|
48
|
+
}\n\
|
|
49
|
+
#else\n\
|
|
50
|
+
// Set start to 0.0 when ray is inside the shape.\n\
|
|
51
|
+
entryExitT.x = max(entryExitT.x, 0.0);\n\
|
|
52
|
+
#endif\n\
|
|
53
|
+
\n\
|
|
54
|
+
return entryExitT;\n\
|
|
55
|
+
}\n\
|
|
56
|
+
";
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/* Intersection defines
|
|
2
|
+
#define INTERSECTION_COUNT ###
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
#define NO_HIT (-czm_infinity)
|
|
6
|
+
#define INF_HIT (czm_infinity * 0.5)
|
|
7
|
+
|
|
8
|
+
struct Ray {
|
|
9
|
+
vec3 pos;
|
|
10
|
+
vec3 dir;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
struct Intersections {
|
|
14
|
+
// Don't access these member variables directly - call the functions instead.
|
|
15
|
+
|
|
16
|
+
#if (INTERSECTION_COUNT > 1)
|
|
17
|
+
// Store an array of intersections. Each intersection is composed of:
|
|
18
|
+
// x for the T value
|
|
19
|
+
// y for the shape type - which encodes positive vs negative and entering vs exiting
|
|
20
|
+
// For example:
|
|
21
|
+
// y = 0: positive shape entry
|
|
22
|
+
// y = 1: positive shape exit
|
|
23
|
+
// y = 2: negative shape entry
|
|
24
|
+
// y = 3: negative shape exit
|
|
25
|
+
vec2 intersections[INTERSECTION_COUNT * 2];
|
|
26
|
+
|
|
27
|
+
// Maintain state for future nextIntersection calls
|
|
28
|
+
int index;
|
|
29
|
+
int surroundCount;
|
|
30
|
+
bool surroundIsPositive;
|
|
31
|
+
#else
|
|
32
|
+
// When there's only one positive shape intersection none of the extra stuff is needed.
|
|
33
|
+
float intersections[2];
|
|
34
|
+
#endif
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// Using a define instead of a real function because WebGL1 cannot access array with non-constant index.
|
|
38
|
+
#if (INTERSECTION_COUNT > 1)
|
|
39
|
+
#define getIntersection(/*inout Intersections*/ ix, /*int*/ index) (ix).intersections[(index)].x
|
|
40
|
+
#else
|
|
41
|
+
#define getIntersection(/*inout Intersections*/ ix, /*int*/ index) (ix).intersections[(index)]
|
|
42
|
+
#endif
|
|
43
|
+
|
|
44
|
+
// Using a define instead of a real function because WebGL1 cannot access array with non-constant index.
|
|
45
|
+
#define getIntersectionPair(/*inout Intersections*/ ix, /*int*/ index) vec2(getIntersection((ix), (index) * 2 + 0), getIntersection((ix), (index) * 2 + 1))
|
|
46
|
+
|
|
47
|
+
// Using a define instead of a real function because WebGL1 cannot access array with non-constant index.
|
|
48
|
+
#if (INTERSECTION_COUNT > 1)
|
|
49
|
+
#define setIntersection(/*inout Intersections*/ ix, /*int*/ index, /*float*/ t, /*bool*/ positive, /*enter*/ enter) (ix).intersections[(index)] = vec2((t), float(!positive) * 2.0 + float(!enter))
|
|
50
|
+
#else
|
|
51
|
+
#define setIntersection(/*inout Intersections*/ ix, /*int*/ index, /*float*/ t, /*bool*/ positive, /*enter*/ enter) (ix).intersections[(index)] = (t)
|
|
52
|
+
#endif
|
|
53
|
+
|
|
54
|
+
// Using a define instead of a real function because WebGL1 cannot access array with non-constant index.
|
|
55
|
+
#if (INTERSECTION_COUNT > 1)
|
|
56
|
+
#define setIntersectionPair(/*inout Intersections*/ ix, /*int*/ index, /*vec2*/ entryExit) (ix).intersections[(index) * 2 + 0] = vec2((entryExit).x, float((index) > 0) * 2.0 + 0.0); (ix).intersections[(index) * 2 + 1] = vec2((entryExit).y, float((index) > 0) * 2.0 + 1.0)
|
|
57
|
+
#else
|
|
58
|
+
#define setIntersectionPair(/*inout Intersections*/ ix, /*int*/ index, /*vec2*/ entryExit) (ix).intersections[(index) * 2 + 0] = (entryExit).x; (ix).intersections[(index) * 2 + 1] = (entryExit).y
|
|
59
|
+
#endif
|
|
60
|
+
|
|
61
|
+
#if (INTERSECTION_COUNT > 1)
|
|
62
|
+
void initializeIntersections(inout Intersections ix) {
|
|
63
|
+
// Sort the intersections from min T to max T with bubble sort.
|
|
64
|
+
// Note: If this sorting function changes, some of the intersection test may
|
|
65
|
+
// need to be updated. Search for "bubble sort" to find those areas.
|
|
66
|
+
const int sortPasses = INTERSECTION_COUNT * 2 - 1;
|
|
67
|
+
for (int n = sortPasses; n > 0; --n) {
|
|
68
|
+
for (int i = 0; i < sortPasses; ++i) {
|
|
69
|
+
// The loop should be: for (i = 0; i < n; ++i) {...} but WebGL1 cannot
|
|
70
|
+
// loop with non-constant condition, so it has to break early instead
|
|
71
|
+
if (i >= n) { break; }
|
|
72
|
+
|
|
73
|
+
vec2 intersect0 = ix.intersections[i + 0];
|
|
74
|
+
vec2 intersect1 = ix.intersections[i + 1];
|
|
75
|
+
|
|
76
|
+
float t0 = intersect0.x;
|
|
77
|
+
float t1 = intersect1.x;
|
|
78
|
+
float b0 = intersect0.y;
|
|
79
|
+
float b1 = intersect1.y;
|
|
80
|
+
|
|
81
|
+
float tmin = min(t0, t1);
|
|
82
|
+
float tmax = max(t0, t1);
|
|
83
|
+
float bmin = tmin == t0 ? b0 : b1;
|
|
84
|
+
float bmax = tmin == t0 ? b1 : b0;
|
|
85
|
+
|
|
86
|
+
ix.intersections[i + 0] = vec2(tmin, bmin);
|
|
87
|
+
ix.intersections[i + 1] = vec2(tmax, bmax);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Prepare initial state for nextIntersection
|
|
92
|
+
ix.index = 0;
|
|
93
|
+
ix.surroundCount = 0;
|
|
94
|
+
ix.surroundIsPositive = false;
|
|
95
|
+
}
|
|
96
|
+
#endif
|
|
97
|
+
|
|
98
|
+
#if (INTERSECTION_COUNT > 1)
|
|
99
|
+
vec2 nextIntersection(inout Intersections ix) {
|
|
100
|
+
vec2 entryExitT = vec2(NO_HIT);
|
|
101
|
+
|
|
102
|
+
const int passCount = INTERSECTION_COUNT * 2;
|
|
103
|
+
|
|
104
|
+
if (ix.index == passCount) {
|
|
105
|
+
return entryExitT;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
for (int i = 0; i < passCount; ++i) {
|
|
109
|
+
// The loop should be: for (i = ix.index; i < passCount; ++i) {...} but WebGL1 cannot
|
|
110
|
+
// loop with non-constant condition, so it has to continue instead.
|
|
111
|
+
if (i < ix.index) {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
ix.index = i + 1;
|
|
116
|
+
|
|
117
|
+
vec2 intersect = ix.intersections[i];
|
|
118
|
+
float t = intersect.x;
|
|
119
|
+
bool currShapeIsPositive = intersect.y < 2.0;
|
|
120
|
+
bool enter = mod(intersect.y, 2.0) == 0.0;
|
|
121
|
+
|
|
122
|
+
ix.surroundCount += enter ? +1 : -1;
|
|
123
|
+
ix.surroundIsPositive = currShapeIsPositive ? enter : ix.surroundIsPositive;
|
|
124
|
+
|
|
125
|
+
// entering positive or exiting negative
|
|
126
|
+
if (ix.surroundCount == 1 && ix.surroundIsPositive && enter == currShapeIsPositive) {
|
|
127
|
+
entryExitT.x = t;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// exiting positive or entering negative after being inside positive
|
|
131
|
+
// TODO: Can this be simplified?
|
|
132
|
+
bool exitPositive = !enter && currShapeIsPositive && ix.surroundCount == 0;
|
|
133
|
+
bool enterNegativeFromPositive = enter && !currShapeIsPositive && ix.surroundCount == 2 && ix.surroundIsPositive;
|
|
134
|
+
if (exitPositive || enterNegativeFromPositive) {
|
|
135
|
+
entryExitT.y = t;
|
|
136
|
+
|
|
137
|
+
// entry and exit have been found, so the loop can stop
|
|
138
|
+
if (exitPositive) {
|
|
139
|
+
// After exiting positive shape there is nothing left to intersect, so jump to the end index.
|
|
140
|
+
ix.index = passCount;
|
|
141
|
+
}
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return entryExitT;
|
|
147
|
+
}
|
|
148
|
+
#endif
|
|
149
|
+
|
|
150
|
+
// NOTE: initializeIntersections, nextIntersection aren't even declared unless INTERSECTION_COUNT > 1
|
|
151
|
+
// export { NO_HIT, INF_HIT, Ray, Intersections, getIntersectionPair, setIntersectionPair, initializeIntersections, nextIntersection };
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
//This file is automatically rebuilt by the Cesium build process.
|
|
2
|
+
export default "/* Intersection defines\n\
|
|
3
|
+
#define INTERSECTION_COUNT ###\n\
|
|
4
|
+
*/\n\
|
|
5
|
+
\n\
|
|
6
|
+
#define NO_HIT (-czm_infinity)\n\
|
|
7
|
+
#define INF_HIT (czm_infinity * 0.5)\n\
|
|
8
|
+
\n\
|
|
9
|
+
struct Ray {\n\
|
|
10
|
+
vec3 pos;\n\
|
|
11
|
+
vec3 dir;\n\
|
|
12
|
+
};\n\
|
|
13
|
+
\n\
|
|
14
|
+
struct Intersections {\n\
|
|
15
|
+
// Don't access these member variables directly - call the functions instead.\n\
|
|
16
|
+
\n\
|
|
17
|
+
#if (INTERSECTION_COUNT > 1)\n\
|
|
18
|
+
// Store an array of intersections. Each intersection is composed of:\n\
|
|
19
|
+
// x for the T value\n\
|
|
20
|
+
// y for the shape type - which encodes positive vs negative and entering vs exiting\n\
|
|
21
|
+
// For example:\n\
|
|
22
|
+
// y = 0: positive shape entry\n\
|
|
23
|
+
// y = 1: positive shape exit\n\
|
|
24
|
+
// y = 2: negative shape entry\n\
|
|
25
|
+
// y = 3: negative shape exit\n\
|
|
26
|
+
vec2 intersections[INTERSECTION_COUNT * 2];\n\
|
|
27
|
+
\n\
|
|
28
|
+
// Maintain state for future nextIntersection calls\n\
|
|
29
|
+
int index;\n\
|
|
30
|
+
int surroundCount;\n\
|
|
31
|
+
bool surroundIsPositive;\n\
|
|
32
|
+
#else\n\
|
|
33
|
+
// When there's only one positive shape intersection none of the extra stuff is needed.\n\
|
|
34
|
+
float intersections[2];\n\
|
|
35
|
+
#endif\n\
|
|
36
|
+
};\n\
|
|
37
|
+
\n\
|
|
38
|
+
// Using a define instead of a real function because WebGL1 cannot access array with non-constant index.\n\
|
|
39
|
+
#if (INTERSECTION_COUNT > 1)\n\
|
|
40
|
+
#define getIntersection(/*inout Intersections*/ ix, /*int*/ index) (ix).intersections[(index)].x\n\
|
|
41
|
+
#else\n\
|
|
42
|
+
#define getIntersection(/*inout Intersections*/ ix, /*int*/ index) (ix).intersections[(index)]\n\
|
|
43
|
+
#endif\n\
|
|
44
|
+
\n\
|
|
45
|
+
// Using a define instead of a real function because WebGL1 cannot access array with non-constant index.\n\
|
|
46
|
+
#define getIntersectionPair(/*inout Intersections*/ ix, /*int*/ index) vec2(getIntersection((ix), (index) * 2 + 0), getIntersection((ix), (index) * 2 + 1))\n\
|
|
47
|
+
\n\
|
|
48
|
+
// Using a define instead of a real function because WebGL1 cannot access array with non-constant index.\n\
|
|
49
|
+
#if (INTERSECTION_COUNT > 1)\n\
|
|
50
|
+
#define setIntersection(/*inout Intersections*/ ix, /*int*/ index, /*float*/ t, /*bool*/ positive, /*enter*/ enter) (ix).intersections[(index)] = vec2((t), float(!positive) * 2.0 + float(!enter))\n\
|
|
51
|
+
#else\n\
|
|
52
|
+
#define setIntersection(/*inout Intersections*/ ix, /*int*/ index, /*float*/ t, /*bool*/ positive, /*enter*/ enter) (ix).intersections[(index)] = (t)\n\
|
|
53
|
+
#endif\n\
|
|
54
|
+
\n\
|
|
55
|
+
// Using a define instead of a real function because WebGL1 cannot access array with non-constant index.\n\
|
|
56
|
+
#if (INTERSECTION_COUNT > 1)\n\
|
|
57
|
+
#define setIntersectionPair(/*inout Intersections*/ ix, /*int*/ index, /*vec2*/ entryExit) (ix).intersections[(index) * 2 + 0] = vec2((entryExit).x, float((index) > 0) * 2.0 + 0.0); (ix).intersections[(index) * 2 + 1] = vec2((entryExit).y, float((index) > 0) * 2.0 + 1.0)\n\
|
|
58
|
+
#else\n\
|
|
59
|
+
#define setIntersectionPair(/*inout Intersections*/ ix, /*int*/ index, /*vec2*/ entryExit) (ix).intersections[(index) * 2 + 0] = (entryExit).x; (ix).intersections[(index) * 2 + 1] = (entryExit).y\n\
|
|
60
|
+
#endif\n\
|
|
61
|
+
\n\
|
|
62
|
+
#if (INTERSECTION_COUNT > 1)\n\
|
|
63
|
+
void initializeIntersections(inout Intersections ix) {\n\
|
|
64
|
+
// Sort the intersections from min T to max T with bubble sort.\n\
|
|
65
|
+
// Note: If this sorting function changes, some of the intersection test may\n\
|
|
66
|
+
// need to be updated. Search for \"bubble sort\" to find those areas.\n\
|
|
67
|
+
const int sortPasses = INTERSECTION_COUNT * 2 - 1;\n\
|
|
68
|
+
for (int n = sortPasses; n > 0; --n) {\n\
|
|
69
|
+
for (int i = 0; i < sortPasses; ++i) {\n\
|
|
70
|
+
// The loop should be: for (i = 0; i < n; ++i) {...} but WebGL1 cannot\n\
|
|
71
|
+
// loop with non-constant condition, so it has to break early instead\n\
|
|
72
|
+
if (i >= n) { break; }\n\
|
|
73
|
+
\n\
|
|
74
|
+
vec2 intersect0 = ix.intersections[i + 0];\n\
|
|
75
|
+
vec2 intersect1 = ix.intersections[i + 1];\n\
|
|
76
|
+
\n\
|
|
77
|
+
float t0 = intersect0.x;\n\
|
|
78
|
+
float t1 = intersect1.x;\n\
|
|
79
|
+
float b0 = intersect0.y;\n\
|
|
80
|
+
float b1 = intersect1.y;\n\
|
|
81
|
+
\n\
|
|
82
|
+
float tmin = min(t0, t1);\n\
|
|
83
|
+
float tmax = max(t0, t1);\n\
|
|
84
|
+
float bmin = tmin == t0 ? b0 : b1;\n\
|
|
85
|
+
float bmax = tmin == t0 ? b1 : b0;\n\
|
|
86
|
+
\n\
|
|
87
|
+
ix.intersections[i + 0] = vec2(tmin, bmin);\n\
|
|
88
|
+
ix.intersections[i + 1] = vec2(tmax, bmax);\n\
|
|
89
|
+
}\n\
|
|
90
|
+
}\n\
|
|
91
|
+
\n\
|
|
92
|
+
// Prepare initial state for nextIntersection\n\
|
|
93
|
+
ix.index = 0;\n\
|
|
94
|
+
ix.surroundCount = 0;\n\
|
|
95
|
+
ix.surroundIsPositive = false;\n\
|
|
96
|
+
}\n\
|
|
97
|
+
#endif\n\
|
|
98
|
+
\n\
|
|
99
|
+
#if (INTERSECTION_COUNT > 1)\n\
|
|
100
|
+
vec2 nextIntersection(inout Intersections ix) {\n\
|
|
101
|
+
vec2 entryExitT = vec2(NO_HIT);\n\
|
|
102
|
+
\n\
|
|
103
|
+
const int passCount = INTERSECTION_COUNT * 2;\n\
|
|
104
|
+
\n\
|
|
105
|
+
if (ix.index == passCount) {\n\
|
|
106
|
+
return entryExitT;\n\
|
|
107
|
+
}\n\
|
|
108
|
+
\n\
|
|
109
|
+
for (int i = 0; i < passCount; ++i) {\n\
|
|
110
|
+
// The loop should be: for (i = ix.index; i < passCount; ++i) {...} but WebGL1 cannot\n\
|
|
111
|
+
// loop with non-constant condition, so it has to continue instead.\n\
|
|
112
|
+
if (i < ix.index) {\n\
|
|
113
|
+
continue;\n\
|
|
114
|
+
}\n\
|
|
115
|
+
\n\
|
|
116
|
+
ix.index = i + 1;\n\
|
|
117
|
+
\n\
|
|
118
|
+
vec2 intersect = ix.intersections[i];\n\
|
|
119
|
+
float t = intersect.x;\n\
|
|
120
|
+
bool currShapeIsPositive = intersect.y < 2.0;\n\
|
|
121
|
+
bool enter = mod(intersect.y, 2.0) == 0.0;\n\
|
|
122
|
+
\n\
|
|
123
|
+
ix.surroundCount += enter ? +1 : -1;\n\
|
|
124
|
+
ix.surroundIsPositive = currShapeIsPositive ? enter : ix.surroundIsPositive;\n\
|
|
125
|
+
\n\
|
|
126
|
+
// entering positive or exiting negative\n\
|
|
127
|
+
if (ix.surroundCount == 1 && ix.surroundIsPositive && enter == currShapeIsPositive) {\n\
|
|
128
|
+
entryExitT.x = t;\n\
|
|
129
|
+
}\n\
|
|
130
|
+
\n\
|
|
131
|
+
// exiting positive or entering negative after being inside positive\n\
|
|
132
|
+
// TODO: Can this be simplified?\n\
|
|
133
|
+
bool exitPositive = !enter && currShapeIsPositive && ix.surroundCount == 0;\n\
|
|
134
|
+
bool enterNegativeFromPositive = enter && !currShapeIsPositive && ix.surroundCount == 2 && ix.surroundIsPositive;\n\
|
|
135
|
+
if (exitPositive || enterNegativeFromPositive) {\n\
|
|
136
|
+
entryExitT.y = t;\n\
|
|
137
|
+
\n\
|
|
138
|
+
// entry and exit have been found, so the loop can stop\n\
|
|
139
|
+
if (exitPositive) {\n\
|
|
140
|
+
// After exiting positive shape there is nothing left to intersect, so jump to the end index.\n\
|
|
141
|
+
ix.index = passCount;\n\
|
|
142
|
+
}\n\
|
|
143
|
+
break;\n\
|
|
144
|
+
}\n\
|
|
145
|
+
}\n\
|
|
146
|
+
\n\
|
|
147
|
+
return entryExitT;\n\
|
|
148
|
+
}\n\
|
|
149
|
+
#endif\n\
|
|
150
|
+
\n\
|
|
151
|
+
// NOTE: initializeIntersections, nextIntersection aren't even declared unless INTERSECTION_COUNT > 1\n\
|
|
152
|
+
// export { NO_HIT, INF_HIT, Ray, Intersections, getIntersectionPair, setIntersectionPair, initializeIntersections, nextIntersection };\n\
|
|
153
|
+
";
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// See Octree.glsl for the definitions of SampleData and intMod
|
|
2
|
+
|
|
3
|
+
/* Megatexture defines (set in Scene/VoxelRenderResources.js)
|
|
4
|
+
#define SAMPLE_COUNT ###
|
|
5
|
+
#define NEAREST_SAMPLING
|
|
6
|
+
#define PADDING
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
uniform ivec2 u_megatextureSliceDimensions; // number of slices per tile, in two dimensions
|
|
10
|
+
uniform ivec2 u_megatextureTileDimensions; // number of tiles per megatexture, in two dimensions
|
|
11
|
+
uniform vec2 u_megatextureVoxelSizeUv;
|
|
12
|
+
uniform vec2 u_megatextureSliceSizeUv;
|
|
13
|
+
uniform vec2 u_megatextureTileSizeUv;
|
|
14
|
+
|
|
15
|
+
uniform ivec3 u_dimensions; // does not include padding
|
|
16
|
+
#if defined(PADDING)
|
|
17
|
+
uniform ivec3 u_paddingBefore;
|
|
18
|
+
uniform ivec3 u_paddingAfter;
|
|
19
|
+
#endif
|
|
20
|
+
|
|
21
|
+
// Integer min, max, clamp: For WebGL1 only
|
|
22
|
+
int intMin(int a, int b) {
|
|
23
|
+
return a <= b ? a : b;
|
|
24
|
+
}
|
|
25
|
+
int intMax(int a, int b) {
|
|
26
|
+
return a >= b ? a : b;
|
|
27
|
+
}
|
|
28
|
+
int intClamp(int v, int minVal, int maxVal) {
|
|
29
|
+
return intMin(intMax(v, minVal), maxVal);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
vec2 index1DTo2DTexcoord(int index, ivec2 dimensions, vec2 uvScale)
|
|
33
|
+
{
|
|
34
|
+
int indexX = intMod(index, dimensions.x);
|
|
35
|
+
int indexY = index / dimensions.x;
|
|
36
|
+
return vec2(indexX, indexY) * uvScale;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/*
|
|
40
|
+
How is 3D data stored in a 2D megatexture?
|
|
41
|
+
|
|
42
|
+
In this example there is only one loaded tile and it has 2x2x2 voxels (8 voxels total).
|
|
43
|
+
The data is sliced by Z. The data at Z = 0 is placed in texels (0,0), (0,1), (1,0), (1,1) and
|
|
44
|
+
the data at Z = 1 is placed in texels (2,0), (2,1), (3,0), (3,1).
|
|
45
|
+
Note that there could be empty space in the megatexture because it's a power of two.
|
|
46
|
+
|
|
47
|
+
0 1 2 3
|
|
48
|
+
+---+---+---+---+
|
|
49
|
+
| | | | | 3
|
|
50
|
+
+---+---+---+---+
|
|
51
|
+
| | | | | 2
|
|
52
|
+
+-------+-------+
|
|
53
|
+
|010|110|011|111| 1
|
|
54
|
+
|--- ---|--- ---|
|
|
55
|
+
|000|100|001|101| 0
|
|
56
|
+
+-------+-------+
|
|
57
|
+
|
|
58
|
+
When doing linear interpolation the megatexture needs to be sampled twice: once for
|
|
59
|
+
the Z slice above the voxel coordinate and once for the slice below. The two slices
|
|
60
|
+
are interpolated with fract(coord.z - 0.5). For example, a Z coordinate of 1.0 is
|
|
61
|
+
halfway between two Z slices so the interpolation factor is 0.5. Below is a side view
|
|
62
|
+
of the 3D voxel grid with voxel coordinates on the left side.
|
|
63
|
+
|
|
64
|
+
2 +---+
|
|
65
|
+
|001|
|
|
66
|
+
1 +-z-+
|
|
67
|
+
|000|
|
|
68
|
+
0 +---+
|
|
69
|
+
|
|
70
|
+
When doing nearest neighbor the megatexture only needs to be sampled once at the closest Z slice.
|
|
71
|
+
*/
|
|
72
|
+
|
|
73
|
+
Properties getPropertiesFromMegatexture(in SampleData sampleData) {
|
|
74
|
+
vec3 tileUv = clamp(sampleData.tileUv, vec3(0.0), vec3(1.0)); // TODO is the clamp necessary?
|
|
75
|
+
int tileIndex = sampleData.megatextureIndex;
|
|
76
|
+
vec3 voxelCoord = tileUv * vec3(u_dimensions);
|
|
77
|
+
ivec3 voxelDimensions = u_dimensions;
|
|
78
|
+
|
|
79
|
+
#if defined(PADDING)
|
|
80
|
+
voxelDimensions += u_paddingBefore + u_paddingAfter;
|
|
81
|
+
voxelCoord += vec3(u_paddingBefore);
|
|
82
|
+
#endif
|
|
83
|
+
|
|
84
|
+
#if defined(NEAREST_SAMPLING)
|
|
85
|
+
// Round to the center of the nearest voxel
|
|
86
|
+
voxelCoord = floor(voxelCoord + vec3(0.5));
|
|
87
|
+
#endif
|
|
88
|
+
|
|
89
|
+
// Tile location
|
|
90
|
+
vec2 tileUvOffset = index1DTo2DTexcoord(tileIndex, u_megatextureTileDimensions, u_megatextureTileSizeUv);
|
|
91
|
+
|
|
92
|
+
// Slice location
|
|
93
|
+
float slice = voxelCoord.z - 0.5;
|
|
94
|
+
int sliceIndex = int(floor(slice));
|
|
95
|
+
int sliceIndex0 = intClamp(sliceIndex, 0, voxelDimensions.z - 1);
|
|
96
|
+
vec2 sliceUvOffset0 = index1DTo2DTexcoord(sliceIndex0, u_megatextureSliceDimensions, u_megatextureSliceSizeUv);
|
|
97
|
+
|
|
98
|
+
// Voxel location
|
|
99
|
+
vec2 voxelUvOffset = clamp(voxelCoord.xy, vec2(0.5), vec2(voxelDimensions.xy) - vec2(0.5)) * u_megatextureVoxelSizeUv;
|
|
100
|
+
|
|
101
|
+
// Final location in the megatexture
|
|
102
|
+
vec2 uv0 = tileUvOffset + sliceUvOffset0 + voxelUvOffset;
|
|
103
|
+
|
|
104
|
+
#if defined(NEAREST_SAMPLING)
|
|
105
|
+
return getPropertiesFromMegatextureAtUv(uv0);
|
|
106
|
+
#else
|
|
107
|
+
float sliceLerp = fract(slice);
|
|
108
|
+
int sliceIndex1 = intMin(sliceIndex + 1, voxelDimensions.z - 1);
|
|
109
|
+
vec2 sliceUvOffset1 = index1DTo2DTexcoord(sliceIndex1, u_megatextureSliceDimensions, u_megatextureSliceSizeUv);
|
|
110
|
+
vec2 uv1 = tileUvOffset + sliceUvOffset1 + voxelUvOffset;
|
|
111
|
+
Properties properties0 = getPropertiesFromMegatextureAtUv(uv0);
|
|
112
|
+
Properties properties1 = getPropertiesFromMegatextureAtUv(uv1);
|
|
113
|
+
return mixProperties(properties0, properties1, sliceLerp);
|
|
114
|
+
#endif
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Convert an array of sample datas to a final weighted properties.
|
|
118
|
+
Properties accumulatePropertiesFromMegatexture(in SampleData sampleDatas[SAMPLE_COUNT]) {
|
|
119
|
+
#if (SAMPLE_COUNT == 1)
|
|
120
|
+
return getPropertiesFromMegatexture(sampleDatas[0]);
|
|
121
|
+
#else
|
|
122
|
+
// When more than one sample is taken the accumulator needs to start at 0
|
|
123
|
+
Properties properties = clearProperties();
|
|
124
|
+
for (int i = 0; i < SAMPLE_COUNT; ++i) {
|
|
125
|
+
float weight = sampleDatas[i].weight;
|
|
126
|
+
|
|
127
|
+
// Avoid reading the megatexture when the weight is 0 as it can be costly.
|
|
128
|
+
if (weight > 0.0) {
|
|
129
|
+
Properties tempProperties = getPropertiesFromMegatexture(sampleDatas[i]);
|
|
130
|
+
tempProperties = scaleProperties(tempProperties, weight);
|
|
131
|
+
properties = sumProperties(properties, tempProperties);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return properties;
|
|
135
|
+
#endif
|
|
136
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
//This file is automatically rebuilt by the Cesium build process.
|
|
2
|
+
export default "// See Octree.glsl for the definitions of SampleData and intMod\n\
|
|
3
|
+
\n\
|
|
4
|
+
/* Megatexture defines (set in Scene/VoxelRenderResources.js)\n\
|
|
5
|
+
#define SAMPLE_COUNT ###\n\
|
|
6
|
+
#define NEAREST_SAMPLING\n\
|
|
7
|
+
#define PADDING\n\
|
|
8
|
+
*/\n\
|
|
9
|
+
\n\
|
|
10
|
+
uniform ivec2 u_megatextureSliceDimensions; // number of slices per tile, in two dimensions\n\
|
|
11
|
+
uniform ivec2 u_megatextureTileDimensions; // number of tiles per megatexture, in two dimensions\n\
|
|
12
|
+
uniform vec2 u_megatextureVoxelSizeUv;\n\
|
|
13
|
+
uniform vec2 u_megatextureSliceSizeUv;\n\
|
|
14
|
+
uniform vec2 u_megatextureTileSizeUv;\n\
|
|
15
|
+
\n\
|
|
16
|
+
uniform ivec3 u_dimensions; // does not include padding\n\
|
|
17
|
+
#if defined(PADDING)\n\
|
|
18
|
+
uniform ivec3 u_paddingBefore;\n\
|
|
19
|
+
uniform ivec3 u_paddingAfter;\n\
|
|
20
|
+
#endif\n\
|
|
21
|
+
\n\
|
|
22
|
+
// Integer min, max, clamp: For WebGL1 only\n\
|
|
23
|
+
int intMin(int a, int b) {\n\
|
|
24
|
+
return a <= b ? a : b;\n\
|
|
25
|
+
}\n\
|
|
26
|
+
int intMax(int a, int b) {\n\
|
|
27
|
+
return a >= b ? a : b;\n\
|
|
28
|
+
}\n\
|
|
29
|
+
int intClamp(int v, int minVal, int maxVal) {\n\
|
|
30
|
+
return intMin(intMax(v, minVal), maxVal);\n\
|
|
31
|
+
}\n\
|
|
32
|
+
\n\
|
|
33
|
+
vec2 index1DTo2DTexcoord(int index, ivec2 dimensions, vec2 uvScale)\n\
|
|
34
|
+
{\n\
|
|
35
|
+
int indexX = intMod(index, dimensions.x);\n\
|
|
36
|
+
int indexY = index / dimensions.x;\n\
|
|
37
|
+
return vec2(indexX, indexY) * uvScale;\n\
|
|
38
|
+
}\n\
|
|
39
|
+
\n\
|
|
40
|
+
/*\n\
|
|
41
|
+
How is 3D data stored in a 2D megatexture?\n\
|
|
42
|
+
\n\
|
|
43
|
+
In this example there is only one loaded tile and it has 2x2x2 voxels (8 voxels total).\n\
|
|
44
|
+
The data is sliced by Z. The data at Z = 0 is placed in texels (0,0), (0,1), (1,0), (1,1) and\n\
|
|
45
|
+
the data at Z = 1 is placed in texels (2,0), (2,1), (3,0), (3,1).\n\
|
|
46
|
+
Note that there could be empty space in the megatexture because it's a power of two.\n\
|
|
47
|
+
\n\
|
|
48
|
+
0 1 2 3\n\
|
|
49
|
+
+---+---+---+---+\n\
|
|
50
|
+
| | | | | 3\n\
|
|
51
|
+
+---+---+---+---+\n\
|
|
52
|
+
| | | | | 2\n\
|
|
53
|
+
+-------+-------+\n\
|
|
54
|
+
|010|110|011|111| 1\n\
|
|
55
|
+
|--- ---|--- ---|\n\
|
|
56
|
+
|000|100|001|101| 0\n\
|
|
57
|
+
+-------+-------+\n\
|
|
58
|
+
\n\
|
|
59
|
+
When doing linear interpolation the megatexture needs to be sampled twice: once for\n\
|
|
60
|
+
the Z slice above the voxel coordinate and once for the slice below. The two slices\n\
|
|
61
|
+
are interpolated with fract(coord.z - 0.5). For example, a Z coordinate of 1.0 is\n\
|
|
62
|
+
halfway between two Z slices so the interpolation factor is 0.5. Below is a side view\n\
|
|
63
|
+
of the 3D voxel grid with voxel coordinates on the left side.\n\
|
|
64
|
+
\n\
|
|
65
|
+
2 +---+\n\
|
|
66
|
+
|001|\n\
|
|
67
|
+
1 +-z-+\n\
|
|
68
|
+
|000|\n\
|
|
69
|
+
0 +---+\n\
|
|
70
|
+
\n\
|
|
71
|
+
When doing nearest neighbor the megatexture only needs to be sampled once at the closest Z slice.\n\
|
|
72
|
+
*/\n\
|
|
73
|
+
\n\
|
|
74
|
+
Properties getPropertiesFromMegatexture(in SampleData sampleData) {\n\
|
|
75
|
+
vec3 tileUv = clamp(sampleData.tileUv, vec3(0.0), vec3(1.0)); // TODO is the clamp necessary?\n\
|
|
76
|
+
int tileIndex = sampleData.megatextureIndex;\n\
|
|
77
|
+
vec3 voxelCoord = tileUv * vec3(u_dimensions);\n\
|
|
78
|
+
ivec3 voxelDimensions = u_dimensions;\n\
|
|
79
|
+
\n\
|
|
80
|
+
#if defined(PADDING)\n\
|
|
81
|
+
voxelDimensions += u_paddingBefore + u_paddingAfter;\n\
|
|
82
|
+
voxelCoord += vec3(u_paddingBefore);\n\
|
|
83
|
+
#endif\n\
|
|
84
|
+
\n\
|
|
85
|
+
#if defined(NEAREST_SAMPLING)\n\
|
|
86
|
+
// Round to the center of the nearest voxel\n\
|
|
87
|
+
voxelCoord = floor(voxelCoord + vec3(0.5));\n\
|
|
88
|
+
#endif\n\
|
|
89
|
+
\n\
|
|
90
|
+
// Tile location\n\
|
|
91
|
+
vec2 tileUvOffset = index1DTo2DTexcoord(tileIndex, u_megatextureTileDimensions, u_megatextureTileSizeUv);\n\
|
|
92
|
+
\n\
|
|
93
|
+
// Slice location\n\
|
|
94
|
+
float slice = voxelCoord.z - 0.5;\n\
|
|
95
|
+
int sliceIndex = int(floor(slice));\n\
|
|
96
|
+
int sliceIndex0 = intClamp(sliceIndex, 0, voxelDimensions.z - 1);\n\
|
|
97
|
+
vec2 sliceUvOffset0 = index1DTo2DTexcoord(sliceIndex0, u_megatextureSliceDimensions, u_megatextureSliceSizeUv);\n\
|
|
98
|
+
\n\
|
|
99
|
+
// Voxel location\n\
|
|
100
|
+
vec2 voxelUvOffset = clamp(voxelCoord.xy, vec2(0.5), vec2(voxelDimensions.xy) - vec2(0.5)) * u_megatextureVoxelSizeUv;\n\
|
|
101
|
+
\n\
|
|
102
|
+
// Final location in the megatexture\n\
|
|
103
|
+
vec2 uv0 = tileUvOffset + sliceUvOffset0 + voxelUvOffset;\n\
|
|
104
|
+
\n\
|
|
105
|
+
#if defined(NEAREST_SAMPLING)\n\
|
|
106
|
+
return getPropertiesFromMegatextureAtUv(uv0);\n\
|
|
107
|
+
#else\n\
|
|
108
|
+
float sliceLerp = fract(slice);\n\
|
|
109
|
+
int sliceIndex1 = intMin(sliceIndex + 1, voxelDimensions.z - 1);\n\
|
|
110
|
+
vec2 sliceUvOffset1 = index1DTo2DTexcoord(sliceIndex1, u_megatextureSliceDimensions, u_megatextureSliceSizeUv);\n\
|
|
111
|
+
vec2 uv1 = tileUvOffset + sliceUvOffset1 + voxelUvOffset;\n\
|
|
112
|
+
Properties properties0 = getPropertiesFromMegatextureAtUv(uv0);\n\
|
|
113
|
+
Properties properties1 = getPropertiesFromMegatextureAtUv(uv1);\n\
|
|
114
|
+
return mixProperties(properties0, properties1, sliceLerp);\n\
|
|
115
|
+
#endif\n\
|
|
116
|
+
}\n\
|
|
117
|
+
\n\
|
|
118
|
+
// Convert an array of sample datas to a final weighted properties.\n\
|
|
119
|
+
Properties accumulatePropertiesFromMegatexture(in SampleData sampleDatas[SAMPLE_COUNT]) {\n\
|
|
120
|
+
#if (SAMPLE_COUNT == 1)\n\
|
|
121
|
+
return getPropertiesFromMegatexture(sampleDatas[0]);\n\
|
|
122
|
+
#else\n\
|
|
123
|
+
// When more than one sample is taken the accumulator needs to start at 0\n\
|
|
124
|
+
Properties properties = clearProperties();\n\
|
|
125
|
+
for (int i = 0; i < SAMPLE_COUNT; ++i) {\n\
|
|
126
|
+
float weight = sampleDatas[i].weight;\n\
|
|
127
|
+
\n\
|
|
128
|
+
// Avoid reading the megatexture when the weight is 0 as it can be costly.\n\
|
|
129
|
+
if (weight > 0.0) {\n\
|
|
130
|
+
Properties tempProperties = getPropertiesFromMegatexture(sampleDatas[i]);\n\
|
|
131
|
+
tempProperties = scaleProperties(tempProperties, weight);\n\
|
|
132
|
+
properties = sumProperties(properties, tempProperties);\n\
|
|
133
|
+
}\n\
|
|
134
|
+
}\n\
|
|
135
|
+
return properties;\n\
|
|
136
|
+
#endif\n\
|
|
137
|
+
}\n\
|
|
138
|
+
";
|