Skip to content

Commit cc540b5

Browse files
committed
Rewrote more stuff from the SDF Renderer into TGSL
1 parent 81ebe71 commit cc540b5

File tree

4 files changed

+121
-152
lines changed

4 files changed

+121
-152
lines changed

apps/phoure-www/src/lib-filter/bicubicFilter.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ const fullScreenQuadVertexFn = tgpu['~unstable']
2121
texelSizeY: vec2f,
2222
coordHG: vec2f,
2323
},
24-
})(/* wgsl */ `{
24+
})(
25+
/* wgsl */ `{
2526
const SCREEN_RECT = array<vec2f, 6>(
2627
vec2f(-1.0, -1.0),
2728
vec2f(1.0, -1.0),
@@ -54,7 +55,8 @@ const fullScreenQuadVertexFn = tgpu['~unstable']
5455
output.coordHG = UVS[in.idx] * viewport_size - vec2f(0.5f, 0.5f); // fetch offsets and weights from filter texture
5556
5657
return output;
57-
}`)
58+
}`,
59+
)
5860
.$uses({ texture: layout.bound.texture });
5961

6062
/**
@@ -71,7 +73,8 @@ const resampleCubic = tgpu['~unstable']
7173
coordHG: vec2f,
7274
},
7375
out: vec4f,
74-
})(/* wgsl */ `{
76+
})(
77+
/* wgsl */ `{
7578
var hg_x = textureSample(hgLookup, wrappingSampler, in.coordHG.x).xyz;
7679
var hg_y = textureSample(hgLookup, wrappingSampler, in.coordHG.y).xyz; // determine linear sampling coordinates
7780
var coord_source10 = in.uv + hg_x.x * in.texelSizeX;
@@ -87,9 +90,10 @@ const resampleCubic = tgpu['~unstable']
8790
tex_source00 = mix(tex_source00, tex_source01, hg_y.z);
8891
tex_source10 = mix(tex_source10, tex_source11, hg_y.z); // weight along x direction
8992
tex_source00 = mix(tex_source00, tex_source10, hg_x.z);
90-
93+
9194
return tex_source00;
92-
}`)
95+
}`,
96+
)
9397
.$uses({
9498
hgLookup: layout.bound.hgLookup,
9599
texture: layout.bound.texture,

apps/phoure-www/src/lib/GameEngine/blipDifferenceStep/blipDifferenceStep.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export const BlipDifferenceStep = ({
7171
pipeline
7272
.withColorAttachment(passColorAttachment)
7373
.with(layout, bindGroup)
74-
.draw(6);
74+
.draw(3);
7575
},
7676
};
7777
};

apps/phoure-www/src/lib/GameEngine/sdfRenderer/sdfRenderer.ts

Lines changed: 111 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,11 @@ import {
2121

2222
import { store } from 'src/lib/store.ts';
2323
import type { GBuffer } from '../../gBuffer.ts';
24-
import { ONES_3F } from '../wgslUtils/mathConstants.ts';
2524
import { Material, skyColor, worldMat, worldSdf } from './worldSdf.ts';
2625

2726
const BlockSize = 8;
2827

2928
// parameters
30-
const OutputFormat = tgpu['~unstable'].slot().$name('output_format');
31-
3229
const SUPER_SAMPLES = 4;
3330
const ONE_OVER_SUPER_SAMPLES = 1 / SUPER_SAMPLES;
3431
const SUB_SAMPLES = 16;
@@ -42,6 +39,8 @@ const Reflection = d.struct({
4239
roughness: d.f32,
4340
});
4441

42+
const ReflectionArray = d.arrayOf(Reflection, MAX_REFL);
43+
4544
export const accumulatedLayersAtom = atom(0);
4645

4746
/**
@@ -50,140 +49,123 @@ export const accumulatedLayersAtom = atom(0);
5049
* @param normal
5150
* @param mat_roughness
5251
*/
53-
const reflect = tgpu['~unstable']
54-
.fn(
55-
[d.vec3f, d.vec3f, d.f32, d.ptrFn(d.f32)],
56-
d.vec3f,
57-
)(
58-
`(rayDir, normal, matRoughness, outRoughness) {
59-
let slope = dot(rayDir, normal);
60-
let dn2 = 2. * slope;
61-
let refl_dir = rayDir - dn2 * normal;
62-
63-
let fresnel = 1. - pow(1. + slope, 16.);
64-
let roughness = matRoughness * fresnel;
65-
*outRoughness = roughness;
66-
67-
var new_ray_dir = randf.onHemisphere(normal);
68-
new_ray_dir = mix(refl_dir, new_ray_dir, roughness);
69-
return normalize(new_ray_dir);
70-
}`,
71-
)
72-
.$uses({ randf })
73-
.$name('reflect');
74-
75-
const renderSubPixel = tgpu['~unstable']
76-
.fn(
77-
[d.vec2f],
78-
d.vec3f,
79-
)(
80-
/* wgsl */ `(coord: vec2f) -> vec3f {
81-
// doing the first march before each sub-sample, since the first march result is the same for all of them
82-
83-
var init_shape_ctx: ShapeContext;
84-
init_shape_ctx.rayPos = constructRayPos();
85-
init_shape_ctx.rayDir = constructRayDir(coord);
86-
init_shape_ctx.rayDistance = 0.;
87-
var init_march_result: MarchResult;
88-
89-
march(&init_shape_ctx, MAX_STEPS, &init_march_result);
90-
91-
if (init_march_result.steps >= MAX_STEPS) {
92-
return min(skyColor(init_shape_ctx.rayDir), ONES_3F);
93-
}
52+
const reflect = tgpu.fn(
53+
[d.vec3f, d.vec3f, d.f32, d.ptrFn(d.f32)],
54+
d.vec3f,
55+
)((rayDir, normal, matRoughness, outRoughness) => {
56+
const slope = std.dot(rayDir, normal);
57+
const refl_dir = rayDir.sub(normal.mul(2 * slope));
58+
59+
const fresnel = 1 - std.pow(1 + slope, 16);
60+
const roughness = matRoughness * fresnel;
61+
// TODO: Fix when boxed values are introduced
62+
// biome-ignore lint/style/noParameterAssign: Has to be done like this for now
63+
outRoughness = roughness;
64+
65+
let new_ray_dir = randf.onHemisphere(normal);
66+
new_ray_dir = std.mix(refl_dir, new_ray_dir, roughness);
67+
return std.normalize(new_ray_dir);
68+
});
9469

95-
let init_normal = estimateNormal(init_march_result.position, init_shape_ctx);
70+
const renderSubPixel = tgpu.fn(
71+
[d.vec2f],
72+
d.vec3f,
73+
)((coord) => {
74+
// doing the first march before each sub-sample, since the first march result is the same for all of them
9675

97-
var init_material: Material;
98-
worldMat(init_march_result.position, init_shape_ctx, &init_material);
76+
const init_shape_ctx = ShapeContext({
77+
rayPos: constructRayPos(),
78+
rayDir: constructRayDir(coord),
79+
rayDistance: 0,
80+
});
81+
const init_march_result = MarchResult();
9982

100-
if (init_material.emissive) {
101-
return min(init_material.albedo, ONES_3F);
102-
}
83+
march(init_shape_ctx, MarchParams.maxSteps.$, init_march_result);
10384

104-
var reflections: array<Reflection, MAX_REFL>;
85+
if (init_march_result.steps >= MarchParams.maxSteps.$) {
86+
return std.min(skyColor(init_shape_ctx.rayDir), d.vec3f(1));
87+
}
10588

106-
var acc = vec3f(0., 0., 0.);
107-
for (var sub = 0u; sub < SUB_SAMPLES; sub++) {
108-
var material: Material = init_material;
109-
var normal = init_normal;
89+
const init_normal = estimateNormal(
90+
init_march_result.position,
91+
init_shape_ctx,
92+
);
93+
const init_material = Material();
11094

111-
var emissive_color = vec3f(0., 0., 0.);
112-
var refl_count = 0u;
95+
worldMat(init_march_result.position, init_shape_ctx, init_material);
11396

114-
var shape_ctx: ShapeContext;
115-
shape_ctx.rayPos = init_march_result.position;
116-
shape_ctx.rayDir = init_shape_ctx.rayDir;
117-
shape_ctx.rayDistance = init_shape_ctx.rayDistance;
97+
if (init_material.emissive) {
98+
return std.min(init_material.albedo, d.vec3f(1));
99+
}
118100

119-
for (var refl = 0u; refl < MAX_REFL; refl++) {
120-
var roughness: f32 = 0.;
121-
shape_ctx.rayDir = reflect(
122-
shape_ctx.rayDir,
123-
normal,
124-
material.roughness,
125-
&roughness,
126-
);
127-
reflections[refl_count].color = material.albedo;
128-
reflections[refl_count].roughness = roughness;
129-
refl_count++;
101+
const reflections = ReflectionArray();
102+
103+
let acc = d.vec3f();
104+
for (let sub = d.u32(0); sub < SUB_SAMPLES; sub++) {
105+
const material = Material(init_material);
106+
107+
let normal = d.vec3f(init_normal);
108+
let emissive_color = d.vec3f();
109+
let refl_count = d.u32(0);
110+
111+
const shape_ctx = ShapeContext({
112+
rayPos: init_march_result.position,
113+
rayDir: init_shape_ctx.rayDir,
114+
rayDistance: init_shape_ctx.rayDistance,
115+
});
116+
117+
for (let refl = d.u32(0); refl < MAX_REFL; refl++) {
118+
const roughness = d.f32(0);
119+
shape_ctx.rayDir = reflect(
120+
shape_ctx.rayDir,
121+
normal,
122+
material.roughness,
123+
roughness,
124+
);
125+
reflections[refl_count].color = material.albedo;
126+
reflections[refl_count].roughness = roughness;
127+
refl_count++;
130128

131-
var march_result: MarchResult;
132-
march(&shape_ctx, MAX_STEPS, &march_result);
133-
shape_ctx.rayPos = march_result.position;
129+
const march_result = MarchResult();
130+
march(shape_ctx, MarchParams.maxSteps.$, march_result);
131+
shape_ctx.rayPos = march_result.position;
134132

135-
if (march_result.steps >= MAX_STEPS) {
136-
emissive_color = skyColor(shape_ctx.rayDir);
137-
break;
138-
}
133+
if (march_result.steps >= MarchParams.maxSteps.$) {
134+
emissive_color = skyColor(shape_ctx.rayDir);
135+
break;
136+
}
139137

140-
normal = estimateNormal(shape_ctx.rayPos, shape_ctx);
138+
normal = estimateNormal(shape_ctx.rayPos, shape_ctx);
141139

142-
worldMat(shape_ctx.rayPos, shape_ctx, &material);
140+
worldMat(shape_ctx.rayPos, shape_ctx, material);
143141

144-
if (material.emissive) {
145-
emissive_color = material.albedo;
146-
break;
147-
}
142+
if (material.emissive) {
143+
emissive_color = material.albedo;
144+
break;
148145
}
146+
}
149147

150-
var sub_acc = emissive_color;
151-
for (var i = i32(refl_count) - 1; i >= 0; i--) {
152-
let mat_color = reflections[i].color;
153-
let reflectivity = 1. - reflections[i].roughness;
154-
155-
sub_acc *= mix(mat_color, ONES_3F, max(0., min(reflectivity, 1.))); // absorb the ray color based on reflectivity
156-
}
148+
let sub_acc = d.vec3f(emissive_color);
149+
for (let i = d.i32(refl_count) - 1; i >= 0; i--) {
150+
const mat_color = d.vec3f(reflections[i].color);
151+
const reflectivity = 1 - reflections[i].roughness;
157152

158-
acc += sub_acc;
153+
sub_acc = sub_acc.mul(
154+
std.mix(mat_color, d.vec3f(1), std.max(0, std.min(reflectivity, 1))),
155+
); // absorb the ray color based on reflectivity
159156
}
160157

161-
// averaging
162-
acc /= f32(SUB_SAMPLES);
158+
acc = acc.add(sub_acc);
159+
}
163160

164-
// clipping
165-
acc = min(acc, ONES_3F);
161+
// averaging
162+
acc = acc.div(SUB_SAMPLES);
166163

167-
return acc;
168-
}`,
169-
)
170-
.$uses({
171-
SUB_SAMPLES,
172-
MAX_STEPS: MarchParams.maxSteps,
173-
MAX_REFL,
174-
ONES_3F,
175-
MarchResult,
176-
Material,
177-
Reflection,
178-
ShapeContext,
179-
constructRayPos,
180-
constructRayDir,
181-
estimateNormal,
182-
march,
183-
skyColor,
184-
worldMat,
185-
reflect,
186-
});
164+
// clipping
165+
acc = std.min(acc, d.vec3f(1));
166+
167+
return acc;
168+
});
187169

188170
const mainLayout = tgpu.bindGroupLayout({
189171
previousRender: { texture: 'unfilterable-float' },
@@ -194,14 +176,12 @@ const mainComputeFn = tgpu['~unstable'].computeFn({
194176
workgroupSize: [BlockSize, BlockSize],
195177
in: { gid: d.builtin.globalInvocationId },
196178
})((input) => {
179+
const preSeed = d.vec2f(input.gid.xy);
197180
randf.seed2(
198-
std.add(
199-
std.mul(d.vec2f(input.gid.xy), 0.1646936793),
200-
std.mul(getRandomSeedPrimer.value, 0.934534732),
201-
),
181+
preSeed.mul(0.1646936793).add(getRandomSeedPrimer.$ * 0.934534732),
202182
);
203183

204-
const prev_layers = getAccumulatedLayers.value;
184+
const prev_layers = getAccumulatedLayers.$;
205185
const prev_render = std.textureLoad(
206186
mainLayout.$.previousRender,
207187
input.gid.xy,
@@ -211,30 +191,24 @@ const mainComputeFn = tgpu['~unstable'].computeFn({
211191
let acc = d.vec3f(0, 0, 0);
212192
for (let sx = d.u32(0); sx < SUPER_SAMPLES; sx++) {
213193
for (let sy = d.u32(0); sy < SUPER_SAMPLES; sy++) {
214-
const offset = d.vec2f(
215-
(d.f32(sx) + 0.5) * ONE_OVER_SUPER_SAMPLES,
216-
(d.f32(sy) + 0.5) * ONE_OVER_SUPER_SAMPLES,
217-
);
194+
const offset = d.vec2f(sx, sy).add(0.5).mul(ONE_OVER_SUPER_SAMPLES);
218195

219-
acc = std.add(
220-
acc,
221-
renderSubPixel(std.add(d.vec2f(input.gid.xy), offset)),
222-
);
196+
acc = acc.add(renderSubPixel(d.vec2f(input.gid.xy).add(offset)));
223197
}
224198
}
225199

226-
acc = std.mul(acc, ONE_OVER_SUPER_SAMPLES * ONE_OVER_SUPER_SAMPLES);
200+
acc = acc.mul(ONE_OVER_SUPER_SAMPLES * ONE_OVER_SUPER_SAMPLES);
227201

228202
// applying gamma correction
229203
const gamma = 2.2;
230-
acc = std.pow(acc, d.vec3f(d.f32(1) / gamma));
204+
acc = std.pow(acc, d.vec3f(1 / gamma));
231205

232-
let new_render = d.vec4f(acc, 1.0);
206+
let new_render = d.vec4f(acc, 1);
233207
if (prev_layers > 0) {
234-
new_render = std.div(
235-
std.add(std.mul(prev_render, prev_layers), d.vec4f(acc, 1.0)),
236-
prev_layers + 1,
237-
);
208+
new_render = prev_render
209+
.mul(prev_layers)
210+
.add(d.vec4f(acc, 1.0))
211+
.div(prev_layers + 1);
238212
}
239213

240214
std.textureStore(mainLayout.$.mainOutput, input.gid.xy, new_render);
@@ -342,7 +316,6 @@ export function createSDFRenderer(options: SDFRendererOptions) {
342316

343317
const mainPipeline = root['~unstable']
344318
// filling slots
345-
.with(OutputFormat, 'rgba8unorm')
346319
.with(getRandomSeedPrimer, randomSeedPrimerBuffer.as('uniform'))
347320
.with(getAccumulatedLayers, layersBuffer.as('uniform'))
348321
.with(getCameraProps, camera.cameraBuffer.as('uniform'))
@@ -355,7 +328,6 @@ export function createSDFRenderer(options: SDFRendererOptions) {
355328

356329
const auxPipeline = root['~unstable']
357330
// filling slots
358-
.with(OutputFormat, 'rgba16float')
359331
.with(getCameraProps, camera.cameraBuffer.as('uniform'))
360332
.with(accessViewportSize, d.vec2f(auxPassSize[0], auxPassSize[1]))
361333
.with(MarchParams.sampleSdf, worldSdf)

apps/phoure-www/src/lib/GameEngine/wgslUtils/mathConstants.ts

Lines changed: 0 additions & 7 deletions
This file was deleted.

0 commit comments

Comments
 (0)