| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- import BlendingState from "./BlendingState.js";
- import Cartesian2 from "../Core/Cartesian2.js";
- import ClippingPlaneCollection from "./ClippingPlaneCollection.js";
- import CullFace from "./CullFace.js";
- import defined from "../Core/defined.js";
- import DrawCommand from "../Renderer/DrawCommand.js";
- import Pass from "../Renderer/Pass.js";
- import PrimitiveType from "../Core/PrimitiveType.js";
- import processVoxelProperties from "./processVoxelProperties.js";
- import RenderState from "../Renderer/RenderState.js";
- import ShaderDestination from "../Renderer/ShaderDestination.js";
- import VoxelBoundsCollection from "./VoxelBoundsCollection.js";
- import VoxelRenderResources from "./VoxelRenderResources.js";
-
- const textureResolutionScratch = new Cartesian2();
-
- /**
- * @function
- *
- * @param {VoxelPrimitive} primitive
- * @param {Context} context
- *
- * @private
- */
- function buildVoxelDrawCommands(primitive, context) {
- const renderResources = new VoxelRenderResources(primitive);
-
- processVoxelProperties(renderResources, primitive);
-
- const {
- shaderBuilder,
- clippingPlanes,
- clippingPlanesLength,
- renderBoundPlanes,
- renderBoundPlanesLength,
- } = renderResources;
-
- if (clippingPlanesLength > 0) {
- const functionId = "getClippingPlane";
- const functionSignature = `vec4 ${functionId}(highp sampler2D packedPlanes, int planeNumber)`;
- const textureResolution = ClippingPlaneCollection.getTextureResolution(
- clippingPlanes,
- context,
- textureResolutionScratch,
- );
- const functionBody = getPlaneFunctionBody(textureResolution);
- shaderBuilder.addFunction(
- functionId,
- functionSignature,
- ShaderDestination.FRAGMENT,
- );
- shaderBuilder.addFunctionLines(functionId, [functionBody]);
- }
-
- if (renderBoundPlanesLength > 0) {
- const functionId = "getBoundPlane";
- const functionSignature = `vec4 ${functionId}(highp sampler2D packedPlanes, int planeNumber)`;
- const textureResolution = VoxelBoundsCollection.getTextureResolution(
- renderBoundPlanes,
- context,
- textureResolutionScratch,
- );
- const functionBody = getPlaneFunctionBody(textureResolution);
- shaderBuilder.addFunction(
- functionId,
- functionSignature,
- ShaderDestination.FRAGMENT,
- );
- shaderBuilder.addFunctionLines(functionId, [functionBody]);
- }
-
- // Compile shaders
- const shaderBuilderPick = shaderBuilder.clone();
- shaderBuilderPick.addDefine("PICKING", undefined, ShaderDestination.FRAGMENT);
- const shaderBuilderPickVoxel = shaderBuilder.clone();
- shaderBuilderPickVoxel.addDefine(
- "PICKING_VOXEL",
- undefined,
- ShaderDestination.FRAGMENT,
- );
- const shaderProgram = shaderBuilder.buildShaderProgram(context);
- const shaderProgramPick = shaderBuilderPick.buildShaderProgram(context);
- const shaderProgramPickVoxel =
- shaderBuilderPickVoxel.buildShaderProgram(context);
- const renderState = RenderState.fromCache({
- cull: {
- enabled: true,
- face: CullFace.BACK,
- },
- depthTest: {
- enabled: false,
- },
- depthMask: false,
- // internally the shader does premultiplied alpha, so it makes sense to blend that way too
- blending: BlendingState.PRE_MULTIPLIED_ALPHA_BLEND,
- });
-
- // Create the draw commands
- const viewportQuadVertexArray = context.getViewportQuadVertexArray();
- const depthTest = primitive._depthTest;
- const drawCommand = new DrawCommand({
- vertexArray: viewportQuadVertexArray,
- primitiveType: PrimitiveType.TRIANGLES,
- renderState: renderState,
- shaderProgram: shaderProgram,
- uniformMap: renderResources.uniformMap,
- modelMatrix: primitive._compoundModelMatrix,
- pass: Pass.VOXELS,
- executeInClosestFrustum: true,
- owner: this,
- cull: depthTest, // don't cull or occlude if depth testing is off
- occlude: depthTest, // don't cull or occlude if depth testing is off
- });
-
- // Create the pick draw command
- const drawCommandPick = DrawCommand.shallowClone(
- drawCommand,
- new DrawCommand(),
- );
- drawCommandPick.shaderProgram = shaderProgramPick;
- drawCommandPick.pickOnly = true;
-
- // Create the pick voxels draw command
- const drawCommandPickVoxel = DrawCommand.shallowClone(
- drawCommand,
- new DrawCommand(),
- );
- drawCommandPickVoxel.shaderProgram = shaderProgramPickVoxel;
- drawCommandPickVoxel.pickOnly = true;
-
- // Delete the old shader programs
- if (defined(primitive._drawCommand)) {
- const command = primitive._drawCommand;
- command.shaderProgram =
- command.shaderProgram && command.shaderProgram.destroy();
- }
- if (defined(primitive._drawCommandPick)) {
- const command = primitive._drawCommandPick;
- command.shaderProgram =
- command.shaderProgram && command.shaderProgram.destroy();
- }
- if (defined(primitive._drawCommandPickVoxel)) {
- const command = primitive._drawCommandPickVoxel;
- command.shaderProgram =
- command.shaderProgram && command.shaderProgram.destroy();
- }
-
- primitive._drawCommand = drawCommand;
- primitive._drawCommandPick = drawCommandPick;
- primitive._drawCommandPickVoxel = drawCommandPickVoxel;
- }
-
- function getPlaneFunctionBody(textureResolution) {
- const width = textureResolution.x;
- const height = textureResolution.y;
-
- const pixelWidth = 1.0 / width;
- const pixelHeight = 1.0 / height;
-
- let pixelWidthString = `${pixelWidth}`;
- if (pixelWidthString.indexOf(".") === -1) {
- pixelWidthString += ".0";
- }
- let pixelHeightString = `${pixelHeight}`;
- if (pixelHeightString.indexOf(".") === -1) {
- pixelHeightString += ".0";
- }
-
- return `int pixY = planeNumber / ${width};
- int pixX = planeNumber - (pixY * ${width});
- // Sample from center of pixel
- float u = (float(pixX) + 0.5) * ${pixelWidthString};
- float v = (float(pixY) + 0.5) * ${pixelHeightString};
- return texture(packedPlanes, vec2(u, v));`;
- }
-
- export default buildVoxelDrawCommands;
|