UNPKG

@itwin/core-frontend

Version:
250 lines (247 loc) • 13.3 kB
"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ /** @packageDocumentation * @module WebGL */ Object.defineProperty(exports, "__esModule", { value: true }); exports.finalizeNormal = void 0; exports.addColorOverrideMix = addColorOverrideMix; exports.createClassifierRealityMeshHiliter = createClassifierRealityMeshHiliter; exports.createRealityMeshHiliter = createRealityMeshHiliter; exports.createRealityMeshBuilder = createRealityMeshBuilder; const core_bentley_1 = require("@itwin/core-bentley"); const core_common_1 = require("@itwin/core-common"); const core_geometry_1 = require("@itwin/core-geometry"); const AttributeMap_1 = require("../AttributeMap"); const Matrix_1 = require("../Matrix"); const RenderFlags_1 = require("../RenderFlags"); const ShaderBuilder_1 = require("../ShaderBuilder"); const System_1 = require("../System"); const Atmosphere_1 = require("./Atmosphere"); const Color_1 = require("./Color"); const Common_1 = require("./Common"); const Decode_1 = require("./Decode"); const FeatureSymbology_1 = require("./FeatureSymbology"); const Fragment_1 = require("./Fragment"); const PlanarClassification_1 = require("./PlanarClassification"); const SolarShadowMapping_1 = require("./SolarShadowMapping"); const Surface_1 = require("./Surface"); const Thematic_1 = require("./Thematic"); const Vertex_1 = require("./Vertex"); const Wiremesh_1 = require("./Wiremesh"); const MaplayerDraping_1 = require("./MaplayerDraping"); const computePosition = "gl_PointSize = 1.0; return MAT_MVP * rawPos;"; const computeNormal = ` vec3 normal = octDecodeNormal(a_norm); // normal coming in for is already in world space g_hillshadeIndex = normal.z; // save off world Z for thematic hill shade mode index return normalize(u_worldToViewN * normal); `; exports.finalizeNormal = ` return normalize(v_n) * (2.0 * float(gl_FrontFacing) - 1.0); `; const computeTexCoord = "return unquantize2d(a_uvParam, u_qTexCoordParams);"; const scratchMatrix4d1 = core_geometry_1.Matrix4d.createIdentity(); const scratchMatrix4d2 = core_geometry_1.Matrix4d.createIdentity(); const scratchMatrix = new Matrix_1.Matrix4(); function addTextures(builder, maxTexturesPerMesh) { builder.vert.addFunction(Decode_1.unquantize2d); builder.addFunctionComputedVarying("v_texCoord", 3 /* VariableType.Vec2 */, "computeTexCoord", computeTexCoord); builder.vert.addUniform("u_qTexCoordParams", 5 /* VariableType.Vec4 */, (prog) => { prog.addGraphicUniform("u_qTexCoordParams", (uniform, params) => { const realityMesh = params.geometry.asRealityMesh; if (undefined !== realityMesh.uvQParams) { uniform.setUniform4fv(realityMesh.uvQParams); } }); }); builder.frag.addUniform("u_texturesPresent", 0 /* VariableType.Boolean */, (program) => { program.addGraphicUniform("u_texturesPresent", (uniform, params) => { uniform.setUniform1i(params.geometry.asRealityMesh.hasTextures ? 1 : 0); }); }); for (let i = 0; i < maxTexturesPerMesh; i++) { const textureLabel = `s_texture${i}`; builder.frag.addUniform(textureLabel, 8 /* VariableType.Sampler2D */, (prog) => { prog.addGraphicUniform(textureLabel, (uniform, params) => { const textureUnits = [RenderFlags_1.TextureUnit.RealityMesh0, RenderFlags_1.TextureUnit.RealityMesh1, params.target.drawForReadPixels ? RenderFlags_1.TextureUnit.ShadowMap : RenderFlags_1.TextureUnit.PickDepthAndOrder, RenderFlags_1.TextureUnit.RealityMesh3, RenderFlags_1.TextureUnit.RealityMesh4, RenderFlags_1.TextureUnit.RealityMesh5]; const realityMesh = params.geometry.asRealityMesh; const realityTexture = realityMesh.textureParams ? realityMesh.textureParams.params[i].texture : undefined; if (realityTexture !== undefined) { const texture = realityTexture; texture.texture.bindSampler(uniform, textureUnits[i]); } else { System_1.System.instance.ensureSamplerBound(uniform, textureUnits[i]); } }); }); const paramsLabel = `u_texParams${i}`, matrixLabel = `u_texMatrix${i}`; builder.frag.addUniform(matrixLabel, 7 /* VariableType.Mat4 */, (prog) => { prog.addGraphicUniform(matrixLabel, (uniform, params) => { const realityMesh = params.geometry.asRealityMesh; const textureParam = realityMesh.textureParams?.params[i]; (0, core_bentley_1.assert)(undefined !== textureParam); if (undefined !== textureParam) { const projectionMatrix = textureParam.getProjectionMatrix(); if (projectionMatrix) { const eyeToModel = core_geometry_1.Matrix4d.createTransform(params.target.uniforms.frustum.viewMatrix.inverse(), scratchMatrix4d1); const eyeToTexture = projectionMatrix.multiplyMatrixMatrix(eyeToModel, scratchMatrix4d2); uniform.setMatrix4(Matrix_1.Matrix4.fromMatrix4d(eyeToTexture, scratchMatrix)); } else uniform.setMatrix4(textureParam.getTerrainMatrix()); } }); }); builder.frag.addUniform(paramsLabel, 7 /* VariableType.Mat4 */, (prog) => { prog.addGraphicUniform(paramsLabel, (uniform, params) => { const realityMesh = params.geometry.asRealityMesh; const textureParam = realityMesh.textureParams?.params[i]; (0, core_bentley_1.assert)(undefined !== textureParam); if (undefined !== textureParam) { uniform.setMatrix4(textureParam.getParams(scratchMatrix)); } }); }); } } function baseColorFromTextures(textureCount, applyFeatureColor) { const applyTextureStrings = []; for (let i = 0; i < textureCount; i++) applyTextureStrings.push(`if (applyTexture(col, s_texture${i}, u_texParams${i}, u_texMatrix${i})) doDiscard = false; `); return ` if (!u_texturesPresent) { vec4 col = u_baseColor; ${applyFeatureColor} return col; } bool doDiscard = true; vec4 col = u_baseColor; ${applyTextureStrings.join("\n ")} if (doDiscard) discard; ${applyFeatureColor} return col; `; } // feature_rgb.r = -1.0 if rgb color not overridden for feature. // feature_alpha = -1.0 if alpha not overridden for feature. const mixFeatureColor = ` col.rgb = mix(col.rgb, mix(col.rgb, v_color.rgb, u_overrideColorMix), step(0.0, v_color.r)); col.a = mix(col.a, v_color.a, step(0.0, v_color.a)); `; function addThematicToRealityMesh(builder, gradientTextureUnit) { (0, Vertex_1.addNormalMatrix)(builder.vert); builder.vert.addFunction(Surface_1.octDecodeNormal); builder.vert.addGlobal("g_hillshadeIndex", 2 /* VariableType.Float */); builder.addFunctionComputedVarying("v_n", 4 /* VariableType.Vec3 */, "computeLightingNormal", computeNormal); builder.frag.addGlobal("g_normal", 4 /* VariableType.Vec3 */); builder.frag.set(25 /* FragmentShaderComponent.FinalizeNormal */, exports.finalizeNormal); (0, Thematic_1.addThematicDisplay)(builder, false, true); builder.addInlineComputedVarying("v_thematicIndex", 2 /* VariableType.Float */, (0, Thematic_1.getComputeThematicIndex)(builder.vert.usesInstancedGeometry, false, false)); builder.vert.addUniform("u_worldToViewN", 6 /* VariableType.Mat3 */, (prog) => { prog.addGraphicUniform("u_worldToViewN", (uniform, params) => { params.target.uniforms.branch.bindWorldToViewNTransform(uniform, params.geometry, false); }); }); builder.frag.addUniform("s_texture", 8 /* VariableType.Sampler2D */, (prog) => { prog.addGraphicUniform("s_texture", (uniform, params) => { params.target.uniforms.thematic.bindTexture(uniform, gradientTextureUnit >= 0 ? gradientTextureUnit : (params.target.drawForReadPixels ? RenderFlags_1.TextureUnit.ShadowMap : RenderFlags_1.TextureUnit.PickDepthAndOrder)); }); }); } /** @internal */ function addColorOverrideMix(frag) { frag.addUniform("u_overrideColorMix", 2 /* VariableType.Float */, (prog) => { prog.addGraphicUniform("u_overrideColorMix", (uniform, params) => { params.target.uniforms.realityModel.bindOverrideColorMix(uniform); }); }); } function createRealityMeshHiliterBuilder() { const builder = new ShaderBuilder_1.ProgramBuilder(AttributeMap_1.AttributeMap.findAttributeMap(7 /* TechniqueId.RealityMesh */, false)); const vert = builder.vert; vert.set(10 /* VertexShaderComponent.ComputePosition */, computePosition); (0, Vertex_1.addModelViewProjectionMatrix)(vert); builder.frag.set(18 /* FragmentShaderComponent.AssignFragData */, Fragment_1.assignFragColor); return builder; } /** @internal */ function createClassifierRealityMeshHiliter() { const builder = createRealityMeshHiliterBuilder(); (0, PlanarClassification_1.addHilitePlanarClassifier)(builder, false); return builder; } /** @internal */ function createRealityMeshHiliter() { const builder = createRealityMeshHiliterBuilder(); (0, FeatureSymbology_1.addHiliter)(builder, false); return builder; } /** @internal */ function createRealityMeshBuilder(flags) { const builder = new ShaderBuilder_1.ProgramBuilder(AttributeMap_1.AttributeMap.findAttributeMap(7 /* TechniqueId.RealityMesh */, false)); const vert = builder.vert; vert.set(10 /* VertexShaderComponent.ComputePosition */, computePosition); (0, Vertex_1.addModelViewProjectionMatrix)(vert); if (flags.isShadowable === 1 /* IsShadowable.Yes */) (0, SolarShadowMapping_1.addSolarShadowMap)(builder, true); const frag = builder.frag; frag.addGlobal("featureIncrement", 2 /* VariableType.Float */, "0.0"); frag.addGlobal("classifierId", 5 /* VariableType.Vec4 */); frag.set(19 /* FragmentShaderComponent.OverrideFeatureId */, MaplayerDraping_1.overrideFeatureId); const textureCount = System_1.System.instance.maxRealityImageryLayers; const gradientTextureUnit = RenderFlags_1.TextureUnit.RealityMeshThematicGradient; const feat = flags.featureMode; let opts = 2 /* FeatureMode.Overrides */ === feat ? 28 /* FeatureSymbologyOptions.Surface */ : 0 /* FeatureSymbologyOptions.None */; let applyFragmentFeatureColor = ""; if (flags.isClassified) { opts &= ~16 /* FeatureSymbologyOptions.Alpha */; (0, PlanarClassification_1.addColorPlanarClassifier)(builder, flags.isTranslucent, flags.isThematic); (0, Surface_1.addClassificationTranslucencyDiscard)(builder); } (0, FeatureSymbology_1.addFeatureSymbology)(builder, feat, opts); if (feat === 2 /* FeatureMode.Overrides */) { (0, Common_1.addShaderFlags)(builder); (0, Color_1.addVaryingColor)(builder, "return vec4(-1.0, -1.0, -1.0, -1.0);"); applyFragmentFeatureColor = mixFeatureColor; addColorOverrideMix(builder.frag); } const computeFragmentBaseColor = baseColorFromTextures(textureCount, applyFragmentFeatureColor); frag.addFunction(Common_1.addUInt32s); frag.addFunction(MaplayerDraping_1.testInside); (0, Common_1.addEyeSpace)(builder); frag.addFunction((0, MaplayerDraping_1.applyTexture)(true)); frag.set(1 /* FragmentShaderComponent.ComputeBaseColor */, computeFragmentBaseColor); builder.frag.addUniform("u_baseColor", 5 /* VariableType.Vec4 */, (prog) => { prog.addGraphicUniform("u_baseColor", (uniform, params) => { const realityMesh = params.geometry.asRealityMesh; const baseColor = (realityMesh.baseColor ? realityMesh.baseColor : core_common_1.ColorDef.create(0xff000000)).colors; uniform.setUniform4fv([baseColor.r / 255, baseColor.g / 255, baseColor.b / 255, 1 - baseColor.t / 255]); }); }); builder.frag.set(1 /* FragmentShaderComponent.ComputeBaseColor */, computeFragmentBaseColor); if (!flags.isTranslucent) { if (0 /* FeatureMode.None */ !== feat) { if (flags.isClassified) (0, PlanarClassification_1.addFeaturePlanarClassifier)(builder); builder.frag.addFunction(Decode_1.decodeDepthRgb); if (flags.isClassified) (0, Fragment_1.addPickBufferOutputs)(builder.frag); else (0, Fragment_1.addAltPickBufferOutputs)(builder.frag); } } addTextures(builder, textureCount); if (1 /* IsThematic.Yes */ === flags.isThematic) addThematicToRealityMesh(builder, gradientTextureUnit); if (flags.isWiremesh) (0, Wiremesh_1.addWiremesh)(builder); if (flags.enableAtmosphere) (0, Atmosphere_1.addAtmosphericScatteringEffect)(builder, false, false); return builder; } //# sourceMappingURL=RealityMesh.js.map