Megatexture.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  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. ";