summaryrefslogtreecommitdiff
path: root/workspaces
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-02-14 19:05:34 +0100
committerskal <pascal.massimino@gmail.com>2026-02-14 19:05:34 +0100
commitb8d4a815453acac752c6fb3c56d047e39a76fd05 (patch)
treee8b49ac34aed2b5cfbdbdc4a4c99903fbd709cef /workspaces
parent57aeae226617dbce364716f2d4e7c4aaa6271c1d (diff)
feat(gpu): add SDF camera infrastructure and effect base class
Add unified camera system for SDF raymarching effects: - CameraParams struct (80 bytes): inv_view matrix + FOV/near/far/aspect - SDFEffect base class: manages camera uniform, provides update_camera() helpers - camera_common.wgsl: getCameraRay(), position/forward/up/right extractors - SDFTestEffect: working example with orbiting camera + animated sphere Refactor effect headers: - Extract class definitions from demo_effects.h to individual .h files - Update includes in .cc files to use specific headers - Cleaner compilation dependencies, faster incremental builds Documentation: - Add SDF_EFFECT_GUIDE.md with complete workflow - Update ARCHITECTURE.md, UNIFORM_BUFFER_GUIDELINES.md - Update EFFECT_WORKFLOW.md, CONTRIBUTING.md Tests: 34/34 passing, SDFTestEffect validated Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Diffstat (limited to 'workspaces')
-rw-r--r--workspaces/main/assets.txt2
-rw-r--r--workspaces/main/shaders/sdf_test.wgsl68
2 files changed, 70 insertions, 0 deletions
diff --git a/workspaces/main/assets.txt b/workspaces/main/assets.txt
index 0b64ba9..972cc8b 100644
--- a/workspaces/main/assets.txt
+++ b/workspaces/main/assets.txt
@@ -25,6 +25,7 @@ NOISE_TEX, PROC(gen_noise, 1234, 16), _, "Procedural noise texture for bump mapp
# --- WGSL Shaders & Snippets ---
SHADER_RENDERER_3D, NONE, shaders/renderer_3d.wgsl, "Hybrid 3D Renderer Shader"
SHADER_COMMON_UNIFORMS, NONE, ../../common/shaders/common_uniforms.wgsl, "Common Uniforms Snippet"
+SHADER_CAMERA_COMMON, NONE, ../../common/shaders/camera_common.wgsl, "Camera parameters and raymarching helpers"
SHADER_SDF_SHAPES, NONE, ../../common/shaders/math/sdf_shapes.wgsl, "SDF Shapes (2D/3D primitives)"
SHADER_LIGHTING, NONE, ../../common/shaders/lighting.wgsl, "Lighting Snippet"
SHADER_RAY_BOX, NONE, ../../common/shaders/ray_box.wgsl, "Ray-Box Intersection Snippet"
@@ -50,6 +51,7 @@ SHADER_SOLARIZE, NONE, shaders/solarize.wgsl, "Solarize Shader"
SHADER_DISTORT, NONE, shaders/distort.wgsl, "Distort Shader"
SHADER_CHROMA_ABERRATION, NONE, shaders/chroma_aberration.wgsl, "Chroma Aberration Shader"
SHADER_VISUAL_DEBUG, NONE, shaders/visual_debug.wgsl, "Visual Debug Shader"
+SHADER_SDF_TEST, NONE, shaders/sdf_test.wgsl, "SDF test effect demonstrating SDFEffect base class"
SHADER_SKYBOX, NONE, ../../common/shaders/skybox.wgsl, "Skybox background shader"
SHADER_MATH_SDF_SHAPES, NONE, ../../common/shaders/math/sdf_shapes.wgsl, "SDF Shapes Snippet"
SHADER_MATH_SDF_UTILS, NONE, ../../common/shaders/math/sdf_utils.wgsl, "SDF Utils Snippet"
diff --git a/workspaces/main/shaders/sdf_test.wgsl b/workspaces/main/shaders/sdf_test.wgsl
new file mode 100644
index 0000000..3c97613
--- /dev/null
+++ b/workspaces/main/shaders/sdf_test.wgsl
@@ -0,0 +1,68 @@
+// SDF Test Effect - demonstrates SDFEffect base class usage
+// Simple scene with a sphere and box
+
+#include "common_uniforms"
+#include "camera_common"
+#include "math/sdf_shapes"
+#include "render/raymarching"
+
+@group(0) @binding(0) var<uniform> uniforms: CommonUniforms;
+@group(0) @binding(1) var<uniform> camera: CameraParams;
+
+// Scene distance function
+fn df(p: vec3<f32>) -> f32 {
+ // Animated sphere
+ let sphere_pos = vec3<f32>(sin(uniforms.beat_time * 0.5) * 2.0, 0.0, 0.0);
+ let d_sphere = sdSphere(p - sphere_pos, 1.0);
+
+ // Static box
+ let box_pos = vec3<f32>(0.0, -2.0, 0.0);
+ let d_box = sdBox(p - box_pos, vec3<f32>(3.0, 0.5, 3.0));
+
+ return min(d_sphere, d_box);
+}
+
+// Simple lighting
+fn shade(pos: vec3<f32>, rd: vec3<f32>) -> vec3<f32> {
+ let n = normal(pos);
+ let light_dir = normalize(vec3<f32>(1.0, 1.0, -1.0));
+ let diff = max(dot(n, light_dir), 0.0);
+ let amb = 0.2;
+
+ // Color based on position
+ let col = mix(vec3<f32>(0.2, 0.6, 0.9), vec3<f32>(0.9, 0.3, 0.2),
+ smoothstep(-2.0, 2.0, pos.x));
+
+ return col * (diff + amb);
+}
+
+@vertex
+fn vs_main(@builtin(vertex_index) vid: u32) -> @builtin(position) vec4<f32> {
+ // Fullscreen triangle
+ let x = f32((vid & 1u) << 2u) - 1.0;
+ let y = f32((vid & 2u) << 1u) - 1.0;
+ return vec4<f32>(x, y, 0.0, 1.0);
+}
+
+@fragment
+fn fs_main(@builtin(position) pos: vec4<f32>) -> @location(0) vec4<f32> {
+ // UV coordinates (-1 to 1)
+ let uv = (pos.xy / uniforms.resolution - 0.5) * 2.0;
+
+ // Generate ray
+ let ray = getCameraRay(camera, uv);
+
+ // Raymarch
+ let t = rayMarch(ray.origin, ray.direction, 0.0);
+
+ // Background color
+ var col = vec3<f32>(0.1, 0.1, 0.15);
+
+ // Shade hit point
+ if (t < MAX_RAY_LENGTH) {
+ let hit_pos = ray.origin + ray.direction * t;
+ col = shade(hit_pos, ray.direction);
+ }
+
+ return vec4<f32>(col, 1.0);
+}