summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/shaders/math/sdf_shapes.wgsl32
-rw-r--r--common/shaders/render/raymarching.wgsl4
-rw-r--r--workspaces/main/beat_test.track44
-rw-r--r--workspaces/main/pop_punk_drums.track2
-rw-r--r--workspaces/main/shaders/scene1.wgsl81
-rw-r--r--workspaces/main/workspace.cfg3
6 files changed, 116 insertions, 50 deletions
diff --git a/common/shaders/math/sdf_shapes.wgsl b/common/shaders/math/sdf_shapes.wgsl
index 64df4fc..4dcfdd6 100644
--- a/common/shaders/math/sdf_shapes.wgsl
+++ b/common/shaders/math/sdf_shapes.wgsl
@@ -23,34 +23,8 @@ fn sdBox2D(p: vec2<f32>, b: vec2<f32>) -> f32 {
return length(max(d, vec2<f32>(0.0))) + min(max(d.x, d.y), 0.0);
}
+// Approximate
fn sdEllipse(p: vec2<f32>, ab: vec2<f32>) -> f32 {
- var p_abs = abs(p);
- if (p_abs.x > p_abs.y) {
- p_abs = vec2<f32>(p_abs.y, p_abs.x);
- }
- let l = ab.y * ab.y - ab.x * ab.x;
- let m = ab.x * p_abs.x / l;
- let n = ab.y * p_abs.y / l;
- let m2 = m * m;
- let n2 = n * n;
- let c = (m2 + n2 - 1.0) / 3.0;
- let c3 = c * c * c;
- let d = c3 + m2 * n2;
- let g = m + m * n2;
- var co: f32;
- if (d < 0.0) {
- let h = acos((c3 + m2 * n2 * 2.0) / c3) / 3.0;
- let s = cos(h);
- let t = sin(h) * sqrt(3.0);
- co = (sqrt(-c * (s + t * 2.0) + m2) + sign(l) * sqrt(-c * (s - t * 2.0) + m2) + abs(g) / (sqrt(-c * (s + t * 2.0) + m2) * sqrt(-c * (s - t * 2.0) + m2)) - m) / 2.0;
- } else {
- let h = 2.0 * m * n * sqrt(d);
- let s = sign(c3 + m2 * n2 + h) * pow(abs(c3 + m2 * n2 + h), 1.0 / 3.0);
- let u = sign(c3 + m2 * n2 - h) * pow(abs(c3 + m2 * n2 - h), 1.0 / 3.0);
- let rx = -s - u + m2 * 2.0;
- let ry = (s - u) * sqrt(3.0);
- co = (ry / sqrt(sqrt(rx * rx + ry * ry) - rx) + 2.0 * g / sqrt(rx * rx + ry * ry) - m) / 2.0;
- }
- let si = sqrt(max(0.0, 1.0 - co * co));
- return length(p_abs - vec2<f32>(ab.x * co, ab.y * si)) * sign(p_abs.y * ab.x * co - p_abs.x * ab.y * si);
+ let d = length(p / ab);
+ return length(p) * (1.0 - 1.0 / d);
}
diff --git a/common/shaders/render/raymarching.wgsl b/common/shaders/render/raymarching.wgsl
index 3adec8d..7d05528 100644
--- a/common/shaders/render/raymarching.wgsl
+++ b/common/shaders/render/raymarching.wgsl
@@ -26,8 +26,8 @@ fn normal(pos: vec3<f32>) -> vec3<f32> {
// Performs the raymarching operation.
// Returns the distance along the ray to the surface, or MAX_RAY_LENGTH if no surface is hit.
-fn rayMarch(ro: vec3<f32>, rd: vec3<f32>, initt: f32) -> f32 {
- var t = initt;
+fn rayMarch(ro: vec3<f32>, rd: vec3<f32>, tmin: f32) -> f32 {
+ var t = tmin;
for (var i = 0; i < MAX_RAY_MARCHES; i++) {
if (t > MAX_RAY_LENGTH) {
t = MAX_RAY_LENGTH;
diff --git a/workspaces/main/beat_test.track b/workspaces/main/beat_test.track
new file mode 100644
index 0000000..1b7f9b1
--- /dev/null
+++ b/workspaces/main/beat_test.track
@@ -0,0 +1,44 @@
+# Pop-Punk High-Energy Drum Track
+# Converted from track.md drum sequence
+# 4/4 time signature, 16th note resolution
+
+BPM 90
+
+# Drum samples (General MIDI mapping)
+SAMPLE ASSET_KICK_1
+SAMPLE ASSET_SNARE_1
+
+# Pattern A: Main Driving Groove (bars 1-3)
+# 1 unit = 4 beats, 16th notes = 0.0625 units apart
+PATTERN main_groove LENGTH 1.0
+ # Snare: beats 2 and 4 (strong)
+ 0.2500, ASSET_SNARE_1, 1.0, 0.0
+ 0.7500, ASSET_SNARE_1, 1.0, 0.0
+ # Kick: syncopated pattern (galloping)
+ 0.0000, ASSET_KICK_1, 1.0, 0.0
+ 0.5000, ASSET_KICK_1, 1.0, 0.0
+ # Crash on beat 1
+ 0.0000, ASSET_CRASH_1, 0.9, 0.0
+
+
+# Score
+SCORE
+ 0.0, main_groove_crash
+ 1.0, main_groove_crash
+ 2.0, main_groove_crash
+ 3.0, main_groove_crash
+
+ 4.0, main_groove_crash
+ 5.0, main_groove_crash
+ 6.0, main_groove_crash
+ 7.0, main_groove_crash
+
+ 8.0, main_groove_crash
+ 9.0, main_groove_crash
+ 10.0, main_groove_crash
+ 11.0, main_groove_crash
+
+ 12.0, main_groove_crash
+ 13.0, main_groove_crash
+ 14.0, main_groove_crash
+ 15.0, main_groove_crash
diff --git a/workspaces/main/pop_punk_drums.track b/workspaces/main/pop_punk_drums.track
index f54bf9d..236b79f 100644
--- a/workspaces/main/pop_punk_drums.track
+++ b/workspaces/main/pop_punk_drums.track
@@ -1,6 +1,6 @@
# Pop-Punk High-Energy Drum Track
# Converted from track.md drum sequence
-# 165 BPM, 4/4 time signature, 16th note resolution
+# 4/4 time signature, 16th note resolution
BPM 90
diff --git a/workspaces/main/shaders/scene1.wgsl b/workspaces/main/shaders/scene1.wgsl
index 2723b66..8d5d5db 100644
--- a/workspaces/main/shaders/scene1.wgsl
+++ b/workspaces/main/shaders/scene1.wgsl
@@ -50,19 +50,22 @@ fn render0(ro: vec3<f32>, rd: vec3<f32>) -> vec3<f32> {
return clamp(col, vec3<f32>(0.0), vec3<f32>(10.0));
}
+const OBJ_BACKGROUND: f32 = 0.0;
+const OBJ_CUBE: f32 = 1.0;
+const OBJ_SPHERE: f32 = 2.0;
+const OBJ_PLANE: f32 = 3.0;
+
fn df(p_in: vec3<f32>) -> f32 {
var p = p_in;
p.x = p_in.x * g_rot0[0][0] + p_in.z * g_rot0[0][1];
p.z = p_in.x * g_rot0[1][0] + p_in.z * g_rot0[1][1];
// Cube
- var pc = p;
- pc -= vec3<f32>(-1.9, 0.0, 0.0);
+ var pc = p - vec3<f32>(-1.9, 0.0, 0.0);
let dCube = sdBox(pc, vec3<f32>(1.6));
// Sphere
- var ps = p;
- ps -= vec3<f32>(1.3, 0.0, 0.0);
+ var ps = p - vec3<f32>(1.3, 0.0, 0.0);
let dSphere = sdSphere(ps, 1.2);
// Ground plane
@@ -75,6 +78,41 @@ fn df(p_in: vec3<f32>) -> f32 {
return d;
}
+fn dfWithID(p_in: vec3<f32>) -> RayMarchResult {
+ var p = p_in;
+ p.x = p_in.x * g_rot0[0][0] + p_in.z * g_rot0[0][1];
+ p.z = p_in.x * g_rot0[1][0] + p_in.z * g_rot0[1][1];
+
+ // Cube
+ var pc = p - vec3<f32>(-1.9, 0.0, 0.0);
+ let dCube = sdBox(pc, vec3<f32>(1.6));
+
+ // Sphere
+ var ps = p - vec3<f32>(1.3, 0.0, 0.0);
+ let dSphere = sdSphere(ps, 1.2);
+
+ // Ground plane
+ let dPlane = p.y + 1.0;
+
+ // Find closest object
+ var result: RayMarchResult;
+ result.distance = dCube;
+ result.object_id = OBJ_CUBE;
+
+ if (dSphere < result.distance) {
+ result.distance = dSphere;
+ result.object_id = OBJ_SPHERE;
+ }
+
+ if (dPlane < result.distance) {
+ result.distance = dPlane;
+ result.object_id = OBJ_PLANE;
+ }
+
+ result.distance_max = result.distance;
+ return result;
+}
+
fn boxCol(col: vec3<f32>, nsp: vec3<f32>, rd: vec3<f32>, nnor: vec3<f32>, nrcol: vec3<f32>, nshd1: f32, nshd2: f32) -> vec3<f32> {
var nfre = 1.0 + dot(rd, nnor);
nfre *= nfre;
@@ -102,24 +140,35 @@ fn render1(ro: vec3<f32>, rd: vec3<f32>) -> vec3<f32> {
let skyCol_local = render0(ro, rd);
var col = skyCol_local;
- let nt = rayMarch(ro, rd, 0.0);
- if (nt < MAX_RAY_LENGTH) {
- let nsp = ro + rd * nt;
- let nnor = normal(nsp);
+ var init: RayMarchResult;
+ init.distance = 0.0;
+ init.distance_max = 0.0;
+ init.object_id = OBJ_BACKGROUND;
+
+ let result = rayMarchWithID(ro, rd, init);
+ if (result.distance < MAX_RAY_LENGTH) {
+ let nsp = reconstructPosition(ro, rd, result);
+ let nnor = normalWithID(nsp);
let nref = reflect(rd, nnor);
- let nrt = rayMarch(nsp, nref, 0.2);
+ var refl_init: RayMarchResult;
+ refl_init.distance = 0.2;
+ refl_init.distance_max = 0.2;
+ refl_init.object_id = OBJ_BACKGROUND;
+ let nrt_result = rayMarchWithID(nsp, nref, refl_init);
var nrcol = render0(nsp, nref);
- if (nrt < MAX_RAY_LENGTH) {
- let nrsp = nsp + nref * nrt;
- let nrnor = normal(nrsp);
+ if (nrt_result.distance < MAX_RAY_LENGTH) {
+ let nrsp = reconstructPosition(nsp, nref, nrt_result);
+ let nrnor = normalWithID(nrsp);
let nrref = reflect(nref, nrnor);
nrcol = boxCol(nrcol, nrsp, nref, nrnor, render0(nrsp, nrref), 1.0, 1.0);
}
- let nshd1 = mix(0.0, 1.0, shadow(nsp, normalize(lightPos1 - nsp), 0.1, distance(lightPos1, nsp)));
- let nshd2 = mix(0.0, 1.0, shadow(nsp, normalize(lightPos2 - nsp), 0.1, distance(lightPos2, nsp)));
+ let light_dist1 = distance(lightPos1, nsp);
+ let light_dist2 = distance(lightPos2, nsp);
+ let nshd1 = mix(0.0, 1.0, shadowWithStoredDistance(nsp, normalize(lightPos1 - nsp), light_dist1));
+ let nshd2 = mix(0.0, 1.0, shadowWithStoredDistance(nsp, normalize(lightPos2 - nsp), light_dist2));
col = boxCol(col, nsp, rd, nnor, nrcol, nshd1, nshd2);
}
@@ -146,9 +195,7 @@ fn effect(p: vec2<f32>) -> vec3<f32> {
#include "render/fullscreen_vs"
@fragment fn fs_main(@builtin(position) p: vec4<f32>) -> @location(0) vec4<f32> {
- // Flip Y to match ShaderToy convention (origin at bottom-left)
- let flipped = vec2<f32>(p.x, uniforms.resolution.y - p.y);
- let q = flipped / uniforms.resolution;
+ let q = p.xy / uniforms.resolution;
var coord = -1.0 + 2.0 * q;
coord.x *= uniforms.resolution.x / uniforms.resolution.y;
var col = effect(coord);
diff --git a/workspaces/main/workspace.cfg b/workspaces/main/workspace.cfg
index 1c2f4c0..5eff423 100644
--- a/workspaces/main/workspace.cfg
+++ b/workspaces/main/workspace.cfg
@@ -6,7 +6,8 @@ version = "1.0"
[build]
target = "demo64k"
timeline = "timeline.seq"
-music = "pop_punk_drums.track"
+# music = "pop_punk_drums.track"
+music = "beat_test.track"
assets = "assets.txt"
asset_dirs = ["music/", "weights/", "obj/"]
shader_dirs = ["shaders/"]