buildVoxelDrawCommands.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import defined from "../Core/defined.js";
  2. import PrimitiveType from "../Core/PrimitiveType.js";
  3. import BlendingState from "./BlendingState.js";
  4. import CullFace from "./CullFace.js";
  5. import getClippingFunction from "./getClippingFunction.js";
  6. import DrawCommand from "../Renderer/DrawCommand.js";
  7. import Pass from "../Renderer/Pass.js";
  8. import RenderState from "../Renderer/RenderState.js";
  9. import ShaderDestination from "../Renderer/ShaderDestination.js";
  10. import VoxelRenderResources from "./VoxelRenderResources.js";
  11. import processVoxelProperties from "./processVoxelProperties.js";
  12. /**
  13. * @function
  14. *
  15. * @param {VoxelPrimitive} primitive
  16. * @param {Context} context
  17. *
  18. * @private
  19. */
  20. function buildVoxelDrawCommands(primitive, context) {
  21. const renderResources = new VoxelRenderResources(primitive);
  22. processVoxelProperties(renderResources, primitive);
  23. const {
  24. shaderBuilder,
  25. clippingPlanes,
  26. clippingPlanesLength,
  27. } = renderResources;
  28. if (clippingPlanesLength > 0) {
  29. // Extract the getClippingPlane function from the getClippingFunction string.
  30. // This is a bit of a hack.
  31. const functionId = "getClippingPlane";
  32. const entireFunction = getClippingFunction(clippingPlanes, context);
  33. const functionSignatureBegin = 0;
  34. const functionSignatureEnd = entireFunction.indexOf(")") + 1;
  35. const functionBodyBegin =
  36. entireFunction.indexOf("{", functionSignatureEnd) + 1;
  37. const functionBodyEnd = entireFunction.indexOf("}", functionBodyBegin);
  38. const functionSignature = entireFunction.slice(
  39. functionSignatureBegin,
  40. functionSignatureEnd
  41. );
  42. const functionBody = entireFunction.slice(
  43. functionBodyBegin,
  44. functionBodyEnd
  45. );
  46. shaderBuilder.addFunction(
  47. functionId,
  48. functionSignature,
  49. ShaderDestination.FRAGMENT
  50. );
  51. shaderBuilder.addFunctionLines(functionId, [functionBody]);
  52. }
  53. // Compile shaders
  54. const shaderBuilderPick = shaderBuilder.clone();
  55. shaderBuilderPick.addDefine("PICKING", undefined, ShaderDestination.FRAGMENT);
  56. const shaderProgram = shaderBuilder.buildShaderProgram(context);
  57. const shaderProgramPick = shaderBuilderPick.buildShaderProgram(context);
  58. const renderState = RenderState.fromCache({
  59. cull: {
  60. enabled: true,
  61. face: CullFace.BACK,
  62. },
  63. depthTest: {
  64. enabled: false,
  65. },
  66. depthMask: false,
  67. // internally the shader does premultiplied alpha, so it makes sense to blend that way too
  68. blending: BlendingState.PRE_MULTIPLIED_ALPHA_BLEND,
  69. });
  70. // Create the draw commands
  71. const viewportQuadVertexArray = context.getViewportQuadVertexArray();
  72. const depthTest = primitive._depthTest;
  73. const drawCommand = new DrawCommand({
  74. vertexArray: viewportQuadVertexArray,
  75. primitiveType: PrimitiveType.TRIANGLES,
  76. renderState: renderState,
  77. shaderProgram: shaderProgram,
  78. uniformMap: renderResources.uniformMap,
  79. modelMatrix: primitive._compoundModelMatrix,
  80. pass: Pass.VOXELS,
  81. executeInClosestFrustum: true,
  82. owner: this,
  83. cull: depthTest, // don't cull or occlude if depth testing is off
  84. occlude: depthTest, // don't cull or occlude if depth testing is off
  85. });
  86. // Create the pick draw command
  87. const drawCommandPick = DrawCommand.shallowClone(
  88. drawCommand,
  89. new DrawCommand()
  90. );
  91. drawCommandPick.shaderProgram = shaderProgramPick;
  92. drawCommandPick.pickOnly = true;
  93. // Delete the old shader programs
  94. if (defined(primitive._drawCommand)) {
  95. const command = primitive._drawCommand;
  96. command.shaderProgram =
  97. command.shaderProgram && command.shaderProgram.destroy();
  98. }
  99. if (defined(primitive._drawCommandPick)) {
  100. const command = primitive._drawCommandPick;
  101. command.shaderProgram =
  102. command.shaderProgram && command.shaderProgram.destroy();
  103. }
  104. primitive._drawCommand = drawCommand;
  105. primitive._drawCommandPick = drawCommandPick;
  106. }
  107. export default buildVoxelDrawCommands;