diff options
| author | skal <pascal.massimino@gmail.com> | 2026-02-14 19:05:34 +0100 |
|---|---|---|
| committer | skal <pascal.massimino@gmail.com> | 2026-02-14 19:05:34 +0100 |
| commit | b8d4a815453acac752c6fb3c56d047e39a76fd05 (patch) | |
| tree | e8b49ac34aed2b5cfbdbdc4a4c99903fbd709cef /workspaces/main | |
| parent | 57aeae226617dbce364716f2d4e7c4aaa6271c1d (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/main')
| -rw-r--r-- | workspaces/main/assets.txt | 2 | ||||
| -rw-r--r-- | workspaces/main/shaders/sdf_test.wgsl | 68 |
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); +} |
