@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,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
|
+
}
|