123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- 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 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 IntersectClippingPlanes from "../Shaders/Voxels/IntersectClippingPlanes.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 convertUvToBox from "../Shaders/Voxels/convertUvToBox.js";
- import convertUvToCylinder from "../Shaders/Voxels/convertUvToCylinder.js";
- import convertUvToEllipsoid from "../Shaders/Voxels/convertUvToEllipsoid.js";
- import Octree from "../Shaders/Voxels/Octree.js";
- import Megatexture from "../Shaders/Voxels/Megatexture.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(
- "sampler2D",
- "u_megatextureTextures[METADATA_COUNT]",
- ShaderDestination.FRAGMENT
- );
- /**
- * A dictionary mapping uniform name to functions that return the uniform
- * values.
- *
- * @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;
- // Build shader
- shaderBuilder.addVertexLines([VoxelVS]);
- shaderBuilder.addFragmentLines([
- customShader.fragmentShaderText,
- "#line 0",
- Octree,
- IntersectionUtils,
- Megatexture,
- ]);
- 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
- );
- }
- shaderBuilder.addFragmentLines([IntersectClippingPlanes]);
- }
- if (primitive._depthTest) {
- shaderBuilder.addDefine(
- "DEPTH_TEST",
- undefined,
- ShaderDestination.FRAGMENT
- );
- shaderBuilder.addFragmentLines([IntersectDepth]);
- }
- const shapeType = primitive._provider.shape;
- if (shapeType === "BOX") {
- shaderBuilder.addDefine("SHAPE_BOX", undefined, ShaderDestination.FRAGMENT);
- shaderBuilder.addFragmentLines([
- convertUvToBox,
- IntersectBox,
- Intersection,
- ]);
- } else if (shapeType === "CYLINDER") {
- shaderBuilder.addFragmentLines([
- IntersectCylinder,
- Intersection,
- convertUvToCylinder,
- ]);
- } else if (shapeType === "ELLIPSOID") {
- shaderBuilder.addFragmentLines([
- IntersectEllipsoid,
- Intersection,
- convertUvToEllipsoid,
- ]);
- }
- 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
- );
- }
- if (primitive._jitter) {
- shaderBuilder.addDefine("JITTER", undefined, ShaderDestination.FRAGMENT);
- }
- if (primitive._nearestSampling) {
- shaderBuilder.addDefine(
- "NEAREST_SAMPLING",
- undefined,
- ShaderDestination.FRAGMENT
- );
- }
- const traversal = primitive._traversal;
- shaderBuilder.addDefine(
- "SAMPLE_COUNT",
- `${traversal._sampleCount}`,
- ShaderDestination.FRAGMENT
- );
- }
- export default VoxelRenderResources;
|