UNPKG

@itwin/core-frontend

Version:
317 lines • 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.lateVertexDiscard = exports.vertexDiscard = exports.earlyVertexDiscard = exports.unquantizePosition = void 0; exports.addSamplePosition = addSamplePosition; exports.addModelViewProjectionMatrix = addModelViewProjectionMatrix; exports.addProjectionMatrix = addProjectionMatrix; exports.addInstancedRtcMatrix = addInstancedRtcMatrix; exports.addModelViewMatrix = addModelViewMatrix; exports.addNormalMatrix = addNormalMatrix; exports.addPosition = addPosition; exports.addAlpha = addAlpha; exports.addLineWeight = addLineWeight; exports.replaceLineWeight = replaceLineWeight; exports.addLineCode = addLineCode; exports.replaceLineCode = replaceLineCode; const core_bentley_1 = require("@itwin/core-bentley"); const Matrix_1 = require("../Matrix"); const RenderFlags_1 = require("../RenderFlags"); const Decode_1 = require("./Decode"); const Instancing_1 = require("./Instancing"); const LookupTable_1 = require("./LookupTable"); const initializeVertLUTCoords = ` g_vertexLUTIndex = decodeUInt24(qpos); g_vertexBaseCoords = compute_vert_coords(g_vertexLUTIndex); `; /** @internal */ exports.unquantizePosition = ` vec4 unquantizePosition(vec3 pos, vec3 origin, vec3 scale) { return vec4(origin + scale * pos, 1.0); } `; const computeQuantizedPosition = ` vec4 computeVertexPosition(vec3 pos) { return unquantizePosition(pos, u_qOrigin, u_qScale); } `; // Need to read 2 rgba values to obtain 6 16-bit integers for position const computeVertexPositionFromLUT = ` vec4 computeVertexPosition(vec3 encodedIndex) { vec3 qpos = vec3(decodeUInt16(g_vertLutData0.xy), decodeUInt16(g_vertLutData0.zw), decodeUInt16(g_vertLutData1.xy)); g_featureAndMaterialIndex = g_vertLutData2; return unquantizePosition(qpos, u_qOrigin, u_qScale); } `; const computeUnquantizedPosition = ` vec4 computeVertexPosition(vec3 encodedIndex) { uvec3 vux = uvec3(g_vertLutData0.xyz); g_featureAndMaterialIndex.x = g_vertLutData0.w; uvec3 vuy = uvec3(g_vertLutData1.xyz); g_featureAndMaterialIndex.y = g_vertLutData1.w; uvec3 vuz = uvec3(g_vertLutData2.xyz); g_featureAndMaterialIndex.z = g_vertLutData2.w; uvec3 vuw = uvec3(g_vertLutData3.xyz); g_featureAndMaterialIndex.w = g_vertLutData3.w; uvec3 u = (vuw << 24) | (vuz << 16) | (vuy << 8) | vux; return vec4(uintBitsToFloat(u), 1.0); } `; const computeLineWeight = "\nfloat computeLineWeight() { return g_lineWeight; }\n"; const computeLineCode = "\nfloat computeLineCode() { return g_lineCode; }\n"; function addSamplePosition(vert) { vert.addFunction(getSamplePosition(vert.positionType)); } const getSamplePositionPrelude = ` vec4 samplePosition(float index) { vec2 tc = compute_vert_coords(index);`; const getSamplePositionQuantizedPostlude = ` vec4 e0 = floor(TEXTURE(u_vertLUT, tc) * 255.0 + 0.5); tc.x += g_vert_stepX; vec4 e1 = floor(TEXTURE(u_vertLUT, tc) * 255.0 + 0.5); vec3 qpos = vec3(decodeUInt16(e0.xy), decodeUInt16(e0.zw), decodeUInt16(e1.xy)); return unquantizePosition(qpos, u_qOrigin, u_qScale); } `; const getSamplePositionUnquantizedPostlude = ` uvec3 vux = uvec3(floor(TEXTURE(u_vertLUT, tc).xyz * 255.0 + 0.5)); tc.x += g_vert_stepX; uvec3 vuy = uvec3(floor(TEXTURE(u_vertLUT, tc).xyz * 255.0 + 0.5)); tc.x += g_vert_stepX; uvec3 vuz = uvec3(floor(TEXTURE(u_vertLUT, tc).xyz * 255.0 + 0.5)); tc.x += g_vert_stepX; uvec3 vuw = uvec3(floor(TEXTURE(u_vertLUT, tc).xyz * 255.0 + 0.5)); uvec3 u = (vuw << 24) | (vuz << 16) | (vuy << 8) | vux; return vec4(uintBitsToFloat(u), 1.0); } `; function getSamplePosition(type) { return `${getSamplePositionPrelude}${"quantized" === type ? getSamplePositionQuantizedPostlude : getSamplePositionUnquantizedPostlude}`; } /** @internal */ function addModelViewProjectionMatrix(vert) { if (vert.usesInstancedGeometry) { addModelViewMatrix(vert); addProjectionMatrix(vert); vert.addGlobal("g_mvp", 7 /* VariableType.Mat4 */); vert.addInitializer("g_mvp = u_proj * g_mv;"); } else { vert.addUniform("u_mvp", 7 /* VariableType.Mat4 */, (prog) => { prog.addGraphicUniform("u_mvp", (uniform, params) => { params.target.uniforms.branch.bindModelViewProjectionMatrix(uniform, params.geometry, params.isViewCoords); }); }); } } /** @internal */ function addProjectionMatrix(vert) { vert.addUniform("u_proj", 7 /* VariableType.Mat4 */, (prog) => { prog.addProgramUniform("u_proj", (uniform, params) => { params.bindProjectionMatrix(uniform); }); }); } const computeInstancedRtcMatrix = ` g_instancedRtcMatrix = u_instanced_rtc * g_modelMatrixRTC; `; /** @internal */ function addInstancedRtcMatrix(vert) { if (!vert.usesInstancedGeometry) return; (0, core_bentley_1.assert)(undefined !== vert.find("g_modelMatrixRTC")); // set up in VertexShaderBuilder constructor... vert.addUniform("u_instanced_rtc", 7 /* VariableType.Mat4 */, (prog) => { prog.addGraphicUniform("u_instanced_rtc", (uniform, params) => { const modelt = params.geometry.asInstanced.getRtcOnlyTransform(); uniform.setMatrix4(Matrix_1.Matrix4.fromTransform(modelt)); }); }); vert.addGlobal("g_instancedRtcMatrix", 7 /* VariableType.Mat4 */); vert.addInitializer(computeInstancedRtcMatrix); } /** @internal */ function addModelViewMatrix(vert) { const bind = (uniform, params) => { params.target.uniforms.branch.bindModelViewMatrix(uniform, params.geometry, params.isViewCoords); }; if (vert.usesInstancedGeometry) { vert.addUniform("u_instanced_modelView", 7 /* VariableType.Mat4 */, (prog) => { prog.addGraphicUniform("u_instanced_modelView", bind); }); vert.addGlobal("g_mv", 7 /* VariableType.Mat4 */); vert.addInitializer("g_mv = u_instanced_modelView * g_modelMatrixRTC;"); } else { vert.addUniform("u_mv", 7 /* VariableType.Mat4 */, (prog) => { // ###TODO: We only need 3 rows, not 4... prog.addGraphicUniform("u_mv", bind); }); } } const computeNormalMatrix = ` g_nmx = transpose(inverse(mat3(MAT_MV))); g_nmx[0][0] *= u_frustumScale.x; g_nmx[1][1] *= u_frustumScale.y; `; /** @internal */ function addNormalMatrix(vert) { vert.addGlobal("g_nmx", 6 /* VariableType.Mat3 */); vert.addUniform("u_frustumScale", 3 /* VariableType.Vec2 */, (prog) => { prog.addGraphicUniform("u_frustumScale", (uniform, params) => { const scale = params.target.uniforms.branch.top.frustumScale; uniform.setUniform2fv([scale.x, scale.y]); }); }); vert.addInitializer(computeNormalMatrix); } function readVertexData(index) { return `g_vertLutData${index} = floor(TEXTURE(u_vertLUT, tc) * 255.0 + 0.5);`; } const nextVertexData = "tc.x += g_vert_stepX;"; function readNextVertexData(index) { return ` ${nextVertexData} ${readVertexData(index)}`; } const prereadVertexDataPrelude = ` vec2 tc = g_vertexBaseCoords; ${readVertexData(0)} ${readNextVertexData(1)} ${readNextVertexData(2)} `; const prereadQuantizedVertexData = `${prereadVertexDataPrelude} if (3.0 < u_vertParams.z) { ${readNextVertexData(3)} } `; const prereadUnquantizedVertexData = `${prereadVertexDataPrelude} ${readNextVertexData(3)} ${readNextVertexData(4)} if (5.0 < u_vertParams.z) { ${readNextVertexData(5)} } `; const scratchLutParams = new Float32Array(4); function addPositionFromLUT(vert) { vert.addGlobal("g_vertexLUTIndex", 2 /* VariableType.Float */); vert.addGlobal("g_vertexBaseCoords", 3 /* VariableType.Vec2 */); const unquantized = "unquantized" === vert.positionType; const maxRgbaPerVert = unquantized ? 6 : 4; for (let i = 0; i < maxRgbaPerVert; i++) vert.addGlobal(`g_vertLutData${i}`, 5 /* VariableType.Vec4 */); vert.addFunction(Decode_1.decodeUint24); vert.addFunction(Decode_1.decodeUint16); vert.addFunction(unquantized ? computeUnquantizedPosition : computeVertexPositionFromLUT); vert.addUniform("u_vertLUT", 8 /* VariableType.Sampler2D */, (prog) => { prog.addGraphicUniform("u_vertLUT", (uniform, params) => { (params.geometry.asLUT).lut.texture.bindSampler(uniform, RenderFlags_1.TextureUnit.VertexLUT); }); }); vert.addUniform("u_vertParams", 5 /* VariableType.Vec4 */, (prog) => { prog.addGraphicUniform("u_vertParams", (uniform, params) => { (0, core_bentley_1.assert)(undefined !== params.geometry.asLUT); const lut = params.geometry.asLUT.lut; const lutParams = scratchLutParams; lutParams[0] = lut.texture.width; lutParams[1] = lut.texture.height; lutParams[2] = lut.numRgbaPerVertex; lutParams[3] = lut.numVertices; uniform.setUniform4fv(lutParams); }); }); (0, LookupTable_1.addLookupTable)(vert, "vert", "u_vertParams.z"); vert.addInitializer(initializeVertLUTCoords); vert.addGlobal("g_featureAndMaterialIndex", 5 /* VariableType.Vec4 */); // Read the vertex data from the vertex table up front. Yields a consistent (if unexplainable) small performance boost. vert.addInitializer(unquantized ? prereadUnquantizedVertexData : prereadQuantizedVertexData); } /** @internal */ function addPosition(vert, fromLUT) { if (!fromLUT || "quantized" === vert.positionType) { vert.addFunction(exports.unquantizePosition); vert.addUniform("u_qScale", 4 /* VariableType.Vec3 */, (prog) => { prog.addGraphicUniform("u_qScale", (uniform, params) => { (0, core_bentley_1.assert)(params.geometry.usesQuantizedPositions); uniform.setUniform3fv(params.geometry.qScale); }); }); vert.addUniform("u_qOrigin", 4 /* VariableType.Vec3 */, (prog) => { prog.addGraphicUniform("u_qOrigin", (uniform, params) => { (0, core_bentley_1.assert)(params.geometry.usesQuantizedPositions); uniform.setUniform3fv(params.geometry.qOrigin); }); }); } if (!fromLUT) { vert.addFunction(computeQuantizedPosition); } else { addPositionFromLUT(vert); } } /** @internal */ function addAlpha(vert) { vert.addUniform("u_hasAlpha", 2 /* VariableType.Float */, (prog) => { prog.addGraphicUniform("u_hasAlpha", (uniform, params) => { uniform.setUniform1f(RenderFlags_1.Pass.rendersTranslucent(params.geometry.getPass(params.target)) ? 1 : 0); }); }); } /** @internal */ function addLineWeight(vert) { vert.addUniform("u_lineWeight", 2 /* VariableType.Float */, (prog) => { prog.addGraphicUniform("u_lineWeight", (attr, params) => { attr.setUniform1f(params.geometry.getLineWeight(params.programParams)); }); }); vert.addGlobal("g_lineWeight", 2 /* VariableType.Float */); if (vert.usesInstancedGeometry) { (0, Instancing_1.addInstanceOverrides)(vert); vert.addInitializer("g_lineWeight = mix(u_lineWeight, a_instanceOverrides.g, extractInstanceBit(kOvrBit_Weight));"); } else { vert.addInitializer("g_lineWeight = u_lineWeight;"); } vert.addFunction(computeLineWeight); } /** @internal */ function replaceLineWeight(vert, func) { vert.replaceFunction(computeLineWeight, func); } /** @internal */ function addLineCode(vert) { vert.addUniform("u_lineCode", 2 /* VariableType.Float */, (prog) => { prog.addGraphicUniform("u_lineCode", (attr, params) => { attr.setUniform1f(params.geometry.getLineCode(params.programParams)); }); }); vert.addGlobal("g_lineCode", 2 /* VariableType.Float */); if (vert.usesInstancedGeometry) { (0, Instancing_1.addInstanceOverrides)(vert); vert.addInitializer("g_lineCode = mix(u_lineCode, a_instanceOverrides.b, extractInstanceBit(kOvrBit_LineCode));"); } else { vert.addInitializer("g_lineCode = u_lineCode;"); } vert.addFunction(computeLineCode); } /** @internal */ function replaceLineCode(vert, func) { vert.replaceFunction(computeLineCode, func); } // This vertex belongs to a triangle which should not be rendered. Produce a degenerate triangle. // Also place it outside NDC range (for GL_POINTS) const discardVertex = ` { gl_Position = vec4(2.0, 2.0, 2.0, 1.0); return; } `; /** @internal */ exports.earlyVertexDiscard = ` if (checkForEarlyDiscard(rawPosition))${discardVertex}`; /** @internal */ exports.vertexDiscard = ` if (checkForDiscard())${discardVertex}`; /** @internal */ exports.lateVertexDiscard = ` if (checkForLateDiscard())${discardVertex}`; //# sourceMappingURL=Vertex.js.map