diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/effects/shaders.cc | 1 | ||||
| -rw-r--r-- | src/shaders/ray_sphere.wgsl | 21 |
2 files changed, 22 insertions, 0 deletions
diff --git a/src/effects/shaders.cc b/src/effects/shaders.cc index a6c1b64..8b625ee 100644 --- a/src/effects/shaders.cc +++ b/src/effects/shaders.cc @@ -51,6 +51,7 @@ void InitShaderComposer() { register_if_exists("ray_box", AssetId::ASSET_SHADER_RAY_BOX); register_if_exists("ray_triangle", AssetId::ASSET_SHADER_RAY_TRIANGLE); + register_if_exists("ray_sphere", AssetId::ASSET_SHADER_RAY_SPHERE); register_if_exists("debug/debug_print", AssetId::ASSET_SHADER_DEBUG_DEBUG_PRINT); diff --git a/src/shaders/ray_sphere.wgsl b/src/shaders/ray_sphere.wgsl new file mode 100644 index 0000000..659e144 --- /dev/null +++ b/src/shaders/ray_sphere.wgsl @@ -0,0 +1,21 @@ +// Ray-sphere intersection. +// ro: ray origin, rd: ray direction (must be normalized). +// center: sphere center, radius: sphere radius. +// Returns t of the nearest positive intersection, or -1.0 if no hit. + +struct RaySphereHit { + t: f32, // distance along ray to nearest hit (negative = miss) + hit: bool, +}; + +fn ray_sphere_intersection(ro: vec3f, rd: vec3f, + center: vec3f, radius: f32) -> RaySphereHit { + let oc = ro - center; + let b = dot(oc, rd); + let c = dot(oc, oc) - radius * radius; + let disc = b * b - c; + if (disc < 0.0) { return RaySphereHit(-1.0, false); } + let t = -b - sqrt(disc); + if (t < 0.0) { return RaySphereHit(-1.0, false); } + return RaySphereHit(t, true); +} |
