From 08fb9c37ade401186bde87d80f0d371ab7064893 Mon Sep 17 00:00:00 2001 From: RedShip Date: Fri, 10 Jan 2025 21:31:55 +0100 Subject: [PATCH] jsp --- includes/RT/Scene.hpp | 4 +- scenes/portalrotation.rt | 2 +- scenes/test.rt | 4 +- shaders/compute.glsl | 6 +- shaders/intersect.glsl | 332 +++++++++++++++++++-------------------- srcs/RT.cpp | 8 +- srcs/class/Scene.cpp | 4 +- srcs/class/Shader.cpp | 2 +- 8 files changed, 181 insertions(+), 181 deletions(-) diff --git a/includes/RT/Scene.hpp b/includes/RT/Scene.hpp index 4fbce65..693eccb 100644 --- a/includes/RT/Scene.hpp +++ b/includes/RT/Scene.hpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/12/23 18:30:18 by ycontre #+# #+# */ -/* Updated: 2024/12/23 18:46:13 by ycontre ### ########.fr */ +/* Updated: 2025/01/10 18:58:38 by ycontre ### ########.fr */ /* */ /* ************************************************************************** */ @@ -59,7 +59,7 @@ class Scene void updateGPUData(); const std::vector &getObjectData() const; - const std::vector &getMaterialData() const; + std::vector &getMaterialData(); Camera *getCamera(void) const; Material *getMaterial(int material_index); diff --git a/scenes/portalrotation.rt b/scenes/portalrotation.rt index 8f95100..e144c35 100644 --- a/scenes/portalrotation.rt +++ b/scenes/portalrotation.rt @@ -20,5 +20,5 @@ pl -3 0 0 1 0 0 3 pl 0 0 -3 0 0 1 4 pl 0 0 3 0 0 -1 2 -po -0.33 -0.66 -1 0 1 0 0.5 0.5 0 0 2 +po -0.33 -0.66 -1 0 1 0 0.5 0.5 -0.5 0 2 po -0.5 -0.5 1 0 1 0 1 0 0 1 4 \ No newline at end of file diff --git a/scenes/test.rt b/scenes/test.rt index b64e276..d04c69a 100644 --- a/scenes/test.rt +++ b/scenes/test.rt @@ -1,8 +1,8 @@ -CAM -0.0970577 1.63916 1.69444 -13.6 -84 0 1 +CAM -0.0970577 1.63916 1.69444 -13.6 -84 0 4 MAT 200 200 200 0.0 0.0 0.0 //white -MAT 255 50 50 0.0 1.0 0.0 //red +MAT 255 50 50 0.0 1.0 1.0 //red MAT 50 255 50 0.0 0.0 0.0 //green MAT 100 100 255 0.0 0.0 0.0 //blue MAT 255 100 255 0.0 0.0 0.0 //purple diff --git a/shaders/compute.glsl b/shaders/compute.glsl index 47e8c10..3d176bb 100644 --- a/shaders/compute.glsl +++ b/shaders/compute.glsl @@ -38,17 +38,17 @@ struct GPUCamera float focus_distance; }; -layout(std430, binding = 1) buffer ObjectBuffer +layout(std430, binding = 0) buffer ObjectBuffer { GPUObject objects[]; }; -layout(std430, binding = 2) buffer MaterialBuffer +layout(std430, binding = 1) buffer MaterialBuffer { GPUMaterial materials[]; }; -layout(std140) uniform CameraData +layout(std140, binding = 0) uniform CameraData { GPUCamera camera; }; diff --git a/shaders/intersect.glsl b/shaders/intersect.glsl index ce2da7a..7db6a7e 100644 --- a/shaders/intersect.glsl +++ b/shaders/intersect.glsl @@ -1,224 +1,224 @@ bool intersectSphere(Ray ray, GPUObject obj, out hitInfo hit) { - vec3 oc = ray.origin - obj.position; - - float b = dot(oc, ray.direction); - float c = dot(oc, oc) - obj.radius * obj.radius; - float h = b * b - c; - - float t = -b - sqrt(h); - t = mix(t, -b + sqrt(h), step(t, 0.0)); - - hit.t = t; - hit.position = ray.origin + ray.direction * t; - hit.normal = normalize(hit.position - obj.position); - - return (h >= 0.0 && t > 0.0); + vec3 oc = ray.origin - obj.position; + + float b = dot(oc, ray.direction); + float c = dot(oc, oc) - obj.radius * obj.radius; + float h = b * b - c; + + float t = -b - sqrt(h); + t = mix(t, -b + sqrt(h), step(t, 0.0)); + + hit.t = t; + hit.position = ray.origin + ray.direction * t; + hit.normal = normalize(hit.position - obj.position); + + return (h >= 0.0 && t > 0.0); } bool intersectPlane(Ray ray, GPUObject obj, out hitInfo hit) { - float d = dot(obj.normal, ray.direction); - float t = dot(obj.position - ray.origin, obj.normal) / d; - bool valid = t >= 0.0 && d != 0.0; + float d = dot(obj.normal, ray.direction); + float t = dot(obj.position - ray.origin, obj.normal) / d; + bool valid = t >= 0.0 && d != 0.0; - if (!valid) return (false); - - hit.t = t; - hit.position = ray.origin + ray.direction * t; - hit.normal = d < 0.0 ? obj.normal : -obj.normal; - - return (valid); + if (!valid) return (false); + + hit.t = t; + hit.position = ray.origin + ray.direction * t; + hit.normal = d < 0.0 ? obj.normal : -obj.normal; + + return (valid); } bool intersectQuad(Ray ray, GPUObject obj, out hitInfo hit) { - vec3 normal = normalize(cross(obj.vertex1, obj.vertex2)); - float d = dot(normal, ray.direction); + vec3 normal = normalize(cross(obj.vertex1, obj.vertex2)); + float d = dot(normal, ray.direction); - if (d == 0.0) return (false); + if (d == 0.0) return (false); - float t = dot(obj.position - ray.origin, normal) / d; + float t = dot(obj.position - ray.origin, normal) / d; - if (t <= 0.0) return (false); - - vec3 p = ray.origin + ray.direction * t - obj.position; - - float e1 = dot(p, obj.vertex1); - float e2 = dot(p, obj.vertex2); - - float l1 = dot(obj.vertex1, obj.vertex1); - float l2 = dot(obj.vertex2, obj.vertex2); - - bool inside = e1 >= 0.0 && e1 <= l1 && e2 >= 0.0 && e2 <= l2; - - hit.t = t; - hit.position = p + obj.position; - hit.normal = normal * -sign(d); - - return (inside); + if (t <= 0.0) return (false); + + vec3 p = ray.origin + ray.direction * t - obj.position; + + float e1 = dot(p, obj.vertex1); + float e2 = dot(p, obj.vertex2); + + float l1 = dot(obj.vertex1, obj.vertex1); + float l2 = dot(obj.vertex2, obj.vertex2); + + bool inside = e1 >= 0.0 && e1 <= l1 && e2 >= 0.0 && e2 <= l2; + + hit.t = t; + hit.position = p + obj.position; + hit.normal = normal * -sign(d); + + return (inside); } bool intersectTriangle(Ray ray, GPUObject obj, out hitInfo hit) { - vec3 pvec = cross(ray.direction, obj.vertex2); - float det = dot(obj.vertex1, pvec); - vec3 tvec = ray.origin - obj.position; - - float invDet = 1.0 / det; - float u = dot(tvec, pvec) * invDet; - vec3 qvec = cross(tvec, obj.vertex1); - float v = dot(ray.direction, qvec) * invDet; - float t = dot(obj.vertex2, qvec) * invDet; - - bool valid = abs(det) > 1e-8 && - u >= 0.0 && u <= 1.0 && - v >= 0.0 && (u + v) <= 1.0 && - t > 0.0; - - hit.t = t; - hit.position = ray.origin + ray.direction * t; - hit.normal = obj.normal * sign(-dot(ray.direction, obj.normal)); - - return (valid); + vec3 pvec = cross(ray.direction, obj.vertex2); + float det = dot(obj.vertex1, pvec); + vec3 tvec = ray.origin - obj.position; + + float invDet = 1.0 / det; + float u = dot(tvec, pvec) * invDet; + vec3 qvec = cross(tvec, obj.vertex1); + float v = dot(ray.direction, qvec) * invDet; + float t = dot(obj.vertex2, qvec) * invDet; + + bool valid = abs(det) > 1e-8 && + u >= 0.0 && u <= 1.0 && + v >= 0.0 && (u + v) <= 1.0 && + t > 0.0; + + hit.t = t; + hit.position = ray.origin + ray.direction * t; + hit.normal = obj.normal * sign(-dot(ray.direction, obj.normal)); + + return (valid); } // bool intersectTriangle(Ray ray, GPUObject obj, out hitInfo hit) // { // vec3 pvec = cross(ray.direction, obj.vertex2); // float det = dot(obj.vertex1, pvec); - + // if (abs(det) < 1e-8) return (false); // det < 0.0 - + // float invDet = 1.0 / det; - + // vec3 tvec = ray.origin - obj.position; - + // float u = dot(tvec, pvec) * invDet; // if (u < 0.0 || u > 1.0) return (false); - + // vec3 qvec = cross(tvec, obj.vertex1); // float v = dot(ray.direction, qvec) * invDet; // if (v < 0.0 || u + v > 1.0) return (false); - + // float t = dot(obj.vertex2, qvec) * invDet; // if (t <= 0.0) return (false); - + // hit.t = t; // hit.position = ray.origin + ray.direction * t; - + // vec3 normal = obj.normal; // hit.normal = dot(ray.direction, normal) < 0.0 ? normal : -normal; - + // return (true); // } bool intersectCube(Ray ray, GPUObject obj, out hitInfo hit) { - vec3 halfSize = obj.vertex1 * 0.5; - vec3 rayOriginLocal = ray.origin - obj.position; - - vec3 invDir = 1.0 / ray.direction; - vec3 t1 = (-halfSize - rayOriginLocal) * invDir; - vec3 t2 = (halfSize - rayOriginLocal) * invDir; - - vec3 tMinVec = min(t1, t2); - vec3 tMaxVec = max(t1, t2); - - float tMin = max(tMinVec.x, max(tMinVec.y, tMinVec.z)); - float tMax = min(tMaxVec.x, min(tMaxVec.y, tMaxVec.z)); - - bool hit_success = (tMax >= tMin) && (tMax > 0.0); - if (!hit_success) return false; - - hit.t = tMin > 0.0 ? tMin : tMax; - - vec3 hitPointLocal = rayOriginLocal + hit.t * ray.direction; - hit.position = hitPointLocal + obj.position; - - vec3 distances = abs(hitPointLocal) - halfSize; - - const float epsilon = 1e-4; - vec3 signs = sign(hitPointLocal); - vec3 masks = step(abs(distances), vec3(epsilon)); - - hit.normal = normalize(masks * signs); - - bool inside = all(lessThan(abs(rayOriginLocal), halfSize + vec3(epsilon))); - hit.normal *= (inside ? -1.0 : 1.0); - - return true; + vec3 halfSize = obj.vertex1 * 0.5; + vec3 rayOriginLocal = ray.origin - obj.position; + + vec3 invDir = 1.0 / ray.direction; + vec3 t1 = (-halfSize - rayOriginLocal) * invDir; + vec3 t2 = (halfSize - rayOriginLocal) * invDir; + + vec3 tMinVec = min(t1, t2); + vec3 tMaxVec = max(t1, t2); + + float tMin = max(tMinVec.x, max(tMinVec.y, tMinVec.z)); + float tMax = min(tMaxVec.x, min(tMaxVec.y, tMaxVec.z)); + + bool hit_success = (tMax >= tMin) && (tMax > 0.0); + if (!hit_success) return false; + + hit.t = tMin > 0.0 ? tMin : tMax; + + vec3 hitPointLocal = rayOriginLocal + hit.t * ray.direction; + hit.position = hitPointLocal + obj.position; + + vec3 distances = abs(hitPointLocal) - halfSize; + + const float epsilon = 1e-4; + vec3 signs = sign(hitPointLocal); + vec3 masks = step(abs(distances), vec3(epsilon)); + + hit.normal = normalize(masks * signs); + + bool inside = all(lessThan(abs(rayOriginLocal), halfSize + vec3(epsilon))); + hit.normal *= (inside ? -1.0 : 1.0); + + return true; } bool intersectCylinder(Ray ray, GPUObject obj, out hitInfo hit) { - float radius = obj.normal.x; - float height = obj.normal.y; - - vec3 p = ray.origin - obj.position; + float radius = obj.normal.x; + float height = obj.normal.y; + + vec3 p = ray.origin - obj.position; - vec3 d = ray.direction * mat3(obj.rotation); - p = p * mat3(obj.rotation); - - float half_height = height * 0.5; + vec3 d = ray.direction * mat3(obj.rotation); + p = p * mat3(obj.rotation); + + float half_height = height * 0.5; - float a = d.x * d.x + d.z * d.z; - float b = p.x * d.x + p.z * d.z; - float c = p.x * p.x + p.z * p.z - radius * radius; - - float h = b * b - a * c; - if (h < 0.0) return false; - - float sqrt_h = sqrt(h); - float t = (-b - sqrt_h) / a; - - if (t <= 0.0) - { - t = (-b + sqrt_h) / a; - if (t <= 0.0) return false; - } + float a = d.x * d.x + d.z * d.z; + float b = p.x * d.x + p.z * d.z; + float c = p.x * p.x + p.z * p.z - radius * radius; + + float h = b * b - a * c; + if (h < 0.0) return false; + + float sqrt_h = sqrt(h); + float t = (-b - sqrt_h) / a; + + if (t <= 0.0) + { + t = (-b + sqrt_h) / a; + if (t <= 0.0) return false; + } - float y = p.y + t * d.y; - - if (abs(y) <= half_height) - { + float y = p.y + t * d.y; + + if (abs(y) <= half_height) + { - hit.t = t; - hit.position = ray.origin + ray.direction * t; - - vec3 local_normal = vec3(p.x + t * d.x, 0.0, p.z + t * d.z); - hit.normal = normalize(local_normal * inverse(mat3(obj.rotation))); - return true; - } - - float cap_t = (sign(y) * half_height - p.y) / d.y; - if (cap_t <= 0.0) return false; + hit.t = t; + hit.position = ray.origin + ray.direction * t; + + vec3 local_normal = vec3(p.x + t * d.x, 0.0, p.z + t * d.z); + hit.normal = normalize(local_normal * inverse(mat3(obj.rotation))); + return true; + } + + float cap_t = (sign(y) * half_height - p.y) / d.y; + if (cap_t <= 0.0) return false; - float cap_x = p.x + cap_t * d.x; - float cap_z = p.z + cap_t * d.z; - if (cap_x * cap_x + cap_z * cap_z > radius * radius) return false; + float cap_x = p.x + cap_t * d.x; + float cap_z = p.z + cap_t * d.z; + if (cap_x * cap_x + cap_z * cap_z > radius * radius) return false; - hit.t = cap_t; - hit.position = ray.origin + ray.direction * cap_t; - + hit.t = cap_t; + hit.position = ray.origin + ray.direction * cap_t; + - vec3 cap_normal = vec3(0.0, sign(y), 0.0); - hit.normal = normalize(cap_normal * inverse(mat3(obj.rotation))); - return true; + vec3 cap_normal = vec3(0.0, sign(y), 0.0); + hit.normal = normalize(cap_normal * inverse(mat3(obj.rotation))); + return true; } bool intersect(Ray ray, GPUObject obj, out hitInfo hit) { - if (obj.type == 0) - return (intersectSphere(ray, obj, hit)); - if (obj.type == 1) - return (intersectPlane(ray, obj, hit)); - if (obj.type == 2 || obj.type == 5) - return (intersectQuad(ray, obj, hit)); - if (obj.type == 3) - return (intersectTriangle(ray, obj, hit)); - if (obj.type == 4) - return (intersectCube(ray, obj, hit)); - if (obj.type == 6) - return (intersectCylinder(ray, obj, hit)); - return (false); + if (obj.type == 0) + return (intersectSphere(ray, obj, hit)); + if (obj.type == 1) + return (intersectPlane(ray, obj, hit)); + if (obj.type == 2 || obj.type == 5) + return (intersectQuad(ray, obj, hit)); + if (obj.type == 3) + return (intersectTriangle(ray, obj, hit)); + if (obj.type == 4) + return (intersectCube(ray, obj, hit)); + if (obj.type == 6) + return (intersectCylinder(ray, obj, hit)); + return (false); } \ No newline at end of file diff --git a/srcs/RT.cpp b/srcs/RT.cpp index 2c1607e..ccca99c 100644 --- a/srcs/RT.cpp +++ b/srcs/RT.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/09/27 14:51:49 by TheRed #+# #+# */ -/* Updated: 2025/01/09 16:17:29 by tomoron ### ########.fr */ +/* Updated: 2025/01/10 19:12:40 by ycontre ### ########.fr */ /* */ /* ************************************************************************** */ @@ -44,7 +44,7 @@ int main(int argc, char **argv) glGetIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &max_gpu_size); const std::vector &object_data = scene.getObjectData(); - const std::vector &material_data = scene.getMaterialData(); + std::vector &material_data = scene.getMaterialData(); std::cout << "Sending " << object_data.size() << " objects for " << \ object_data.size() * sizeof(GPUObject) + material_data.size() * sizeof(GPUMaterial) \ << " / " << max_gpu_size << " bytes" << std::endl; @@ -56,11 +56,11 @@ int main(int argc, char **argv) glBindBuffer(GL_SHADER_STORAGE_BUFFER, objectSSBO); glBufferData(GL_SHADER_STORAGE_BUFFER, object_data.size() * sizeof(GPUObject), object_data.data(), GL_DYNAMIC_DRAW); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, objectSSBO); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, objectSSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, materialSSBO); glBufferData(GL_SHADER_STORAGE_BUFFER, material_data.size() * sizeof(GPUMaterial), material_data.data(), GL_DYNAMIC_DRAW); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, materialSSBO); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, materialSSBO); GPUCamera camera_data = scene.getCamera()->getGPUData(); glBindBuffer(GL_UNIFORM_BUFFER, cameraUBO); diff --git a/srcs/class/Scene.cpp b/srcs/class/Scene.cpp index 73c9afb..8b32490 100644 --- a/srcs/class/Scene.cpp +++ b/srcs/class/Scene.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/12/23 18:29:41 by ycontre #+# #+# */ -/* Updated: 2025/01/08 20:08:03 by ycontre ### ########.fr */ +/* Updated: 2025/01/10 18:58:57 by ycontre ### ########.fr */ /* */ /* ************************************************************************** */ @@ -153,7 +153,7 @@ const std::vector& Scene::getObjectData() const return (_gpu_objects); } -const std::vector& Scene::getMaterialData() const +std::vector& Scene::getMaterialData() { return (_gpu_materials); } diff --git a/srcs/class/Shader.cpp b/srcs/class/Shader.cpp index d93c2ee..fdd2c45 100644 --- a/srcs/class/Shader.cpp +++ b/srcs/class/Shader.cpp @@ -6,7 +6,7 @@ /* By: ycontre +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/13 20:21:13 by ycontre #+# #+# */ -/* Updated: 2024/10/14 19:52:40 by ycontre ### ########.fr */ +/* Updated: 2025/01/10 18:53:39 by ycontre ### ########.fr */ /* */ /* ************************************************************************** */