智慧水务管理系统 - 精河县供水工程综合管理平台

VoxelRenderResources.js 7.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. import Cartesian3 from "../Core/Cartesian3.js";
  2. import combine from "../Core/combine.js";
  3. import defined from "../Core/defined.js";
  4. import ShaderBuilder from "../Renderer/ShaderBuilder.js";
  5. import ShaderDestination from "../Renderer/ShaderDestination.js";
  6. import VoxelUtils from "../Shaders/Voxels/VoxelUtils.js";
  7. import VoxelFS from "../Shaders/Voxels/VoxelFS.js";
  8. import VoxelVS from "../Shaders/Voxels/VoxelVS.js";
  9. import IntersectionUtils from "../Shaders/Voxels/IntersectionUtils.js";
  10. import IntersectDepth from "../Shaders/Voxels/IntersectDepth.js";
  11. import IntersectPlane from "../Shaders/Voxels/IntersectPlane.js";
  12. import IntersectLongitude from "../Shaders/Voxels/IntersectLongitude.js";
  13. import IntersectBox from "../Shaders/Voxels/IntersectBox.js";
  14. import IntersectCylinder from "../Shaders/Voxels/IntersectCylinder.js";
  15. import IntersectEllipsoid from "../Shaders/Voxels/IntersectEllipsoid.js";
  16. import Intersection from "../Shaders/Voxels/Intersection.js";
  17. import convertLocalToBoxUv from "../Shaders/Voxels/convertLocalToBoxUv.js";
  18. import convertLocalToCylinderUv from "../Shaders/Voxels/convertLocalToCylinderUv.js";
  19. import convertLocalToEllipsoidUv from "../Shaders/Voxels/convertLocalToEllipsoidUv.js";
  20. import Octree from "../Shaders/Voxels/Octree.js";
  21. import Megatexture from "../Shaders/Voxels/Megatexture.js";
  22. import VoxelMetadataOrder from "./VoxelMetadataOrder.js";
  23. /**
  24. * Set up render resources, including basic shader code, for rendering
  25. * a Voxel primitive.
  26. * The shader code generated by this function may be modified in later stages.
  27. * @constructor
  28. * @param {VoxelPrimitive} primitive
  29. *
  30. * @private
  31. */
  32. function VoxelRenderResources(primitive) {
  33. const shaderBuilder = new ShaderBuilder();
  34. /**
  35. * An object used to build a shader incrementally. Each pipeline stage
  36. * may add lines of shader code to this object.
  37. *
  38. * @type {ShaderBuilder}
  39. * @readonly
  40. *
  41. * @private
  42. */
  43. this.shaderBuilder = shaderBuilder;
  44. // Custom shader uniforms
  45. const customShader = primitive._customShader;
  46. const uniformMap = combine(primitive._uniformMap, customShader.uniformMap);
  47. primitive._uniformMap = uniformMap;
  48. const customShaderUniforms = customShader.uniforms;
  49. for (const uniformName in customShaderUniforms) {
  50. if (customShaderUniforms.hasOwnProperty(uniformName)) {
  51. const uniform = customShaderUniforms[uniformName];
  52. shaderBuilder.addUniform(
  53. uniform.type,
  54. uniformName,
  55. ShaderDestination.FRAGMENT,
  56. );
  57. }
  58. }
  59. // The reason this uniform is added by shader builder is because some of the
  60. // dynamically generated shader code reads from it.
  61. shaderBuilder.addUniform(
  62. "sampler3D",
  63. "u_megatextureTextures[METADATA_COUNT]",
  64. ShaderDestination.FRAGMENT,
  65. );
  66. /**
  67. * A dictionary mapping uniform name to functions that return the uniform
  68. * values.
  69. * @private
  70. * @type {Object<string, Function>}
  71. */
  72. this.uniformMap = uniformMap;
  73. const clippingPlanes = primitive._clippingPlanes;
  74. const clippingPlanesLength =
  75. defined(clippingPlanes) && clippingPlanes.enabled
  76. ? clippingPlanes.length
  77. : 0;
  78. this.clippingPlanes = clippingPlanes;
  79. this.clippingPlanesLength = clippingPlanesLength;
  80. const renderBoundPlanes = primitive._shape.renderBoundPlanes;
  81. const renderBoundPlanesLength = renderBoundPlanes?.length ?? 0;
  82. this.renderBoundPlanes = renderBoundPlanes;
  83. this.renderBoundPlanesLength = renderBoundPlanesLength;
  84. // Build shader
  85. shaderBuilder.addVertexLines([VoxelVS]);
  86. if (primitive.provider.metadataOrder === VoxelMetadataOrder.Y_UP) {
  87. shaderBuilder.addDefine(
  88. "Y_UP_METADATA_ORDER",
  89. undefined,
  90. ShaderDestination.FRAGMENT,
  91. );
  92. }
  93. const shapeType = primitive._provider.shape;
  94. if (shapeType === "BOX") {
  95. shaderBuilder.addDefine("SHAPE_BOX", undefined, ShaderDestination.FRAGMENT);
  96. } else if (shapeType === "CYLINDER") {
  97. shaderBuilder.addDefine(
  98. "SHAPE_CYLINDER",
  99. undefined,
  100. ShaderDestination.FRAGMENT,
  101. );
  102. } else if (shapeType === "ELLIPSOID") {
  103. shaderBuilder.addDefine(
  104. "SHAPE_ELLIPSOID",
  105. undefined,
  106. ShaderDestination.FRAGMENT,
  107. );
  108. }
  109. shaderBuilder.addFragmentLines([
  110. customShader.fragmentShaderText,
  111. "#line 0",
  112. Octree,
  113. VoxelUtils,
  114. Megatexture,
  115. IntersectionUtils,
  116. IntersectPlane,
  117. IntersectDepth,
  118. ]);
  119. if (clippingPlanesLength > 0) {
  120. shaderBuilder.addDefine(
  121. "CLIPPING_PLANES",
  122. undefined,
  123. ShaderDestination.FRAGMENT,
  124. );
  125. shaderBuilder.addDefine(
  126. "CLIPPING_PLANES_COUNT",
  127. clippingPlanesLength,
  128. ShaderDestination.FRAGMENT,
  129. );
  130. if (clippingPlanes.unionClippingRegions) {
  131. shaderBuilder.addDefine(
  132. "CLIPPING_PLANES_UNION",
  133. undefined,
  134. ShaderDestination.FRAGMENT,
  135. );
  136. }
  137. }
  138. if (primitive._depthTest) {
  139. shaderBuilder.addDefine(
  140. "DEPTH_TEST",
  141. undefined,
  142. ShaderDestination.FRAGMENT,
  143. );
  144. }
  145. if (shapeType === "BOX") {
  146. shaderBuilder.addFragmentLines([
  147. convertLocalToBoxUv,
  148. IntersectBox,
  149. Intersection,
  150. ]);
  151. } else if (shapeType === "CYLINDER") {
  152. shaderBuilder.addFragmentLines([
  153. convertLocalToCylinderUv,
  154. IntersectLongitude,
  155. IntersectCylinder,
  156. Intersection,
  157. ]);
  158. } else if (shapeType === "ELLIPSOID") {
  159. shaderBuilder.addFragmentLines([
  160. convertLocalToEllipsoidUv,
  161. IntersectLongitude,
  162. IntersectEllipsoid,
  163. Intersection,
  164. ]);
  165. }
  166. shaderBuilder.addFragmentLines([VoxelFS]);
  167. const shape = primitive._shape;
  168. const shapeDefines = shape.shaderDefines;
  169. for (const key in shapeDefines) {
  170. if (shapeDefines.hasOwnProperty(key)) {
  171. let value = shapeDefines[key];
  172. // if value is undefined, don't define it
  173. // if value is true, define it to nothing
  174. if (defined(value)) {
  175. value = value === true ? undefined : value;
  176. shaderBuilder.addDefine(key, value, ShaderDestination.FRAGMENT);
  177. }
  178. }
  179. }
  180. // Count how many intersections the shader will do.
  181. let intersectionCount = shape.shaderMaximumIntersectionsLength;
  182. if (clippingPlanesLength > 0) {
  183. shaderBuilder.addDefine(
  184. "CLIPPING_PLANES_INTERSECTION_INDEX",
  185. intersectionCount,
  186. ShaderDestination.FRAGMENT,
  187. );
  188. if (clippingPlanesLength === 1) {
  189. intersectionCount += 1;
  190. } else if (clippingPlanes.unionClippingRegions) {
  191. intersectionCount += 2;
  192. } else {
  193. intersectionCount += 1;
  194. }
  195. }
  196. if (primitive._depthTest) {
  197. shaderBuilder.addDefine(
  198. "DEPTH_INTERSECTION_INDEX",
  199. intersectionCount,
  200. ShaderDestination.FRAGMENT,
  201. );
  202. intersectionCount += 1;
  203. }
  204. shaderBuilder.addDefine(
  205. "INTERSECTION_COUNT",
  206. intersectionCount,
  207. ShaderDestination.FRAGMENT,
  208. );
  209. // Additional fragment shader defines
  210. if (
  211. !Cartesian3.equals(primitive.paddingBefore, Cartesian3.ZERO) ||
  212. !Cartesian3.equals(primitive.paddingAfter, Cartesian3.ZERO)
  213. ) {
  214. shaderBuilder.addDefine("PADDING", undefined, ShaderDestination.FRAGMENT);
  215. }
  216. // Allow reading from log depth texture, but don't write log depth anywhere.
  217. // Note: This needs to be set even if depthTest is off because it affects the
  218. // derived command system.
  219. if (primitive._useLogDepth) {
  220. shaderBuilder.addDefine(
  221. "LOG_DEPTH_READ_ONLY",
  222. undefined,
  223. ShaderDestination.FRAGMENT,
  224. );
  225. }
  226. const traversal = primitive._traversal;
  227. shaderBuilder.addDefine(
  228. "SAMPLE_COUNT",
  229. `${traversal._sampleCount}`,
  230. ShaderDestination.FRAGMENT,
  231. );
  232. }
  233. export default VoxelRenderResources;