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

buildVoxelDrawCommands.js 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. import BlendingState from "./BlendingState.js";
  2. import Cartesian2 from "../Core/Cartesian2.js";
  3. import ClippingPlaneCollection from "./ClippingPlaneCollection.js";
  4. import CullFace from "./CullFace.js";
  5. import defined from "../Core/defined.js";
  6. import DrawCommand from "../Renderer/DrawCommand.js";
  7. import Pass from "../Renderer/Pass.js";
  8. import PrimitiveType from "../Core/PrimitiveType.js";
  9. import processVoxelProperties from "./processVoxelProperties.js";
  10. import RenderState from "../Renderer/RenderState.js";
  11. import ShaderDestination from "../Renderer/ShaderDestination.js";
  12. import VoxelBoundsCollection from "./VoxelBoundsCollection.js";
  13. import VoxelRenderResources from "./VoxelRenderResources.js";
  14. const textureResolutionScratch = new Cartesian2();
  15. /**
  16. * @function
  17. *
  18. * @param {VoxelPrimitive} primitive
  19. * @param {Context} context
  20. *
  21. * @private
  22. */
  23. function buildVoxelDrawCommands(primitive, context) {
  24. const renderResources = new VoxelRenderResources(primitive);
  25. processVoxelProperties(renderResources, primitive);
  26. const {
  27. shaderBuilder,
  28. clippingPlanes,
  29. clippingPlanesLength,
  30. renderBoundPlanes,
  31. renderBoundPlanesLength,
  32. } = renderResources;
  33. if (clippingPlanesLength > 0) {
  34. const functionId = "getClippingPlane";
  35. const functionSignature = `vec4 ${functionId}(highp sampler2D packedPlanes, int planeNumber)`;
  36. const textureResolution = ClippingPlaneCollection.getTextureResolution(
  37. clippingPlanes,
  38. context,
  39. textureResolutionScratch,
  40. );
  41. const functionBody = getPlaneFunctionBody(textureResolution);
  42. shaderBuilder.addFunction(
  43. functionId,
  44. functionSignature,
  45. ShaderDestination.FRAGMENT,
  46. );
  47. shaderBuilder.addFunctionLines(functionId, [functionBody]);
  48. }
  49. if (renderBoundPlanesLength > 0) {
  50. const functionId = "getBoundPlane";
  51. const functionSignature = `vec4 ${functionId}(highp sampler2D packedPlanes, int planeNumber)`;
  52. const textureResolution = VoxelBoundsCollection.getTextureResolution(
  53. renderBoundPlanes,
  54. context,
  55. textureResolutionScratch,
  56. );
  57. const functionBody = getPlaneFunctionBody(textureResolution);
  58. shaderBuilder.addFunction(
  59. functionId,
  60. functionSignature,
  61. ShaderDestination.FRAGMENT,
  62. );
  63. shaderBuilder.addFunctionLines(functionId, [functionBody]);
  64. }
  65. // Compile shaders
  66. const shaderBuilderPick = shaderBuilder.clone();
  67. shaderBuilderPick.addDefine("PICKING", undefined, ShaderDestination.FRAGMENT);
  68. const shaderBuilderPickVoxel = shaderBuilder.clone();
  69. shaderBuilderPickVoxel.addDefine(
  70. "PICKING_VOXEL",
  71. undefined,
  72. ShaderDestination.FRAGMENT,
  73. );
  74. const shaderProgram = shaderBuilder.buildShaderProgram(context);
  75. const shaderProgramPick = shaderBuilderPick.buildShaderProgram(context);
  76. const shaderProgramPickVoxel =
  77. shaderBuilderPickVoxel.buildShaderProgram(context);
  78. const renderState = RenderState.fromCache({
  79. cull: {
  80. enabled: true,
  81. face: CullFace.BACK,
  82. },
  83. depthTest: {
  84. enabled: false,
  85. },
  86. depthMask: false,
  87. // internally the shader does premultiplied alpha, so it makes sense to blend that way too
  88. blending: BlendingState.PRE_MULTIPLIED_ALPHA_BLEND,
  89. });
  90. // Create the draw commands
  91. const viewportQuadVertexArray = context.getViewportQuadVertexArray();
  92. const depthTest = primitive._depthTest;
  93. const drawCommand = new DrawCommand({
  94. vertexArray: viewportQuadVertexArray,
  95. primitiveType: PrimitiveType.TRIANGLES,
  96. renderState: renderState,
  97. shaderProgram: shaderProgram,
  98. uniformMap: renderResources.uniformMap,
  99. modelMatrix: primitive._compoundModelMatrix,
  100. pass: Pass.VOXELS,
  101. executeInClosestFrustum: true,
  102. owner: this,
  103. cull: depthTest, // don't cull or occlude if depth testing is off
  104. occlude: depthTest, // don't cull or occlude if depth testing is off
  105. });
  106. // Create the pick draw command
  107. const drawCommandPick = DrawCommand.shallowClone(
  108. drawCommand,
  109. new DrawCommand(),
  110. );
  111. drawCommandPick.shaderProgram = shaderProgramPick;
  112. drawCommandPick.pickOnly = true;
  113. // Create the pick voxels draw command
  114. const drawCommandPickVoxel = DrawCommand.shallowClone(
  115. drawCommand,
  116. new DrawCommand(),
  117. );
  118. drawCommandPickVoxel.shaderProgram = shaderProgramPickVoxel;
  119. drawCommandPickVoxel.pickOnly = true;
  120. // Delete the old shader programs
  121. if (defined(primitive._drawCommand)) {
  122. const command = primitive._drawCommand;
  123. command.shaderProgram =
  124. command.shaderProgram && command.shaderProgram.destroy();
  125. }
  126. if (defined(primitive._drawCommandPick)) {
  127. const command = primitive._drawCommandPick;
  128. command.shaderProgram =
  129. command.shaderProgram && command.shaderProgram.destroy();
  130. }
  131. if (defined(primitive._drawCommandPickVoxel)) {
  132. const command = primitive._drawCommandPickVoxel;
  133. command.shaderProgram =
  134. command.shaderProgram && command.shaderProgram.destroy();
  135. }
  136. primitive._drawCommand = drawCommand;
  137. primitive._drawCommandPick = drawCommandPick;
  138. primitive._drawCommandPickVoxel = drawCommandPickVoxel;
  139. }
  140. function getPlaneFunctionBody(textureResolution) {
  141. const width = textureResolution.x;
  142. const height = textureResolution.y;
  143. const pixelWidth = 1.0 / width;
  144. const pixelHeight = 1.0 / height;
  145. let pixelWidthString = `${pixelWidth}`;
  146. if (pixelWidthString.indexOf(".") === -1) {
  147. pixelWidthString += ".0";
  148. }
  149. let pixelHeightString = `${pixelHeight}`;
  150. if (pixelHeightString.indexOf(".") === -1) {
  151. pixelHeightString += ".0";
  152. }
  153. return `int pixY = planeNumber / ${width};
  154. int pixX = planeNumber - (pixY * ${width});
  155. // Sample from center of pixel
  156. float u = (float(pixX) + 0.5) * ${pixelWidthString};
  157. float v = (float(pixY) + 0.5) * ${pixelHeightString};
  158. return texture(packedPlanes, vec2(u, v));`;
  159. }
  160. export default buildVoxelDrawCommands;