From c84861692826efa9f3cfdb78608c758737b47b04 Mon Sep 17 00:00:00 2001 From: ktyl Date: Sun, 8 Aug 2021 16:47:25 +0100 Subject: [PATCH] add plane and some randomness --- shader/root/rt.glsl | 50 ++++++++++++++++++++++++++++++++++------- src/cam.h | 2 +- src/{time.c => clock.c} | 2 +- src/{time.h => clock.h} | 0 src/main.c | 14 +++++++++++- src/random.c | 11 +++++++++ src/random.h | 7 ++++++ src/sphere.c | 2 +- src/sphere.h | 2 +- 9 files changed, 77 insertions(+), 13 deletions(-) rename src/{time.c => clock.c} (76%) rename src/{time.h => clock.h} (100%) create mode 100644 src/random.c create mode 100644 src/random.h diff --git a/shader/root/rt.glsl b/shader/root/rt.glsl index eef8b62..67aa379 100644 --- a/shader/root/rt.glsl +++ b/shader/root/rt.glsl @@ -20,12 +20,12 @@ const int SPHERES = 250; // 253 is the maximum?? TODO: use uniform buffer object layout (location = 12) uniform int _activeSpheres; layout (location = 13) uniform Sphere _spheres[SPHERES]; -uniform float _seed; +uniform vec4 _seed; layout(local_size_x = 1, local_size_y = 1) in; // size of local work group - 1 pixel layout(rgba32f, binding = 0) uniform image2D img_output; // rgba32f defines internal format, image2d for random write to output texture -const float INF = 30.0; +const float INF = 1000.0; const float PI = 3.14159; struct Ray @@ -80,12 +80,30 @@ void intersectSphere(Ray ray, inout RayHit bestHit, Sphere sphere) if (t > 0 && t < bestHit.distance) { bestHit.distance = t; - bestHit.position = ray.origin + t*ray.direction; + bestHit.position = ray.origin + t * ray.direction; bestHit.normal = normalize(bestHit.position-c); bestHit.albedo = sphere.albedo; } } +void intersectPlane(Ray ray, inout RayHit bestHit, vec3 p, vec3 normal) +{ + //normal = vec3(0.0,0.0,1.0); + float denom = dot(normal, ray.direction); + + if (abs(denom) > 0.0001) + { + float t = dot(p-ray.origin, normal) / denom; + if (t >= 0 && t < bestHit.distance) + { + bestHit.distance = t; + bestHit.position = ray.origin + t*ray.direction; + bestHit.normal = normal; + bestHit.albedo = vec3(1.0,1.0,1.0); + } + } +} + Ray createCameraRay(vec2 uv) { // transform -1..1 -> 0..1 @@ -110,16 +128,29 @@ RayHit trace(Ray ray) // TODO: intersect something other than spheres + Sphere s; + s.cr = vec4(0.0,0.0,0.0,2.0); + s.albedo = vec3(1.0,0.0,0.0); + + intersectPlane(ray, hit, vec3(0.0,-1.5,0.0),vec3(0.0,1.0,0.0)); + for (int i = 0; i < _activeSpheres; i++) { intersectSphere(ray, hit, _spheres[i]); } + //intersectSphere(ray, hit, s); + return hit; } float random(vec2 st) { + st += gl_GlobalInvocationID.xy; + st += _seed.xy; + st += _seed.zw; + normalize(st); + return fract(sin(dot(st.xy,vec2(12.9898,78.233)))*43758.5453123); } @@ -144,10 +175,11 @@ vec3 sampleHemisphere(vec3 normal) { float cosTheta = random(normal.xy); float sinTheta = sqrt(max(0.0,1.0-cosTheta*cosTheta)); - float phi = 2.0*PI*random(vec2(cosTheta,sinTheta)); + + float phi = 2.0*PI*random(normal.yx); vec3 tangentSpaceDir = vec3(cos(phi)*sinTheta, sin(phi)*sinTheta, cosTheta); - // TODO: this lookin sketch af rn + // convert direction from tangent space to world space mat3 ts = getTangentSpace(normal); return ts* tangentSpaceDir; } @@ -186,8 +218,8 @@ void main() uv.x = (float(pixel_coords.x * 2 - dims.x) / dims.x) * dims.x/dims.y; // account for aspect ratio uv.y = (float(pixel_coords.y * 2 - dims.y) / dims.y); - int samples = 1; - int bounces = 2; + int samples = 2; + int bounces = 3; for (int i = 0; i < samples; i++) { @@ -200,10 +232,12 @@ void main() RayHit hit = trace(ray); pixel.xyz += ray.energy * shade(ray, hit); + + if (length(ray.energy) < 0.001) break; } } - pixel /= samples; + pixel.xyz /= samples; // TODO: write depth to texture //float depth = hit.distance/INF; diff --git a/src/cam.h b/src/cam.h index 7298001..4004a75 100644 --- a/src/cam.h +++ b/src/cam.h @@ -4,6 +4,6 @@ #include -#include "time.h" +#include "clock.h" void updateCameraUniforms(GLuint shaderProgram, float aspect); diff --git a/src/time.c b/src/clock.c similarity index 76% rename from src/time.c rename to src/clock.c index f08b2a7..00c36b3 100644 --- a/src/time.c +++ b/src/clock.c @@ -1,4 +1,4 @@ -#include "time.h" +#include "clock.h" float now() { diff --git a/src/time.h b/src/clock.h similarity index 100% rename from src/time.h rename to src/clock.h diff --git a/src/main.c b/src/main.c index c03de1d..9a415c9 100644 --- a/src/main.c +++ b/src/main.c @@ -1,6 +1,7 @@ #include "main.h" #include "gfx.h" -#include "time.h" +#include "clock.h" +#include "random.h" #include "sphere.h" #include "cam.h" @@ -59,6 +60,17 @@ int main() void updateUniforms(GLuint shaderProgram) { + // update random values + vec4 seed = + { + randomFloat(), + randomFloat(), + randomFloat(), + randomFloat() + }; + int loc = glGetUniformLocation(shaderProgram, "_seed"); + glUniform4fv(loc, 1, seed); + float t = now(); float sin_t = sin(t); int tLocation = glGetUniformLocation(shaderProgram, "_t"); diff --git a/src/random.c b/src/random.c new file mode 100644 index 0000000..4fb608f --- /dev/null +++ b/src/random.c @@ -0,0 +1,11 @@ +#include "random.h" + +void randomInit() +{ + srand(time(NULL)); +} + +float randomFloat() +{ + return (float)rand()/(float)RAND_MAX; +} diff --git a/src/random.h b/src/random.h new file mode 100644 index 0000000..9ef7ae3 --- /dev/null +++ b/src/random.h @@ -0,0 +1,7 @@ +#pragma once + +#include +#include + +void randomInit(); +float randomFloat(); diff --git a/src/sphere.c b/src/sphere.c index df97fb1..c2fd193 100644 --- a/src/sphere.c +++ b/src/sphere.c @@ -26,7 +26,7 @@ void makeSpheres(struct Sphere *spheres, int count) { x = 2.0*CGLM_PI * (float)i/(float)count; sc[0] = sin(x)*d; - sc[1] = sin(x*3.0-2.5*sin(t)); + sc[1] = sin(x*3.0-t); sc[2] = cos(x)*d; float ic = i/(float)count*CGLM_PI*2.0; diff --git a/src/sphere.h b/src/sphere.h index 2759c42..1c8f19d 100644 --- a/src/sphere.h +++ b/src/sphere.h @@ -7,7 +7,7 @@ #include -#include "time.h" +#include "clock.h" struct Sphere {