From 8f256e5c35ef52808f296eadc2714e2ff9f3ef03 Mon Sep 17 00:00:00 2001 From: TheRedShip Date: Sat, 4 Jan 2025 18:14:24 +0100 Subject: [PATCH] + | Better random --- includes/RT/Object.hpp | 2 +- includes/RT/Scene.hpp | 2 +- scenes/cornell.rt | 6 +++--- scenes/roughness.rt | 21 +++++++++++++++++++ shaders/compute.glsl | 41 +++++++++++++++++++++----------------- shaders/random.glsl | 29 +++++++++++++++++++++++++++ srcs/class/Scene.cpp | 4 ++-- srcs/class/SceneParser.cpp | 6 +++--- 8 files changed, 83 insertions(+), 28 deletions(-) create mode 100644 scenes/roughness.rt diff --git a/includes/RT/Object.hpp b/includes/RT/Object.hpp index 5b71f31..ebad6b5 100644 --- a/includes/RT/Object.hpp +++ b/includes/RT/Object.hpp @@ -20,7 +20,7 @@ typedef struct s_Material glm::vec3 color; float emission; float roughness; - float specular; + float metallic; } Material; class Object diff --git a/includes/RT/Scene.hpp b/includes/RT/Scene.hpp index e7d47fa..155c9bc 100644 --- a/includes/RT/Scene.hpp +++ b/includes/RT/Scene.hpp @@ -22,7 +22,7 @@ struct GPUObject alignas(16) glm::vec3 color; float emission; float roughness; - float specular; + float metallic; float radius; // sphere alignas(16) glm::vec3 normal; // plane diff --git a/scenes/cornell.rt b/scenes/cornell.rt index e51f5b3..34db2e7 100644 --- a/scenes/cornell.rt +++ b/scenes/cornell.rt @@ -1,12 +1,12 @@ MAT 255 255 255 0.0 0.0 0.0 -MAT 255 255 255 5.0 0.0 0.0 +MAT 255 255 255 3.0 0.0 0.0 MAT 255 100 100 0.0 0.0 0.0 MAT 100 100 255 0.0 0.0 0.0 -MAT 100 255 100 0.0 0.0 0.0 +MAT 100 255 100 0.0 0.5 0.0 -MAT 255 255 255 0.0 0.98 0.0 +MAT 255 255 255 0.0 1.0 0.0 sp 0 -1 0 1 5 diff --git a/scenes/roughness.rt b/scenes/roughness.rt new file mode 100644 index 0000000..77e5240 --- /dev/null +++ b/scenes/roughness.rt @@ -0,0 +1,21 @@ + + +MAT 255 255 255 5.0 0.0 0.0 // white light 0 + +MAT 255 50 50 0.0 0.0 0.0 // red 1 +MAT 50 50 50 0.0 0.0 0.0 // gray 2 +MAT 50 255 50 0.0 0.0 0.0 // green 3 +MAT 255 255 255 0.0 0.0 0.0 // white 4 + +// walls of a long width box + +pl 0 0 -3 0 0 1 4 // back wall +pl 0 0 3 0 0 -1 4 // front wall +pl 4 0 0 -1 0 0 3 // right wall +pl -4 0 0 1 0 0 1 // left wall +pl 0 3 0 0 -1 0 2 // ceiling +pl 0 -3 0 0 1 0 4 // floor + +// light quad +qu -1 2.9 -1 2 0 0 0 0 2 0 + diff --git a/shaders/compute.glsl b/shaders/compute.glsl index 4bfa9f5..35ed334 100644 --- a/shaders/compute.glsl +++ b/shaders/compute.glsl @@ -10,7 +10,7 @@ struct GPUObject { vec3 color; // 12 + 4 float emission; // 4 float roughness; // 4 - float specular; // 4 + float metallic; // 4 float radius; // 4 vec3 normal; // 12 + 4 @@ -73,24 +73,27 @@ hitInfo traceRay(Ray ray) return (hit); } -Ray newRay(hitInfo hit, Ray ray, vec2 uv) +Ray newRay(hitInfo hit, Ray ray, inout uint rng_state) { - Ray new_ray; - vec3 in_unit_sphere; + GPUObject obj; + Ray new_ray; + // vec3 in_unit_sphere; - in_unit_sphere = normalize(randomVec3(uv, u_time)); - in_unit_sphere *= sign(dot(in_unit_sphere, hit.normal)); + obj = objects[hit.obj_index]; + + // in_unit_sphere = normalize(randomVec3(uv, u_time)); + // in_unit_sphere *= sign(dot(in_unit_sphere, hit.normal)); - vec3 diffuse_dir = normalize(hit.normal + in_unit_sphere); + vec3 diffuse_dir = normalize(randomHemisphereDirection(hit.normal, rng_state)); vec3 specular_dir = reflect(ray.direction, hit.normal); - + new_ray.origin = hit.position + hit.normal * 0.001; - new_ray.direction = mix(diffuse_dir, specular_dir, objects[hit.obj_index].roughness); + new_ray.direction = mix(diffuse_dir, specular_dir, obj.roughness); return (new_ray); } -vec3 pathtrace(Ray ray, vec2 uv) +vec3 pathtrace(Ray ray, inout uint rng_state) { vec3 color = vec3(1.0); vec3 light = vec3(0.0); @@ -109,13 +112,12 @@ vec3 pathtrace(Ray ray, vec2 uv) GPUObject obj = objects[hit.obj_index]; color *= obj.color; - if (obj.emission > 0.0) - { - light += obj.emission * obj.color; - break; - } - ray = newRay(hit, ray, uv); + light += obj.emission * obj.color; + if (obj.emission > 0.0) + break; + + ray = newRay(hit, ray, rng_state); } return (color * light); } @@ -128,6 +130,9 @@ void main() vec2 uv = (vec2(pixel_coords) / u_resolution) * 2.0 - 1.0;; uv.x *= u_resolution.x / u_resolution.y; + + uint rng_state = uint(u_resolution.x) * uint(pixel_coords.y) + pixel_coords.x; + rng_state = rng_state + u_frameCount * 719393; float fov = 90.0; float focal_length = 1.0 / tan(radians(fov) / 2.0); @@ -136,8 +141,8 @@ void main() vec3 ray_direction = normalize((inverse(u_viewMatrix) * vec4(view_space_ray, 0.0)).xyz); Ray ray = Ray(u_cameraPosition, ray_direction); - vec3 color = pathtrace(ray, uv); - color = vec3(sqrt(color.x), sqrt(color.y), sqrt(color.z)); + vec3 color = pathtrace(ray, rng_state); + // color = vec3(sqrt(color.x), sqrt(color.y), sqrt(color.z)); float blend = 1.0 / float(u_frameCount + 1); vec4 accum = imageLoad(accumulation_image, pixel_coords); diff --git a/shaders/random.glsl b/shaders/random.glsl index db409f2..039f98d 100644 --- a/shaders/random.glsl +++ b/shaders/random.glsl @@ -42,3 +42,32 @@ vec3 randomVec3(vec2 uv, float time) { return (vec3((random(uv, time) - 0.5) * 2, (random(uv, time) - 0.5) * 2, (random(uv, time) - 0.5) * 2)); } + +float randomValue(inout uint rng_state) +{ + rng_state = rng_state * 747796405 + 2891336453; + uint result = ((rng_state >> ((rng_state >> 28) + 4)) ^ rng_state) * 277803737; + result = (result >> 22) ^ result; + return (result / 4294967295.0); +} + +float randomValueNormalDistribution(inout uint rng_state) +{ + float theta = 2.0 * 3.14159265359 * randomValue(rng_state); + float rho = sqrt(-2.0 * log(randomValue(rng_state))); + return (rho * cos(theta)); +} + +vec3 randomDirection(inout uint rng_state) +{ + float x = randomValueNormalDistribution(rng_state); + float y = randomValueNormalDistribution(rng_state); + float z = randomValueNormalDistribution(rng_state); + return normalize(vec3(x, y, z)); +} + +vec3 randomHemisphereDirection(vec3 normal, inout uint rng_state) +{ + vec3 direction = randomDirection(rng_state); + return (direction * sign(dot(normal, direction))); +} \ No newline at end of file diff --git a/srcs/class/Scene.cpp b/srcs/class/Scene.cpp index de07e21..f0a4ef5 100644 --- a/srcs/class/Scene.cpp +++ b/srcs/class/Scene.cpp @@ -76,8 +76,8 @@ void Scene::updateGPUData() gpu_obj.color = mat->color; gpu_obj.emission = mat->emission; gpu_obj.roughness = mat->roughness; - gpu_obj.specular = mat->specular; - + gpu_obj.metallic = mat->metallic; + gpu_obj.type = static_cast(obj->getType()); if (obj->getType() == Object::Type::SPHERE) diff --git a/srcs/class/SceneParser.cpp b/srcs/class/SceneParser.cpp index 382d7ca..b06db29 100644 --- a/srcs/class/SceneParser.cpp +++ b/srcs/class/SceneParser.cpp @@ -38,10 +38,10 @@ void SceneParser::parseMaterial(std::stringstream &line) float r,g,b; float emission; float roughness; - float specular; + float metallic; Material *mat; - if (!(line >> r >> g >> b >> emission >> roughness >> specular)) + if (!(line >> r >> g >> b >> emission >> roughness >> metallic)) throw std::runtime_error("Material: Missing material properties"); mat = new Material; @@ -49,7 +49,7 @@ void SceneParser::parseMaterial(std::stringstream &line) mat->color = glm::vec3(r / 255.0f, g / 255.0f, b / 255.0f); mat->emission = emission; mat->roughness = roughness; - mat->specular = specular; + mat->metallic = metallic; _scene->addMaterial(mat); }