-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathTonemappingPass.ts
More file actions
74 lines (62 loc) · 2.72 KB
/
TonemappingPass.ts
File metadata and controls
74 lines (62 loc) · 2.72 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
70
71
72
73
74
import {fromValues as Vec4} from 'gl-vec4';
import {setUniforms} from 'gl-utils';
import {PassExecuteParams} from './structs';
import {FboBindType} from 'resources';
import {ColorGradingPerRangeSettings, ColorGradingProp} from 'Config';
export enum TonemappingMode {
Linear = 0, Reinhard = 1, Uncharted2 = 2, Photographic = 3, ACES_UE4 = 4,
}
type TonemappingModeKey = keyof typeof TonemappingMode;
export const TonemappingModesList = [
'Linear', 'Reinhard', 'Uncharted2', 'Photographic', 'ACES_UE4'
] as TonemappingModeKey[];
/**
* FXAA needs data after tonemapping, so we need separate pass
* - tonemapping
* - color grading - LUTs do not work on HDR displays,
* so industry moved to film-like color grading tools
* (https://docs.unrealengine.com/en-us/Engine/Rendering/PostProcessEffects/ColorGrading)
*/
export class TonemappingPass {
execute (params: PassExecuteParams) {
const {cfg, device, frameRes} = params;
const {gl} = device;
const shader = frameRes.tonemappingShader;
shader.use(gl);
const fbo = frameRes.tonemappingFbo;
frameRes.tonemappingFbo.bind(gl, FboBindType.Draw, true);
gl.viewport(0.0, 0.0, fbo.dimensions[0], fbo.dimensions[1]);
const colorGradCfg = cfg.postfx.colorGrading;
setUniforms(device, shader, {
'u_source': frameRes.forwardColorTex,
'u_gamma': cfg.postfx.gamma, // needed for luma, not actuall gamm (this will be after AA)
'u_ditherStrength': cfg.postfx.ditherStrength,
// color grading
...this.prepareColorGradingParams('', colorGradCfg.global),
...this.prepareColorGradingParams('Shadows', colorGradCfg.shadows),
...this.prepareColorGradingParams('Midtones', colorGradCfg.midtones),
...this.prepareColorGradingParams('Highlights', colorGradCfg.highlights),
'u_colorCorrectionShadowsMax': colorGradCfg.shadows.shadowsMax,
'u_colorCorrectionHighlightsMin': colorGradCfg.highlights.highlightsMin,
// tonemapping
'u_exposure': cfg.postfx.exposure,
'u_whitePoint': cfg.postfx.whitePoint,
'u_tonemappingMode': cfg.postfx.tonemappingOp,
'u_acesC': cfg.postfx.acesC,
'u_acesS': cfg.postfx.acesS,
}, true);
device.renderFullscreenQuad(true);
}
private prepareColorGradingParams(uSufix: string, obj: ColorGradingPerRangeSettings) {
const toVec4 = (cgp: ColorGradingProp) => Vec4(
cgp.color[0], cgp.color[1], cgp.color[2], cgp.value
);
return {
[`u_colorSaturation${uSufix}`]: toVec4(obj.saturation),
[`u_colorContrast${uSufix}`]: toVec4(obj.contrast),
[`u_colorGamma${uSufix}`]: toVec4(obj.gamma),
[`u_colorGain${uSufix}`]: toVec4(obj.gain),
[`u_colorOffset${uSufix}`]: toVec4(obj.offset),
};
}
}