@itwin/core-frontend
Version:
iTwin.js frontend components
141 lines • 7.28 kB
JavaScript
;
/*---------------------------------------------------------------------------------------------
* 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.addUInt32s = void 0;
exports.addChooseVec2WithBitFlagsFunction = addChooseVec2WithBitFlagsFunction;
exports.addChooseVec3WithBitFlagFunction = addChooseVec3WithBitFlagFunction;
exports.addShaderFlags = addShaderFlags;
exports.addFrustum = addFrustum;
exports.addEyeSpace = addEyeSpace;
exports.addExtractNthBit = addExtractNthBit;
const webgl_compatibility_1 = require("@itwin/webgl-compatibility");
const System_1 = require("../System");
const Vertex_1 = require("./Vertex");
// These are not used anywhere currently, but will leave them here commented out in case we want them later.
// const chooseFloatWithBitFlag2 = `
// float chooseFloatWithBitFlag(float f1, float f2, uint flags, uint n) { return 0u != (flags & n) ? f2 : f1; }
// `;
const chooseVec2With2BitFlags = `
vec2 chooseVec2With2BitFlags(vec2 v1, vec2 v2, uint flags, uint n1, uint n2) { return 0u != (flags & (n1 | n2)) ? v2 : v1; }
`;
const chooseVec3WithBitFlag = `
vec3 chooseVec3WithBitFlag(vec3 v1, vec3 v2, uint flags, uint n) { return 0u != (flags & n) ? v2 : v1; }
`;
/** @internal */
function addChooseVec2WithBitFlagsFunction(shader) {
shader.addFunction(extractNthBit);
shader.addFunction(chooseVec2With2BitFlags);
}
/** @internal */
function addChooseVec3WithBitFlagFunction(shader) {
shader.addFunction(extractNthBit);
shader.addFunction(chooseVec3WithBitFlag);
}
function addShaderFlagsConstants(shader) {
shader.addConstant("kShaderBit_Monochrome", 1 /* VariableType.Int */, "0");
shader.addConstant("kShaderBit_NonUniformColor", 1 /* VariableType.Int */, "1");
shader.addConstant("kShaderBit_OITFlatAlphaWeight", 1 /* VariableType.Int */, "2");
shader.addConstant("kShaderBit_OITScaleOutput", 1 /* VariableType.Int */, "3");
shader.addConstant("kShaderBit_IgnoreNonLocatable", 1 /* VariableType.Int */, "4");
}
const shaderFlagArray = new Int32Array(5);
const kShaderBitMonochrome = 0;
const kShaderBitNonUniformColor = 1;
const kShaderBitOITFlatAlphaWeight = 2;
const kShaderBitOITScaleOutput = 3;
const kShaderBitIgnoreNonLocatable = 4;
function setShaderFlags(uniform, params) {
const monochrome = params.target.currentViewFlags.monochrome && params.geometry.wantMonochrome(params.target);
shaderFlagArray[kShaderBitMonochrome] = monochrome ? 1 : 0;
shaderFlagArray[kShaderBitNonUniformColor] = 0;
shaderFlagArray[kShaderBitOITFlatAlphaWeight] = 0;
shaderFlagArray[kShaderBitOITScaleOutput] = 0;
shaderFlagArray[kShaderBitIgnoreNonLocatable] = 0;
const geom = params.geometry.asLUT;
if (undefined !== geom) {
// Could also be RealityMeshGeometry, so only detect non-uniform color if explicitly LUTGeometry.
const color = geom.getColor(params.target);
if (color.isNonUniform)
shaderFlagArray[kShaderBitNonUniformColor] = 1;
}
// Certain textures render in the translucent pass but we actually want to maintain true opacity for opaque pixels.
// For these, use a constant Z to calculate alpha weight. Otherwise, the opaque things in the texture are weighted by their Z due
// to the nature of the OIT algorithm. In this case, we set OITFlatAlphaWeight.
// Since RGBA8 rendering is very low precision, if we are using that kind of output, we also want to flatten alpha weight.
// Otherwise, the very tiny Z range makes things fade to black as the precision limit is encountered. This workaround disregards Z
// in calculating the color, so it means that transparency is less accurate based on Z-ordering, but it is the best we can do with
// this algorithm on low-end hardware.
// Finally, the application can put the viewport into "fadeout mode", which explicitly enables flat alpha weight in order to de-emphasize transparent geometry.
const maxRenderType = System_1.System.instance.maxRenderType;
let flatAlphaWeight = webgl_compatibility_1.RenderType.TextureUnsignedByte === maxRenderType || params.target.isFadeOutActive;
if (!flatAlphaWeight) {
const surface = params.geometry.asSurface;
flatAlphaWeight = undefined !== surface && (surface.isGlyph || surface.isTileSection);
}
if (flatAlphaWeight)
shaderFlagArray[kShaderBitOITFlatAlphaWeight] = 1;
// If Cesium-style transparency is being used with non-float texture targets, we must scale the output in the shaders to 0-1 range.
// Otherwise, it will get implicitly clamped to that range and we'll lose any semblance our desired precision (even though it is low).
if (maxRenderType < webgl_compatibility_1.RenderType.TextureHalfFloat)
shaderFlagArray[kShaderBitOITScaleOutput] = 1;
if (!params.target.drawNonLocatable)
shaderFlagArray[kShaderBitIgnoreNonLocatable] = 1;
uniform.setUniform1iv(shaderFlagArray);
}
/** @internal */
function addShaderFlags(builder) {
addShaderFlagsConstants(builder.vert);
addShaderFlagsConstants(builder.frag);
builder.addUniformArray("u_shaderFlags", 0 /* VariableType.Boolean */, 5, (prog) => {
prog.addGraphicUniform("u_shaderFlags", (uniform, params) => setShaderFlags(uniform, params));
});
}
/** @internal */
function addFrustum(builder) {
builder.addUniform("u_frustum", 4 /* VariableType.Vec3 */, (prog) => {
prog.addProgramUniform("u_frustum", (uniform, params) => {
uniform.setUniform3fv(params.target.uniforms.frustum.frustum);
});
});
builder.addGlobal("kFrustumType_Ortho2d", 2 /* VariableType.Float */, 3 /* ShaderType.Both */, "0.0", true);
builder.addGlobal("kFrustumType_Ortho3d", 2 /* VariableType.Float */, 3 /* ShaderType.Both */, "1.0", true);
builder.addGlobal("kFrustumType_Perspective", 2 /* VariableType.Float */, 3 /* ShaderType.Both */, "2.0", true);
}
const computeEyeSpace = "v_eyeSpace = (MAT_MV * rawPosition).rgb;";
/** @internal */
function addEyeSpace(builder) {
(0, Vertex_1.addModelViewMatrix)(builder.vert);
builder.addInlineComputedVarying("v_eyeSpace", 4 /* VariableType.Vec3 */, computeEyeSpace);
}
/** @internal */
exports.addUInt32s = `
vec4 addUInt32s(vec4 a, vec4 b) {
vec4 c = a + b;
if (c.x > 255.0) { c.x -= 256.0; c.y += 1.0; }
if (c.y > 255.0) { c.y -= 256.0; c.z += 1.0; }
if (c.z > 255.0) { c.z -= 256.0; c.w += 1.0; }
return c;
}
`;
/** Expects flags in range [0...256] with no fraction; and bit is [0..31] with no fraction.
* Return true if bit `n` is set in `flags`.
*/
const nthBitSet = `
bool nthBitSet(float flags, uint n) { return 0u != (uint(flags) & n); }
`;
/** @internal */
const extractNthBit = `
float extractNthBit(float flags, uint n) { return 0u != (uint(flags) & n) ? 1.0 : 0.0; }
`;
/** @internal */
function addExtractNthBit(shader) {
shader.addFunction(nthBitSet);
shader.addFunction(extractNthBit);
}
//# sourceMappingURL=Common.js.map