@itwin/core-frontend
Version:
iTwin.js frontend components
55 lines (53 loc) • 2.64 kB
JavaScript
"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.computeOutputs = exports.computeAlphaWeight = void 0;
exports.addTranslucency = addTranslucency;
const Common_1 = require("./Common");
const Fragment_1 = require("./Fragment");
const Vertex_1 = require("./Vertex");
// See Weighted Blended Order-Independent Transparency for examples of different weighting functions:
// http://jcgt.org/published/0002/02/09/
// We are using Equation 10 from the above paper. Equation 10 directly uses screen-space gl_FragCoord.z.
// flatAlphaWeight bit is set if we want to apply OIT transparency using a constant Z value of 1.
// computeLinearDepth() removes the perspective and puts z in linear [0..1]
// To avoid excessively low weight for fragments close to the far plane, scale depth to [0.15, 1.0].
exports.computeAlphaWeight = `
float computeAlphaWeight(float a) {
float d = computeLinearDepth(v_eyeSpace.z) * .85 + .15;
float z = (u_shaderFlags[kShaderBit_OITFlatAlphaWeight] ? 1.0 : d);
return pow(a + 0.01, 4.0) + max(1e-2, 3.0 * 1e3 * pow(z, 3.0));
}
`;
// NB: Our blending algorithm uses pre-multiplied alpha
exports.computeOutputs = `
vec3 Ci = baseColor.rgb * baseColor.a;
float ai = min(0.99, baseColor.a); // OIT algorithm does not nicely handle a=1
float wzi = computeAlphaWeight(ai);
// If we are scaling output into the 0 to 1 range, we use the maximum output of the alpha weight function.
float outputScale = (u_shaderFlags[kShaderBit_OITScaleOutput] ? 1.0 / 3001.040604 : 1.0);
vec4 output0 = vec4(Ci * wzi * outputScale, ai);
vec4 output1 = vec4(ai * wzi * outputScale, 0.0, 0.0, ai * wzi * outputScale);
`;
const assignFragData = `${exports.computeOutputs}
FragColor0 = output0;
FragColor1 = output1;
`;
/** @internal */
function addTranslucency(prog) {
const frag = prog.frag;
(0, Common_1.addEyeSpace)(prog);
(0, Common_1.addFrustum)(prog);
(0, Vertex_1.addModelViewMatrix)(prog.vert);
frag.addFunction(Fragment_1.computeLinearDepth);
frag.addFunction(exports.computeAlphaWeight);
frag.addDrawBuffersExtension(2);
frag.set(18 /* FragmentShaderComponent.AssignFragData */, assignFragData);
}
//# sourceMappingURL=Translucency.js.map