| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- import Cartesian3 from "../Core/Cartesian3.js";
- import combine from "../Core/combine.js";
- import defined from "../Core/defined.js";
- import ShaderBuilder from "../Renderer/ShaderBuilder.js";
- import ShaderDestination from "../Renderer/ShaderDestination.js";
- import VoxelUtils from "../Shaders/Voxels/VoxelUtils.js";
- import VoxelFS from "../Shaders/Voxels/VoxelFS.js";
- import VoxelVS from "../Shaders/Voxels/VoxelVS.js";
- import IntersectionUtils from "../Shaders/Voxels/IntersectionUtils.js";
- import IntersectDepth from "../Shaders/Voxels/IntersectDepth.js";
- import IntersectPlane from "../Shaders/Voxels/IntersectPlane.js";
- import IntersectLongitude from "../Shaders/Voxels/IntersectLongitude.js";
- import IntersectBox from "../Shaders/Voxels/IntersectBox.js";
- import IntersectCylinder from "../Shaders/Voxels/IntersectCylinder.js";
- import IntersectEllipsoid from "../Shaders/Voxels/IntersectEllipsoid.js";
- import Intersection from "../Shaders/Voxels/Intersection.js";
- import convertLocalToBoxUv from "../Shaders/Voxels/convertLocalToBoxUv.js";
- import convertLocalToCylinderUv from "../Shaders/Voxels/convertLocalToCylinderUv.js";
- import convertLocalToEllipsoidUv from "../Shaders/Voxels/convertLocalToEllipsoidUv.js";
- import Octree from "../Shaders/Voxels/Octree.js";
- import Megatexture from "../Shaders/Voxels/Megatexture.js";
- import VoxelMetadataOrder from "./VoxelMetadataOrder.js";
-
- /**
- * Set up render resources, including basic shader code, for rendering
- * a Voxel primitive.
- * The shader code generated by this function may be modified in later stages.
- * @constructor
- * @param {VoxelPrimitive} primitive
- *
- * @private
- */
- function VoxelRenderResources(primitive) {
- const shaderBuilder = new ShaderBuilder();
- /**
- * An object used to build a shader incrementally. Each pipeline stage
- * may add lines of shader code to this object.
- *
- * @type {ShaderBuilder}
- * @readonly
- *
- * @private
- */
- this.shaderBuilder = shaderBuilder;
-
- // Custom shader uniforms
- const customShader = primitive._customShader;
- const uniformMap = combine(primitive._uniformMap, customShader.uniformMap);
- primitive._uniformMap = uniformMap;
-
- const customShaderUniforms = customShader.uniforms;
- for (const uniformName in customShaderUniforms) {
- if (customShaderUniforms.hasOwnProperty(uniformName)) {
- const uniform = customShaderUniforms[uniformName];
- shaderBuilder.addUniform(
- uniform.type,
- uniformName,
- ShaderDestination.FRAGMENT,
- );
- }
- }
- // The reason this uniform is added by shader builder is because some of the
- // dynamically generated shader code reads from it.
- shaderBuilder.addUniform(
- "sampler3D",
- "u_megatextureTextures[METADATA_COUNT]",
- ShaderDestination.FRAGMENT,
- );
-
- /**
- * A dictionary mapping uniform name to functions that return the uniform
- * values.
- * @private
- * @type {Object<string, Function>}
- */
- this.uniformMap = uniformMap;
-
- const clippingPlanes = primitive._clippingPlanes;
- const clippingPlanesLength =
- defined(clippingPlanes) && clippingPlanes.enabled
- ? clippingPlanes.length
- : 0;
-
- this.clippingPlanes = clippingPlanes;
- this.clippingPlanesLength = clippingPlanesLength;
-
- const renderBoundPlanes = primitive._shape.renderBoundPlanes;
- const renderBoundPlanesLength = renderBoundPlanes?.length ?? 0;
-
- this.renderBoundPlanes = renderBoundPlanes;
- this.renderBoundPlanesLength = renderBoundPlanesLength;
-
- // Build shader
- shaderBuilder.addVertexLines([VoxelVS]);
-
- if (primitive.provider.metadataOrder === VoxelMetadataOrder.Y_UP) {
- shaderBuilder.addDefine(
- "Y_UP_METADATA_ORDER",
- undefined,
- ShaderDestination.FRAGMENT,
- );
- }
- const shapeType = primitive._provider.shape;
- if (shapeType === "BOX") {
- shaderBuilder.addDefine("SHAPE_BOX", undefined, ShaderDestination.FRAGMENT);
- } else if (shapeType === "CYLINDER") {
- shaderBuilder.addDefine(
- "SHAPE_CYLINDER",
- undefined,
- ShaderDestination.FRAGMENT,
- );
- } else if (shapeType === "ELLIPSOID") {
- shaderBuilder.addDefine(
- "SHAPE_ELLIPSOID",
- undefined,
- ShaderDestination.FRAGMENT,
- );
- }
-
- shaderBuilder.addFragmentLines([
- customShader.fragmentShaderText,
- "#line 0",
- Octree,
- VoxelUtils,
- Megatexture,
- IntersectionUtils,
- IntersectPlane,
- IntersectDepth,
- ]);
-
- if (clippingPlanesLength > 0) {
- shaderBuilder.addDefine(
- "CLIPPING_PLANES",
- undefined,
- ShaderDestination.FRAGMENT,
- );
- shaderBuilder.addDefine(
- "CLIPPING_PLANES_COUNT",
- clippingPlanesLength,
- ShaderDestination.FRAGMENT,
- );
- if (clippingPlanes.unionClippingRegions) {
- shaderBuilder.addDefine(
- "CLIPPING_PLANES_UNION",
- undefined,
- ShaderDestination.FRAGMENT,
- );
- }
- }
-
- if (primitive._depthTest) {
- shaderBuilder.addDefine(
- "DEPTH_TEST",
- undefined,
- ShaderDestination.FRAGMENT,
- );
- }
-
- if (shapeType === "BOX") {
- shaderBuilder.addFragmentLines([
- convertLocalToBoxUv,
- IntersectBox,
- Intersection,
- ]);
- } else if (shapeType === "CYLINDER") {
- shaderBuilder.addFragmentLines([
- convertLocalToCylinderUv,
- IntersectLongitude,
- IntersectCylinder,
- Intersection,
- ]);
- } else if (shapeType === "ELLIPSOID") {
- shaderBuilder.addFragmentLines([
- convertLocalToEllipsoidUv,
- IntersectLongitude,
- IntersectEllipsoid,
- Intersection,
- ]);
- }
-
- shaderBuilder.addFragmentLines([VoxelFS]);
-
- const shape = primitive._shape;
- const shapeDefines = shape.shaderDefines;
- for (const key in shapeDefines) {
- if (shapeDefines.hasOwnProperty(key)) {
- let value = shapeDefines[key];
- // if value is undefined, don't define it
- // if value is true, define it to nothing
- if (defined(value)) {
- value = value === true ? undefined : value;
- shaderBuilder.addDefine(key, value, ShaderDestination.FRAGMENT);
- }
- }
- }
-
- // Count how many intersections the shader will do.
- let intersectionCount = shape.shaderMaximumIntersectionsLength;
- if (clippingPlanesLength > 0) {
- shaderBuilder.addDefine(
- "CLIPPING_PLANES_INTERSECTION_INDEX",
- intersectionCount,
- ShaderDestination.FRAGMENT,
- );
- if (clippingPlanesLength === 1) {
- intersectionCount += 1;
- } else if (clippingPlanes.unionClippingRegions) {
- intersectionCount += 2;
- } else {
- intersectionCount += 1;
- }
- }
- if (primitive._depthTest) {
- shaderBuilder.addDefine(
- "DEPTH_INTERSECTION_INDEX",
- intersectionCount,
- ShaderDestination.FRAGMENT,
- );
- intersectionCount += 1;
- }
- shaderBuilder.addDefine(
- "INTERSECTION_COUNT",
- intersectionCount,
- ShaderDestination.FRAGMENT,
- );
-
- // Additional fragment shader defines
- if (
- !Cartesian3.equals(primitive.paddingBefore, Cartesian3.ZERO) ||
- !Cartesian3.equals(primitive.paddingAfter, Cartesian3.ZERO)
- ) {
- shaderBuilder.addDefine("PADDING", undefined, ShaderDestination.FRAGMENT);
- }
- // Allow reading from log depth texture, but don't write log depth anywhere.
- // Note: This needs to be set even if depthTest is off because it affects the
- // derived command system.
- if (primitive._useLogDepth) {
- shaderBuilder.addDefine(
- "LOG_DEPTH_READ_ONLY",
- undefined,
- ShaderDestination.FRAGMENT,
- );
- }
- const traversal = primitive._traversal;
- shaderBuilder.addDefine(
- "SAMPLE_COUNT",
- `${traversal._sampleCount}`,
- ShaderDestination.FRAGMENT,
- );
- }
-
- export default VoxelRenderResources;
|