@itwin/core-frontend
Version:
iTwin.js frontend components
71 lines (66 loc) • 3.31 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
*/
import { AttributeMap } from "../AttributeMap";
import { TextureUnit } from "../RenderFlags";
import { ProgramBuilder } from "../ShaderBuilder";
import { Texture2DHandle } from "../Texture";
import { assignFragColor } from "./Fragment";
import { addEvsmExponent, warpDepth } from "./SolarShadowMapping";
// This shader reads the depth texture, converts it to EVSM values, then averages those down 4 to 1
// Positions are in NDC [-1..1]. Compute UV params in [0..1]
const computeTexCoord = "v_texCoord = (rawPosition.xy + 1.0) * 0.5;";
const computePosition = "return rawPos;";
const computeEVSM = `
const float sampleWeight = 0.25;
vec4 average = vec4(0.0);
vec2 tc = v_texCoord - u_stepSize * 0.5; // v_texCoord starts in between the 4 texels
float depth = TEXTURE(u_depthTexture, tc).r;
vec2 vsmDepth = warpDepth(depth, u_evsmExponent);
average += sampleWeight * vec4(vsmDepth.xy, vsmDepth.xy * vsmDepth.xy);
tc.x += u_stepSize.x;
depth = TEXTURE(u_depthTexture, tc).r;
vsmDepth = warpDepth(depth, u_evsmExponent);
average += sampleWeight * vec4(vsmDepth.xy, vsmDepth.xy * vsmDepth.xy);
tc.y += u_stepSize.y;
depth = TEXTURE(u_depthTexture, tc).r;
vsmDepth = warpDepth(depth, u_evsmExponent);
average += sampleWeight * vec4(vsmDepth.xy, vsmDepth.xy * vsmDepth.xy);
tc.x -= u_stepSize.x;
depth = TEXTURE(u_depthTexture, tc).r;
vsmDepth = warpDepth(depth, u_evsmExponent);
average += sampleWeight * vec4(vsmDepth.xy, vsmDepth.xy * vsmDepth.xy);
return average;
`;
/** @internal */
export function createEVSMProgram(context) {
const builder = new ProgramBuilder(AttributeMap.findAttributeMap(undefined, false));
const vert = builder.vert;
const frag = builder.frag;
vert.set(10 /* VertexShaderComponent.ComputePosition */, computePosition);
builder.addInlineComputedVarying("v_texCoord", 3 /* VariableType.Vec2 */, computeTexCoord);
frag.addUniform("u_depthTexture", 8 /* VariableType.Sampler2D */, (prog) => {
prog.addGraphicUniform("u_depthTexture", (uniform, params) => {
const geom = params.geometry;
Texture2DHandle.bindSampler(uniform, geom.depthTexture, TextureUnit.Zero);
});
});
frag.addUniform("u_stepSize", 3 /* VariableType.Vec2 */, (prog) => {
prog.addGraphicUniform("u_stepSize", (uniform, params) => {
const geom = params.geometry;
uniform.setUniform2fv(geom.stepSize);
});
}, 3 /* VariablePrecision.High */);
addEvsmExponent(frag);
frag.addFunction(warpDepth);
frag.set(1 /* FragmentShaderComponent.ComputeBaseColor */, computeEVSM);
frag.set(18 /* FragmentShaderComponent.AssignFragData */, assignFragColor);
builder.vert.headerComment = "//!V! EVSMFromDepth";
builder.frag.headerComment = "//!F! EVSMFromDepth";
return builder.buildProgram(context);
}
//# sourceMappingURL=EVSMFromDepth.js.map