@animech-public/playcanvas
Version:
PlayCanvas WebGL game engine
40 lines (30 loc) • 1.28 kB
JavaScript
var shadowVSM_commonPS = /* glsl */`
float linstep(float a, float b, float v) {
return saturate((v - a) / (b - a));
}
float reduceLightBleeding(float pMax, float amount) {
// Remove the [0, amount] tail and linearly rescale (amount, 1].
return linstep(amount, 1.0, pMax);
}
float chebyshevUpperBound(vec2 moments, float mean, float minVariance, float lightBleedingReduction) {
// Compute variance
float variance = moments.y - (moments.x * moments.x);
variance = max(variance, minVariance);
// Compute probabilistic upper bound
float d = mean - moments.x;
float pMax = variance / (variance + (d * d));
pMax = reduceLightBleeding(pMax, lightBleedingReduction);
// One-tailed Chebyshev
return (mean <= moments.x ? 1.0 : pMax);
}
float calculateEVSM(vec3 moments, float Z, float vsmBias, float exponent) {
Z = 2.0 * Z - 1.0;
float warpedDepth = exp(exponent * Z);
moments.xy += vec2(warpedDepth, warpedDepth*warpedDepth) * (1.0 - moments.z);
float VSMBias = vsmBias;//0.01 * 0.25;
float depthScale = VSMBias * exponent * warpedDepth;
float minVariance1 = depthScale * depthScale;
return chebyshevUpperBound(moments.xy, warpedDepth, minVariance1, 0.1);
}
`;
export { shadowVSM_commonPS as default };