-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathSSSBlurPass.ts
More file actions
69 lines (55 loc) · 2.2 KB
/
SSSBlurPass.ts
File metadata and controls
69 lines (55 loc) · 2.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import {fromValues as Vec2} from 'gl-vec2';
import {setUniforms} from 'gl-utils';
import {DrawParams, DepthTest, CullingMode, StencilTest} from 'gl-utils/DrawParams';
import {FboBindType, Fbo, Texture} from 'resources';
import {PassExecuteParams} from './structs';
interface SSSBlurPassData {
fbo: Fbo;
sourceTexture: Texture;
isFirstPass: boolean;
}
const DIRECTION_HORIZONTAL = Vec2(1, 0);
const DIRECTION_VERTICAL = Vec2(0, 1);
export class SSSBlurPass {
execute (params: PassExecuteParams, data: SSSBlurPassData) {
const {cfg, device, frameRes} = params;
const {gl} = device;
const {fbo, isFirstPass, sourceTexture} = data;
fbo.bind(gl, FboBindType.Draw, true);
gl.viewport(0.0, 0.0, fbo.dimensions[0], fbo.dimensions[1]);
if (isFirstPass) {
gl.clear(gl.COLOR_BUFFER_BIT); // clear last frame ping-pong texture
}
const shader = frameRes.sssBlurShader;
shader.use(gl);
const dp = new DrawParams();
dp.depth.write = false;
dp.depth.test = DepthTest.AlwaysPass;
dp.culling = CullingMode.None;
// stencil: everywhere that is skin, but no hair
dp.stencil.referenceValue = cfg.stencilConsts.skin; // ref: 0b01
dp.stencil.compareMask = cfg.stencilConsts.skin | cfg.stencilConsts.hair; // compare bits: 0b11
dp.stencil.front.test = StencilTest.IfRefIsEqualCurrent;
dp.stencil.back.test = StencilTest.IfRefIsEqualCurrent;
device.setState(dp);
setUniforms(device, shader, {
'u_sourceTex': sourceTexture,
'u_linearDepthTex': frameRes.linearDepthTex,
'u_sssDirection': this.getDirection(isFirstPass),
'u_sssFollowSurface': cfg.lightSSS.blurFollowSurface ? 1 : 0,
'u_sssFovy': this.getFovY(params), // in dgr?
'u_sssWidth': cfg.lightSSS.blurWidth,
'u_sssStrength': cfg.lightSSS.blurStrength,
}, true);
device.renderFullscreenQuad();
}
private getDirection(isFirstPass: boolean) {
return isFirstPass ? DIRECTION_HORIZONTAL : DIRECTION_VERTICAL;
}
private getFovY(params: PassExecuteParams) {
// I have no idea if this is correct.
// I do not care if this is correct.
const {viewport, camera} = params;
return camera.settings.fovDgr / viewport.width * viewport.height;
}
}