@cesium/engine
Version:
CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.
126 lines (125 loc) • 5.15 kB
JavaScript
//This file is automatically rebuilt by the Cesium build process.
export default "// See Octree.glsl for the definitions of SampleData and intMod\n\
\n\
/* Megatexture defines (set in Scene/VoxelRenderResources.js)\n\
#define SAMPLE_COUNT ###\n\
#define NEAREST_SAMPLING\n\
#define PADDING\n\
*/\n\
\n\
uniform ivec2 u_megatextureSliceDimensions; // number of slices per tile, in two dimensions\n\
uniform ivec2 u_megatextureTileDimensions; // number of tiles per megatexture, in two dimensions\n\
uniform vec2 u_megatextureVoxelSizeUv;\n\
uniform vec2 u_megatextureSliceSizeUv;\n\
uniform vec2 u_megatextureTileSizeUv;\n\
\n\
// Integer min, max, clamp: For WebGL1 only\n\
int intMin(int a, int b) {\n\
return a <= b ? a : b;\n\
}\n\
int intMax(int a, int b) {\n\
return a >= b ? a : b;\n\
}\n\
int intClamp(int v, int minVal, int maxVal) {\n\
return intMin(intMax(v, minVal), maxVal);\n\
}\n\
\n\
vec2 index1DTo2DTexcoord(int index, ivec2 dimensions, vec2 uvScale)\n\
{\n\
int indexX = intMod(index, dimensions.x);\n\
int indexY = index / dimensions.x;\n\
return vec2(indexX, indexY) * uvScale;\n\
}\n\
\n\
/*\n\
How is 3D data stored in a 2D megatexture?\n\
\n\
In this example there is only one loaded tile and it has 2x2x2 voxels (8 voxels total).\n\
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\
the data at Z = 1 is placed in texels (2,0), (2,1), (3,0), (3,1).\n\
Note that there could be empty space in the megatexture because it's a power of two.\n\
\n\
0 1 2 3\n\
+---+---+---+---+\n\
| | | | | 3\n\
+---+---+---+---+\n\
| | | | | 2\n\
+-------+-------+\n\
|010|110|011|111| 1\n\
|--- ---|--- ---|\n\
|000|100|001|101| 0\n\
+-------+-------+\n\
\n\
When doing linear interpolation the megatexture needs to be sampled twice: once for\n\
the Z slice above the voxel coordinate and once for the slice below. The two slices\n\
are interpolated with fract(coord.z - 0.5). For example, a Z coordinate of 1.0 is\n\
halfway between two Z slices so the interpolation factor is 0.5. Below is a side view\n\
of the 3D voxel grid with voxel coordinates on the left side.\n\
\n\
2 +---+\n\
|001|\n\
1 +-z-+\n\
|000|\n\
0 +---+\n\
\n\
When doing nearest neighbor the megatexture only needs to be sampled once at the closest Z slice.\n\
*/\n\
\n\
Properties getPropertiesFromMegatexture(in SampleData sampleData) {\n\
int tileIndex = sampleData.megatextureIndex;\n\
\n\
vec3 voxelCoord = sampleData.inputCoordinate;\n\
#if defined(NEAREST_SAMPLING)\n\
// Round to the center of the nearest voxel\n\
voxelCoord = floor(voxelCoord) + vec3(0.5);\n\
#endif\n\
\n\
// Tile location\n\
vec2 tileUvOffset = index1DTo2DTexcoord(tileIndex, u_megatextureTileDimensions, u_megatextureTileSizeUv);\n\
\n\
// Slice location\n\
float slice = voxelCoord.z - 0.5;\n\
int sliceIndex = int(floor(slice));\n\
int sliceIndex0 = intClamp(sliceIndex, 0, u_inputDimensions.z - 1);\n\
vec2 sliceUvOffset0 = index1DTo2DTexcoord(sliceIndex0, u_megatextureSliceDimensions, u_megatextureSliceSizeUv);\n\
\n\
// Voxel location\n\
vec2 voxelUvOffset = clamp(voxelCoord.xy, vec2(0.5), vec2(u_inputDimensions.xy) - vec2(0.5)) * u_megatextureVoxelSizeUv;\n\
\n\
// Final location in the megatexture\n\
vec2 uv0 = tileUvOffset + sliceUvOffset0 + voxelUvOffset;\n\
\n\
#if defined(NEAREST_SAMPLING)\n\
return getPropertiesFromMegatextureAtUv(uv0);\n\
#else\n\
float sliceLerp = fract(slice);\n\
int sliceIndex1 = intMin(sliceIndex + 1, u_inputDimensions.z - 1);\n\
vec2 sliceUvOffset1 = index1DTo2DTexcoord(sliceIndex1, u_megatextureSliceDimensions, u_megatextureSliceSizeUv);\n\
vec2 uv1 = tileUvOffset + sliceUvOffset1 + voxelUvOffset;\n\
Properties properties0 = getPropertiesFromMegatextureAtUv(uv0);\n\
Properties properties1 = getPropertiesFromMegatextureAtUv(uv1);\n\
return mixProperties(properties0, properties1, sliceLerp);\n\
#endif\n\
}\n\
\n\
// Convert an array of sample datas to a final weighted properties.\n\
Properties accumulatePropertiesFromMegatexture(in SampleData sampleDatas[SAMPLE_COUNT]) {\n\
#if (SAMPLE_COUNT == 1)\n\
return getPropertiesFromMegatexture(sampleDatas[0]);\n\
#else\n\
// When more than one sample is taken the accumulator needs to start at 0\n\
Properties properties = clearProperties();\n\
for (int i = 0; i < SAMPLE_COUNT; ++i) {\n\
float weight = sampleDatas[i].weight;\n\
\n\
// Avoid reading the megatexture when the weight is 0 as it can be costly.\n\
if (weight > 0.0) {\n\
Properties tempProperties = getPropertiesFromMegatexture(sampleDatas[i]);\n\
tempProperties = scaleProperties(tempProperties, weight);\n\
properties = sumProperties(properties, tempProperties);\n\
}\n\
}\n\
return properties;\n\
#endif\n\
}\n\
";