Skip to content

Commit 506ef55

Browse files
mvaligurskyMartin Valigursky
andauthored
Reproject texture functionality uses native WGSL shaders on WebGPU (#7434)
* Reproject texture functionality uses native WGSL shaders on WebGPU * use wgsl tag for wgsl chunks --------- Co-authored-by: Martin Valigursky <mvaligursky@snapchat.com>
1 parent 44198f8 commit 506ef55

File tree

23 files changed

+423
-48
lines changed

23 files changed

+423
-48
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
export default /* glsl */`
2+
3+
// convert clip space position into texture coordinates for sampling scene grab textures
4+
fn getGrabScreenPos(clipPos: vec4<f32>) -> vec2<f32> {
5+
var uv: vec2<f32> = (clipPos.xy / clipPos.w) * 0.5 + vec2<f32>(0.5);
6+
uv.y = 1.0 - uv.y;
7+
return uv;
8+
}
9+
10+
// convert uv coordinates to sample image effect texture (render target texture rendered without
11+
// forward renderer which does the flip in the projection matrix)
12+
fn getImageEffectUV(uv: vec2<f32>) -> vec2<f32> {
13+
var modifiedUV: vec2<f32> = uv;
14+
modifiedUV.y = 1.0 - modifiedUV.y;
15+
return modifiedUV;
16+
}
17+
`;

src/platform/graphics/shader-utils.js

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ import webgpuFS from './shader-chunks/frag/webgpu.js';
1212
import webgpuVS from './shader-chunks/vert/webgpu.js';
1313
import wgslFS from './shader-chunks/frag/webgpu-wgsl.js';
1414
import wgslVS from './shader-chunks/vert/webgpu-wgsl.js';
15-
import sharedFS from './shader-chunks/frag/shared.js';
15+
import sharedGLSL from './shader-chunks/frag/shared.js';
16+
import sharedWGSL from './shader-chunks/frag/shared-wgsl.js';
1617

1718
/**
1819
* @import { GraphicsDevice } from './graphics-device.js'
@@ -115,13 +116,19 @@ class ShaderUtils {
115116

116117
if (wgsl) {
117118

118-
vertCode = `${wgslVS}
119+
vertCode = `
120+
${wgslVS}
121+
${sharedWGSL}
119122
${vertexDefinesCode}
120-
${options.vertexCode}`;
123+
${options.vertexCode}
124+
`;
121125

122-
fragCode = `${wgslFS}
126+
fragCode = `
127+
${wgslFS}
128+
${sharedWGSL}
123129
${fragmentDefinesCode}
124-
${options.fragmentCode}`;
130+
${options.fragmentCode}
131+
`;
125132

126133
} else {
127134

@@ -130,7 +137,7 @@ class ShaderUtils {
130137
getDefines(webgpuVS, gles3VS, true, options) +
131138
vertexDefinesCode +
132139
ShaderUtils.precisionCode(device)}
133-
${sharedFS}
140+
${sharedGLSL}
134141
${ShaderUtils.getShaderNameCode(name)}
135142
${options.vertexCode}`;
136143

@@ -140,7 +147,7 @@ class ShaderUtils {
140147
getDefines(webgpuFS, gles3FS, false, options) +
141148
fragmentDefinesCode +
142149
ShaderUtils.precisionCode(device)}
143-
${sharedFS}
150+
${sharedGLSL}
144151
${ShaderUtils.getShaderNameCode(name)}
145152
${options.fragmentCode || ShaderUtils.dummyFragmentCode()}`;
146153
}

src/platform/graphics/webgpu/webgpu-shader-processor-wgsl.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ class WebgpuShaderProcessorWGSL {
623623
return `${structCode}};\n`;
624624
}
625625

626-
static processAttributes(attributeLines, shaderDefinitionAttributes, processingOptions) {
626+
static processAttributes(attributeLines, shaderDefinitionAttributes = {}, processingOptions) {
627627
let block = '';
628628
const usedLocations = {};
629629
attributeLines.forEach((line) => {

src/scene/graphics/reproject-texture.js

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ import { random } from '../../core/math/random.js';
33
import { Vec3 } from '../../core/math/vec3.js';
44
import {
55
FILTER_NEAREST,
6-
TEXTUREPROJECTION_OCTAHEDRAL, TEXTUREPROJECTION_CUBE
6+
TEXTUREPROJECTION_OCTAHEDRAL, TEXTUREPROJECTION_CUBE,
7+
SHADERLANGUAGE_WGSL,
8+
SHADERLANGUAGE_GLSL,
9+
SEMANTIC_POSITION
710
} from '../../platform/graphics/constants.js';
811
import { DebugGraphics } from '../../platform/graphics/debug-graphics.js';
912
import { DeviceCache } from '../../platform/graphics/device-cache.js';
@@ -15,6 +18,7 @@ import { getProgramLibrary } from '../shader-lib/get-program-library.js';
1518
import { createShaderFromCode } from '../shader-lib/utils.js';
1619
import { BlendState } from '../../platform/graphics/blend-state.js';
1720
import { drawQuadWithShader } from './quad-render-utils.js';
21+
import { shaderChunksWGSL } from '../shader-lib/chunks-wgsl/chunks-wgsl.js';
1822

1923
/**
2024
* @import { Vec4 } from '../../core/math/vec4.js'
@@ -439,17 +443,26 @@ function reprojectTexture(source, target, options = {}) {
439443
#define {NUM_SAMPLES_SQRT} ${Math.round(Math.sqrt(numSamples)).toFixed(1)}
440444
`;
441445

446+
const wgsl = device.isWebGPU;
447+
const chunks = wgsl ? shaderChunksWGSL : shaderChunks;
442448
const includes = new Map();
443-
includes.set('decodePS', shaderChunks.decodePS);
444-
includes.set('encodePS', shaderChunks.encodePS);
449+
includes.set('decodePS', chunks.decodePS);
450+
includes.set('encodePS', chunks.encodePS);
445451

452+
const vert = chunks.reprojectVS;
453+
const frag = chunks.reprojectPS;
446454
shader = createShaderFromCode(
447455
device,
448-
shaderChunks.reprojectVS,
449-
`${defines}\n${shaderChunks.reprojectPS}`,
450-
shaderKey,
451-
undefined, {
452-
fragmentIncludes: includes
456+
vert,
457+
`
458+
${defines}
459+
${frag}
460+
`,
461+
shaderKey, {
462+
vertex_position: SEMANTIC_POSITION
463+
}, {
464+
fragmentIncludes: includes,
465+
shaderLanguage: wgsl ? SHADERLANGUAGE_WGSL : SHADERLANGUAGE_GLSL
453466
}
454467
);
455468
}

src/scene/shader-lib/chunks-wgsl/chunks-wgsl.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import decodePS from './common/frag/decode.js';
2727
// import diffusePS from './standard/frag/diffuse.js';
2828
// import diffuseDetailMapPS from './standard/frag/diffuseDetailMap.js';
2929
// import emissivePS from './standard/frag/emissive.js';
30-
// import encodePS from './common/frag/encode.js';
30+
import encodePS from './common/frag/encode.js';
3131
// import endPS from './lit/frag/end.js';
3232
import envAtlasPS from './common/frag/envAtlas.js';
3333
import envProcPS from './common/frag/envProc.js';
@@ -154,8 +154,8 @@ import immediateLineVS from './internal/vert/immediateLine.js';
154154
// import reflectionSheenPS from './lit/frag/reflectionSheen.js';
155155
// import refractionCubePS from './lit/frag/refractionCube.js';
156156
// import refractionDynamicPS from './lit/frag/refractionDynamic.js';
157-
// import reprojectPS from './common/frag/reproject.js';
158-
// import reprojectVS from './common/vert/reproject.js';
157+
import reprojectPS from './internal/frag/reproject.js';
158+
import reprojectVS from './internal/vert/reproject.js';
159159
// import sampleCatmullRomPS from './common/frag/sampleCatmullRom.js';
160160
// import screenDepthPS from './common/frag/screenDepth.js';
161161
// import shadowCascadesPS from './lit/frag/shadowCascades.js';
@@ -235,7 +235,7 @@ const shaderChunksWGSL = {
235235
// diffuseDetailMapPS,
236236
decodePS,
237237
// emissivePS,
238-
// encodePS,
238+
encodePS,
239239
// endPS,
240240
envAtlasPS,
241241
// envConstPS,
@@ -364,8 +364,8 @@ const shaderChunksWGSL = {
364364
// reflectionSheenPS,
365365
// refractionCubePS,
366366
// refractionDynamicPS,
367-
// reprojectPS,
368-
// reprojectVS,
367+
reprojectPS,
368+
reprojectVS,
369369
// sampleCatmullRomPS,
370370
// screenDepthPS,
371371
// shadowCascadesPS,

src/scene/shader-lib/chunks-wgsl/common/frag/decode.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export default /* glsl */`
1+
export default /* wgsl */`
22
33
#ifndef _DECODE_INCLUDED_
44
#define _DECODE_INCLUDED_
@@ -7,15 +7,15 @@ fn decodeLinear(raw: vec4f) -> vec3f {
77
return raw.rgb;
88
}
99
10-
fn decodeGamma(raw: f32) -> f32 {
10+
fn decodeGammaFloat(raw: f32) -> f32 {
1111
return pow(raw, 2.2);
1212
}
1313
1414
fn decodeGammaVec3(raw: vec3f) -> vec3f {
1515
return pow(raw, vec3f(2.2));
1616
}
1717
18-
fn decodeGammaVec4(raw: vec4f) -> vec3f {
18+
fn decodeGamma(raw: vec4f) -> vec3f {
1919
return pow(raw.xyz, vec3f(2.2));
2020
}
2121
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
export default /* wgsl */`
2+
fn encodeLinear(source: vec3f) -> vec4f {
3+
return vec4f(source, 1.0);
4+
}
5+
6+
fn encodeGamma(source: vec3f) -> vec4f {
7+
return vec4f(pow(source + vec3f(0.0000001), vec3f(1.0 / 2.2)), 1.0);
8+
}
9+
10+
fn encodeRGBM(source: vec3f) -> vec4f {
11+
var color: vec3f = pow(source, vec3f(0.5));
12+
color *= 1.0 / 8.0;
13+
14+
var a: f32 = saturate(max(max(color.r, color.g), max(color.b, 1.0 / 255.0)));
15+
a = ceil(a * 255.0) / 255.0;
16+
17+
color /= a;
18+
return vec4f(color, a);
19+
}
20+
21+
fn encodeRGBP(source: vec3f) -> vec4f {
22+
// convert incoming linear to gamma(ish)
23+
var gamma: vec3f = pow(source, vec3f(0.5));
24+
25+
// calculate the maximum component clamped to 1..8
26+
var maxVal: f32 = min(8.0, max(1.0, max(gamma.x, max(gamma.y, gamma.z))));
27+
28+
// calculate storage factor
29+
var v: f32 = 1.0 - ((maxVal - 1.0) / 7.0);
30+
31+
// round the value for storage in 8bit channel
32+
v = ceil(v * 255.0) / 255.0;
33+
34+
return vec4f(gamma / (-v * 7.0 + 8.0), v);
35+
}
36+
37+
fn encodeRGBE(source: vec3f) -> vec4f {
38+
var maxVal: f32 = max(source.x, max(source.y, source.z));
39+
if (maxVal < 1e-32) {
40+
return vec4f(0.0, 0.0, 0.0, 0.0);
41+
} else {
42+
var e: f32 = ceil(log2(maxVal));
43+
return vec4f(source / pow(2.0, e), (e + 128.0) / 255.0);
44+
}
45+
}
46+
`;

src/scene/shader-lib/chunks-wgsl/common/frag/fog.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export default /* glsl */`
1+
export default /* wgsl */`
22
33
#if (FOG != NONE)
44
uniform fog_color : vec3f;

src/scene/shader-lib/chunks-wgsl/common/frag/gamma.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
export default /* glsl */`
1+
export default /* wgsl */`
22
33
#include "decodePS"
44
55
#if (GAMMA == SRGB)
66
77
fn gammaCorrectInput(color: f32) -> f32 {
8-
return decodeGamma(color);
8+
return decodeGammaFloat(color);
99
}
1010
1111
fn gammaCorrectInputVec3(color: vec3f) -> vec3f {

src/scene/shader-lib/chunks-wgsl/common/frag/tonemapping/tonemapping.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export default /* glsl */`
1+
export default /* wgsl */`
22
#if (TONEMAP == NONE)
33
#include "tonemappingNonePS"
44
#elif TONEMAP == FILMIC

0 commit comments

Comments
 (0)