Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions src/extras/render-passes/render-pass-compose.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { Color } from '../../core/math/color.js';
import { RenderPassShaderQuad } from '../../scene/graphics/render-pass-shader-quad.js';
import { GAMMA_NONE, GAMMA_SRGB, gammaNames, TONEMAP_LINEAR, tonemapNames } from '../../scene/constants.js';
import { ShaderChunks } from '../../scene/shader-lib/shader-chunks.js';
import { SEMANTIC_POSITION, SHADERLANGUAGE_GLSL } from '../../platform/graphics/constants.js';
import { SEMANTIC_POSITION, SHADERLANGUAGE_GLSL, SHADERLANGUAGE_WGSL } from '../../platform/graphics/constants.js';
import { ShaderUtils } from '../../scene/shader-lib/shader-utils.js';
import glslComposePS from '../../scene/shader-lib/glsl/chunks/render-pass/frag/compose.js';
import { composeChunksGLSL } from '../../scene/shader-lib/glsl/collections/compose-chunks-glsl.js';
import { composeChunksWGSL } from '../../scene/shader-lib/wgsl/collections/compose-chunks-wgsl.js';

/**
* Render pass implementation of the final post-processing composition.
Expand Down Expand Up @@ -69,6 +70,10 @@ class RenderPassCompose extends RenderPassShaderQuad {
constructor(graphicsDevice) {
super(graphicsDevice);

// register compose shader chunks
ShaderChunks.get(graphicsDevice, SHADERLANGUAGE_GLSL).add(composeChunksGLSL);
ShaderChunks.get(graphicsDevice, SHADERLANGUAGE_WGSL).add(composeChunksWGSL);

const { scope } = graphicsDevice;
this.sceneTextureId = scope.resolve('sceneTexture');
this.bloomTextureId = scope.resolve('bloomTexture');
Expand Down Expand Up @@ -254,13 +259,13 @@ class RenderPassCompose extends RenderPassShaderQuad {
if (this.isSharpnessEnabled) defines.set('CAS', true);
if (this._debug) defines.set('DEBUG_COMPOSE', this._debug);

const includes = new Map(ShaderChunks.get(this.device, SHADERLANGUAGE_GLSL));
const includes = new Map(ShaderChunks.get(this.device, this.device.isWebGPU ? SHADERLANGUAGE_WGSL : SHADERLANGUAGE_GLSL));

this.shader = ShaderUtils.createShader(this.device, {
uniqueName: `ComposeShader-${key}`,
attributes: { aPosition: SEMANTIC_POSITION },
vertexChunk: 'quadVS',
fragmentGLSL: glslComposePS,
fragmentChunk: 'composePS',
fragmentDefines: defines,
fragmentIncludes: includes
});
Expand Down
264 changes: 0 additions & 264 deletions src/scene/shader-lib/glsl/chunks/render-pass/frag/compose.js

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export default /* glsl */`
#ifdef BLOOM
uniform sampler2D bloomTexture;
uniform float bloomIntensity;

// Global variable for debug
vec3 dBloom;

vec3 applyBloom(vec3 color, vec2 uv) {
dBloom = texture2DLod(bloomTexture, uv, 0.0).rgb;
return color + dBloom * bloomIntensity;
}
#endif
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Contrast Adaptive Sharpening (CAS) is used to apply the sharpening. It's based on AMD's
// FidelityFX CAS, WebGL implementation: https://www.shadertoy.com/view/wtlSWB. It's best to run it
// on a tone-mapped color buffer after post-processing, but before the UI, and so this is the
// obvious place to put it to avoid a separate render pass, even though we need to handle running it
// before the tone-mapping.
export default /* glsl */`
#ifdef CAS
uniform float sharpness;

// reversible LDR <-> HDR tone mapping, as CAS needs LDR input
float maxComponent(float x, float y, float z) { return max(x, max(y, z)); }
vec3 toSDR(vec3 c) { return c / (1.0 + maxComponent(c.r, c.g, c.b)); }
vec3 toHDR(vec3 c) { return c / (1.0 - maxComponent(c.r, c.g, c.b)); }

vec3 applyCas(vec3 color, vec2 uv, float sharpness) {
float x = sceneTextureInvRes.x;
float y = sceneTextureInvRes.y;

// sample 4 neighbors around the already sampled pixel, and convert it to SDR
vec3 a = toSDR(texture2DLod(sceneTexture, uv + vec2(0.0, -y), 0.0).rgb);
vec3 b = toSDR(texture2DLod(sceneTexture, uv + vec2(-x, 0.0), 0.0).rgb);
vec3 c = toSDR(color.rgb);
vec3 d = toSDR(texture2DLod(sceneTexture, uv + vec2(x, 0.0), 0.0).rgb);
vec3 e = toSDR(texture2DLod(sceneTexture, uv + vec2(0.0, y), 0.0).rgb);

// apply the sharpening
float min_g = min(a.g, min(b.g, min(c.g, min(d.g, e.g))));
float max_g = max(a.g, max(b.g, max(c.g, max(d.g, e.g))));
float sharpening_amount = sqrt(min(1.0 - max_g, min_g) / max_g);
float w = sharpening_amount * sharpness;
vec3 res = (w * (a + b + d + e) + c) / (4.0 * w + 1.0);

// remove negative colors
res = max(res, 0.0);

// convert back to HDR
return toHDR(res);
}
#endif
`;
Loading