Skip to content

Commit

Permalink
Compose render pass contains color grading (#5839)
Browse files Browse the repository at this point in the history
Co-authored-by: Martin Valigursky <mvaligursky@snapchat.com>
  • Loading branch information
mvaligursky and Martin Valigursky authored Nov 22, 2023
1 parent 37da3b2 commit 7bbf071
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 10 deletions.
67 changes: 67 additions & 0 deletions examples/src/examples/graphics/post-processing.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ function controls({ observer, ReactPCUI, React, jsx, fragment }) {
)
),
jsx(Panel, { headerText: 'BLOOM' },
jsx(LabelGroup, { text: 'enabled' },
jsx(BooleanInput, {
type: 'toggle',
binding: new BindingTwoWay(),
link: { observer, path: 'data.bloom.enabled' }
})
),
jsx(LabelGroup, { text: 'intensity' },
jsx(SliderInput, {
binding: new BindingTwoWay(),
Expand All @@ -51,6 +58,42 @@ function controls({ observer, ReactPCUI, React, jsx, fragment }) {
precision: 0
})
)
),
jsx(Panel, { headerText: 'Grading' },
jsx(LabelGroup, { text: 'enabled' },
jsx(BooleanInput, {
type: 'toggle',
binding: new BindingTwoWay(),
link: { observer, path: 'data.grading.enabled' }
})
),
jsx(LabelGroup, { text: 'saturation' },
jsx(SliderInput, {
binding: new BindingTwoWay(),
link: { observer, path: 'data.grading.saturation' },
min: 0,
max: 3,
precision: 2
})
),
jsx(LabelGroup, { text: 'brightness' },
jsx(SliderInput, {
binding: new BindingTwoWay(),
link: { observer, path: 'data.grading.brightness' },
min: 0,
max: 3,
precision: 2
})
),
jsx(LabelGroup, { text: 'contrast' },
jsx(SliderInput, {
binding: new BindingTwoWay(),
link: { observer, path: 'data.grading.contrast' },
min: 0,
max: 3,
precision: 2
})
)
)
);
}
Expand Down Expand Up @@ -319,6 +362,23 @@ async function example({ canvas, deviceType, assetPath, glslangPath, twgslPath,
if (pathArray[2] === 'lastMipLevel') {
bloomPass.lastMipLevel = value;
}
if (pathArray[2] === 'enabled') {
composePass.bloomTexture = value ? bloomPass.bloomTexture : null;
}
}
if (pathArray[1] === 'grading') {
if (pathArray[2] === 'saturation') {
composePass.gradingSaturation = value;
}
if (pathArray[2] === 'brightness') {
composePass.gradingBrightness = value;
}
if (pathArray[2] === 'contrast') {
composePass.gradingContrast = value;
}
if (pathArray[2] === 'enabled') {
composePass.gradingEnabled = value;
}
}
});

Expand All @@ -328,8 +388,15 @@ async function example({ canvas, deviceType, assetPath, glslangPath, twgslPath,
tonemapping: pc.TONEMAP_ACES
},
bloom: {
enabled: true,
intensity: 20,
lastMipLevel: 1
},
grading: {
enabled: false,
saturation: 1,
brightness: 1,
contrast: 1
}
});

Expand Down
94 changes: 84 additions & 10 deletions extras/render-passes/render-pass-compose.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,41 @@ import {
} from "playcanvas";

const fragmentShader = `
uniform sampler2D sceneTexture;
uniform sampler2D bloomTexture;
uniform float bloomIntensity;
varying vec2 uv0;
uniform sampler2D sceneTexture;
#ifdef BLOOM
uniform sampler2D bloomTexture;
uniform float bloomIntensity;
#endif
#ifdef GRADING
uniform vec3 brightnessContrastSaturation;
// for all parameters, 1.0 is the no-change value
vec3 ContrastSaturationBrightness(vec3 color, float brt, float sat, float con)
{
color = color * brt;
float grey = dot(color, vec3(0.3, 0.59, 0.11));
color = mix(vec3(grey), color, sat);
return max(mix(vec3(0.5), color, con), 0.0);
}
#endif
void main() {
vec4 scene = texture2D(sceneTexture, uv0);
vec3 bloom = texture2D(bloomTexture, uv0).rgb;
vec3 result = scene.rgb;
result += bloom * bloomIntensity;
#ifdef BLOOM
vec3 bloom = texture2D(bloomTexture, uv0).rgb;
result += bloom * bloomIntensity;
#endif
#ifdef GRADING
result = ContrastSaturationBrightness(result, brightnessContrastSaturation.x, brightnessContrastSaturation.z, brightnessContrastSaturation.y);
#endif
result = toneMap(result);
result = gammaCorrectOutput(result);
Expand All @@ -24,10 +49,22 @@ const fragmentShader = `
`;

class RenderPassCompose extends RenderPassShaderQuad {
sceneTexture = null;

bloomIntensity = 0.01;

_bloomTexture = null;

_toneMapping = TONEMAP_ACES2;

_gradingEnabled = false;

gradingSaturation = 1;

gradingContrast = 1;

gradingBrightness = 1;

_shaderDirty = true;

_key = '';
Expand All @@ -38,6 +75,29 @@ class RenderPassCompose extends RenderPassShaderQuad {
this.sceneTextureId = graphicsDevice.scope.resolve('sceneTexture');
this.bloomTextureId = graphicsDevice.scope.resolve('bloomTexture');
this.bloomIntensityId = graphicsDevice.scope.resolve('bloomIntensity');
this.bcsId = graphicsDevice.scope.resolve('brightnessContrastSaturation');
}

set bloomTexture(value) {
if (this._bloomTexture !== value) {
this._bloomTexture = value;
this._shaderDirty = true;
}
}

get bloomTexture() {
return this._bloomTexture;
}

set gradingEnabled(value) {
if (this._gradingEnabled !== value) {
this._gradingEnabled = value;
this._shaderDirty = true;
}
}

get gradingEnabled() {
return this._gradingEnabled;
}

set toneMapping(value) {
Expand Down Expand Up @@ -74,25 +134,39 @@ class RenderPassCompose extends RenderPassShaderQuad {
if (this._shaderDirty) {
this._shaderDirty = false;

const key = `${this.toneMapping}`;
const key = `${this.toneMapping}` +
`-${this.bloomTexture ? 'bloom' : 'nobloom'}` +
`-${this.gradingEnabled ? 'grading' : 'nograding'}`;

if (this._key !== key) {
this._key = key;

const defines =
(this.bloomTexture ? `#define BLOOM\n` : '') +
(this.gradingEnabled ? `#define GRADING\n` : '');

const fsChunks =
shaderChunks.decodePS +
shaderChunks.gamma2_2PS +
this.toneMapChunk;

this.shader = this.createQuadShader(`ComposeShader-${key}`, fsChunks + fragmentShader);
this.shader = this.createQuadShader(`ComposeShader-${key}`, defines + fsChunks + fragmentShader);
}
}
}

execute() {

this.sceneTextureId.setValue(this.sceneTexture);
this.bloomTextureId.setValue(this.bloomTexture);
this.bloomIntensityId.setValue(this.bloomIntensity);

if (this._bloomTexture) {
this.bloomTextureId.setValue(this._bloomTexture);
this.bloomIntensityId.setValue(this.bloomIntensity);
}

if (this._gradingEnabled) {
this.bcsId.setValue([this.gradingBrightness, this.gradingContrast, this.gradingSaturation]);
}

super.execute();
}
Expand Down

0 comments on commit 7bbf071

Please sign in to comment.