diff options
Diffstat (limited to 'workspaces/main/shaders/scene1.wgsl')
| -rw-r--r-- | workspaces/main/shaders/scene1.wgsl | 81 |
1 files changed, 64 insertions, 17 deletions
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); |
