diff options
| author | Akshay Nair <phenax5@gmail.com> | 2026-09-10 00:12:15 +0530 |
|---|---|---|
| committer | Akshay Nair <phenax5@gmail.com> | 2026-09-10 00:12:18 +0530 |
| commit | 80fd0d3c61f315b83c1eeda40daef31af01ad798 (patch) | |
| tree | 6998720e619f23ef5029d5a755d04ad67cba3cf2 /src/main/resources/shaders/play_shader.cs | |
| parent | bd52960a3e7bf2ecf12ec73373cd556f37af698b (diff) | |
| download | art-playground-openrndr-80fd0d3c61f315b83c1eeda40daef31af01ad798.tar.gz art-playground-openrndr-80fd0d3c61f315b83c1eeda40daef31af01ad798.zip | |
Ray-march in play_shader
Diffstat (limited to 'src/main/resources/shaders/play_shader.cs')
| -rw-r--r-- | src/main/resources/shaders/play_shader.cs | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/src/main/resources/shaders/play_shader.cs b/src/main/resources/shaders/play_shader.cs new file mode 100644 index 0000000..d3cd4f5 --- /dev/null +++ b/src/main/resources/shaders/play_shader.cs @@ -0,0 +1,75 @@ +#version 430 +layout(local_size_x = 1, local_size_y = 1) in; + +uniform float seconds = 0; +layout(rgba8) uniform writeonly image2D outputImg; + +#define MAX_ITERATIONS 500 +#define MAX_DISTANCE 100.0 +#define SURF_DIST 0.01 + +float sdfCircle(in vec3 p, in vec3 origin, in float radius) { + return length(p - origin) - radius; +} + +float smin(float a, float b, float k) { + float h = clamp(0.5 + 0.5 * (b - a) / k, 0.0, 1.0); + return mix(b, a, h) - k * h * (1.0 - h); +} + +float scene(in vec3 p) { + float c1 = sdfCircle(p, vec3(0, 1, 2.4), 0.2); + float c2 = sdfCircle(p, vec3(-0.6, 1, 3), 0.3); + return min(c1, c2); +} + +float ray_march_scene(in vec3 ray_origin, in vec3 ray_direction) { + float dist = 0.; + for (int i = 0; i < MAX_ITERATIONS && dist < MAX_DISTANCE; i++) { + vec3 p = ray_origin + dist * ray_direction; + float gap = scene(p); + dist += gap; + if (gap <= SURF_DIST) + return dist; + } + return dist; +} + +vec3 surface_normal_scene(in vec3 p) { + vec2 inc = vec2(0.01, 0); + return normalize(vec3(scene(p + inc.xyy) - scene(p - inc.xyy), + scene(p + inc.yxy) - scene(p - inc.yxy), + scene(p + inc.yyx) - scene(p - inc.yyx))); +} + +void main() { + vec2 resolution = vec2(imageSize(outputImg).xy); + vec3 uv = vec3((gl_GlobalInvocationID.xy - resolution / 2.0) / resolution, 0); + float aspect_ratio = resolution.y / resolution.x; + uv /= vec3(aspect_ratio, 1, 1); + + vec3 camera_pos = vec3(0, 1, 0); + vec3 camera_direction = normalize(vec3(uv.x, uv.y, 1.)); + + vec3 light_pos = vec3(1, 2. * sin(seconds), 1); + + float depth = ray_march_scene(camera_pos, camera_direction); + vec3 p = camera_pos + camera_direction * depth; + vec3 normal = surface_normal_scene(p); + vec3 light_vec = normalize(light_pos - p); + + float contrast = dot(normal, light_vec); + contrast = clamp(contrast, 0.1, 1.); + + vec3 col = vec3(0.15); + if (depth < MAX_DISTANCE) { + float light_ray_dist = + ray_march_scene(p + 10. * normal * SURF_DIST, light_vec); + if (light_ray_dist < length(light_pos - p)) + contrast *= 0.3; + col = vec3(0, 1. - (depth / MAX_DISTANCE), 0.4); + col *= contrast; + } + + imageStore(outputImg, ivec2(gl_GlobalInvocationID.xy), vec4(col, 1.)); +} |
