diff --git a/includes/RT/Camera.hpp b/includes/RT/Camera.hpp index a82c3bd..4d420a8 100644 --- a/includes/RT/Camera.hpp +++ b/includes/RT/Camera.hpp @@ -15,6 +15,14 @@ # include "RT.hpp" +struct GPUCamera +{ + glm::mat4 view_matrix; + alignas(16) glm::vec3 camera_position; + float aperture_size; + float focus_distance; +}; + class Camera { public: @@ -27,13 +35,20 @@ class Camera void processMouse(float xoffset, float yoffset, bool constrainPitch); void processKeyboard(bool forward, bool backward, bool left, bool right, bool up, bool down); - glm::mat4 getViewMatrix(); + void updateCameraVectors(); + glm::vec3 getPosition(); + glm::vec2 getDirection(); + glm::vec2 getDOV(); + glm::mat4 getViewMatrix(); + + GPUCamera getGPUData(); void setPosition(glm::vec3 position); + void setDirection(float pitch, float yaw); + void setDOV(float aperture, float focus); private: - void updateCameraVectors(); glm::vec3 _position; glm::vec3 _forward; @@ -50,6 +65,9 @@ class Camera float _acceleration_rate = 40.0f; float _deceleration_rate = 10000.0f; float _sensitivity = 0.2f; + + float _aperture_size = 0.0f; + float _focus_distance = 1.0f; }; #endif \ No newline at end of file diff --git a/includes/RT/objects/Portal.hpp b/includes/RT/objects/Portal.hpp index 324d5c0..331ae7d 100644 --- a/includes/RT/objects/Portal.hpp +++ b/includes/RT/objects/Portal.hpp @@ -45,11 +45,11 @@ class Portal : public Object throw std::runtime_error("Missing material properties"); _position = glm::vec3(x, y, z); - _edge1 = glm::vec3(x1, y1, z1); - _edge2 = glm::vec3(x2, y2, z2); + _up = glm::vec3(x1, y1, z1); + _right = glm::vec3(x2, y2, z2); - glm::vec3 up = glm::normalize(_edge1); - glm::vec3 right = glm::normalize(_edge2); + glm::vec3 up = glm::normalize(_up); + glm::vec3 right = glm::normalize(_right); glm::vec3 forward = glm::normalize(glm::cross(right, up)); up = normalize(glm::cross(forward, right)); @@ -64,17 +64,17 @@ class Portal : public Object catch (const std::exception &e) { throw; } } Portal(const glm::vec3 &position, const glm::vec3 &edge1, const glm::vec3 &edge2, const int linked_portal, const int mat_index) - : Object(position, mat_index), _edge1(edge1), _edge2(edge2), _linked_portal(linked_portal) {} + : Object(position, mat_index), _up(edge1), _right(edge2), _linked_portal(linked_portal) {} Quad *createSupportQuad() const { float extension = 0.2f; - glm::vec3 right_dir = glm::normalize(_edge1); - glm::vec3 up_dir = glm::normalize(_edge2); + glm::vec3 right_dir = glm::normalize(_up); + glm::vec3 up_dir = glm::normalize(_right); - float right_length = glm::length(_edge1) + extension; - float up_length = glm::length(_edge2) + extension; + float right_length = glm::length(_up) + extension; + float up_length = glm::length(_right) + extension; glm::vec3 center_offset = -(right_dir * (extension / 2.0f) + up_dir * (extension / 2.0f)); glm::vec3 position = _position + _normal * -0.001f + center_offset; @@ -85,8 +85,8 @@ class Portal : public Object return (new Quad(position, right, up, _mat_index)); } - glm::vec3 getEdge1() const { return (_edge1); } - glm::vec3 getEdge2() const { return (_edge2); } + glm::vec3 getUp() const { return (_up); } + glm::vec3 getRight() const { return (_right); } glm::vec3 getNormal() const { return (_normal); } glm::mat3 getTransform() const { return (_transform); } @@ -97,8 +97,8 @@ class Portal : public Object Type getType() const override { return Type::PORTAL; } private: - glm::vec3 _edge1; - glm::vec3 _edge2; + glm::vec3 _up; + glm::vec3 _right; glm::vec3 _normal; glm::mat3 _transform; diff --git a/includes/RT/objects/Quad.hpp b/includes/RT/objects/Quad.hpp index 133980c..851f2a0 100644 --- a/includes/RT/objects/Quad.hpp +++ b/includes/RT/objects/Quad.hpp @@ -39,23 +39,23 @@ class Quad : public Object throw std::runtime_error("Missing material properties"); _position = glm::vec3(x, y, z); - _edge1 = glm::vec3(x1, y1, z1); - _edge2 = glm::vec3(x2, y2, z2); + _up = glm::vec3(x1, y1, z1); + _right = glm::vec3(x2, y2, z2); _mat_index = mat_index; } catch (const std::exception &e) { throw; } } Quad(const glm::vec3 &position, const glm::vec3 &edge1, const glm::vec3 &edge2, const int mat_index) - : Object(position, mat_index), _edge1(edge1), _edge2(edge2) {} + : Object(position, mat_index), _up(edge1), _right(edge2) {} - glm::vec3 getEdge1() const { return (_edge1); } - glm::vec3 getEdge2() const { return (_edge2); } + glm::vec3 getUp() const { return (_up); } + glm::vec3 getRight() const { return (_right); } Type getType() const override { return Type::QUAD; } private: - glm::vec3 _edge1; - glm::vec3 _edge2; + glm::vec3 _up; + glm::vec3 _right; }; #endif \ No newline at end of file diff --git a/scenes/test.rt b/scenes/test.rt index 4c6ef7c..b60710f 100644 --- a/scenes/test.rt +++ b/scenes/test.rt @@ -1,4 +1,4 @@ -CAM 0 1 3 +CAM 0.576905 1.29122 1.46329 -6.8 -128 0.1 2 MAT 200 200 200 0.0 0.0 0.0 //white MAT 255 50 50 0.0 0.0 0.0 //red diff --git a/shaders/compute.glsl b/shaders/compute.glsl index c5e59eb..19492cc 100644 --- a/shaders/compute.glsl +++ b/shaders/compute.glsl @@ -14,14 +14,10 @@ struct GPUObject { vec3 vertex1; // 12 + 4 vec3 vertex2; // 12 + 4 - float radius; // 4 int mat_index; // 4 int type; // 4 - - vec3 cube_size() { return (vertex1); } - int portal_index() { return (int(radius)); } }; struct GPUMaterial @@ -34,6 +30,14 @@ struct GPUMaterial int texture_index; // 4 }; +struct GPUCamera +{ + mat4 view_matrix; + vec3 position; + float aperture_size; + float focus_distance; +}; + layout(std430, binding = 1) buffer ObjectBuffer { GPUObject objects[]; @@ -44,10 +48,13 @@ layout(std430, binding = 2) buffer MaterialBuffer GPUMaterial materials[]; }; +layout(std140) uniform CameraData +{ + GPUCamera camera; +}; + uniform int u_objectsNum; uniform vec2 u_resolution; -uniform vec3 u_cameraPosition; -uniform mat4 u_viewMatrix; uniform int u_frameCount; uniform float u_time; @@ -76,7 +83,7 @@ Ray portalRay(Ray ray, hitInfo hit) vec3 relative; portal_1 = objects[hit.obj_index]; - portal_2 = objects[portal_1.portal_index()]; // saving memory radius = portal_index + portal_2 = objects[int(portal_1.radius)]; // saving memory radius = portal_index relative = hit.position - portal_1.position; @@ -100,7 +107,7 @@ hitInfo traceRay(Ray ray) { hitInfo hit; - for (int p = 0; p < 20; p++) //portals + for (int p = 0; p < 5; p++) //portals { hit.t = 1e30; hit.obj_index = -1; @@ -139,7 +146,7 @@ vec3 pathtrace(Ray ray, inout uint rng_state) hitInfo hit = traceRay(ray); if (hit.obj_index == -1) { - // light += GetEnvironmentLight(ray); + light += GetEnvironmentLight(ray); // light += vec3(135 / 255.0f, 206 / 255.0f, 235 / 255.0f); //ambient color break; } @@ -170,21 +177,18 @@ Ray initRay(vec2 uv, inout uint rng_state) float fov = 90.0; float focal_length = 1.0 / tan(radians(fov) / 2.0); - vec3 origin = u_cameraPosition; + vec3 origin = camera.position; vec3 view_space_ray = normalize(vec3(uv.x, uv.y, -focal_length)); - vec3 ray_direction = normalize((inverse(u_viewMatrix) * vec4(view_space_ray, 0.0)).xyz); + vec3 ray_direction = normalize((inverse(camera.view_matrix) * vec4(view_space_ray, 0.0)).xyz); - float focus_distance = 4.5; - float aperture = 0.1; - - vec3 right = vec3(u_viewMatrix[0][0], u_viewMatrix[1][0], u_viewMatrix[2][0]); - vec3 up = vec3(u_viewMatrix[0][1], u_viewMatrix[1][1], u_viewMatrix[2][1]); + vec3 right = vec3(camera.view_matrix[0][0], camera.view_matrix[1][0], camera.view_matrix[2][0]); + vec3 up = vec3(camera.view_matrix[0][1], camera.view_matrix[1][1], camera.view_matrix[2][1]); - vec3 focal_point = u_cameraPosition + ray_direction * focus_distance; + vec3 focal_point = origin + ray_direction * camera.focus_distance; float r = sqrt(randomValue(rng_state)); float theta = 2.0 * M_PI * randomValue(rng_state); - vec2 lens_point = aperture * r * vec2(cos(theta), sin(theta)); + vec2 lens_point = camera.aperture_size * r * vec2(cos(theta), sin(theta)); origin += right * lens_point.x + up * lens_point.y; ray_direction = normalize(focal_point - origin); diff --git a/shaders/intersect.glsl b/shaders/intersect.glsl index 972456f..f643d6e 100644 --- a/shaders/intersect.glsl +++ b/shaders/intersect.glsl @@ -115,7 +115,7 @@ bool intersectTriangle(Ray ray, GPUObject obj, out hitInfo hit) bool intersectCube(Ray ray, GPUObject obj, out hitInfo hit) { - vec3 halfSize = obj.cube_size() * 0.5; + vec3 halfSize = obj.vertex1 * 0.5; vec3 rayOriginLocal = ray.origin - obj.position; vec3 invDir = 1.0 / ray.direction; diff --git a/srcs/RT.cpp b/srcs/RT.cpp index 1b5c609..86b4d51 100644 --- a/srcs/RT.cpp +++ b/srcs/RT.cpp @@ -28,6 +28,12 @@ int main(int argc, char **argv) GLuint materialSSBO; glGenBuffers(1, &materialSSBO); + GLuint cameraUBO; + glGenBuffers(1, &cameraUBO); + glBindBuffer(GL_UNIFORM_BUFFER, cameraUBO); + glBufferData(GL_UNIFORM_BUFFER, sizeof(GPUCamera), nullptr, GL_DYNAMIC_DRAW); + glBindBufferBase(GL_UNIFORM_BUFFER, 0, cameraUBO); + shader.attach(); Vertex vertices[3] = {{{-1.0f, -1.0f}, {0.0f, 0.0f}},{{3.0f, -1.0f}, {2.0f, 0.0f}},{{-1.0f, 3.0f}, {0.0f, 2.0f}}}; @@ -56,12 +62,14 @@ int main(int argc, char **argv) glBufferData(GL_SHADER_STORAGE_BUFFER, material_data.size() * sizeof(GPUMaterial), material_data.data(), GL_DYNAMIC_DRAW); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, materialSSBO); + GPUCamera camera_data = scene.getCamera()->getGPUData(); + glBindBuffer(GL_UNIFORM_BUFFER, cameraUBO); + glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(GPUCamera), &camera_data); + shader.set_int("u_frameCount", window.getFrameCount()); shader.set_int("u_objectsNum", object_data.size()); shader.set_float("u_time", (float)(glfwGetTime())); shader.set_vec2("u_resolution", glm::vec2(WIDTH, HEIGHT)); - shader.set_vec3("u_cameraPosition", scene.getCamera()->getPosition()); - shader.set_mat4("u_viewMatrix", scene.getCamera()->getViewMatrix()); glDispatchCompute((WIDTH + 15) / 16, (HEIGHT + 15) / 16, 1); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); diff --git a/srcs/class/Camera.cpp b/srcs/class/Camera.cpp index 13af644..8dc05bc 100644 --- a/srcs/class/Camera.cpp +++ b/srcs/class/Camera.cpp @@ -95,7 +95,41 @@ glm::vec3 Camera::getPosition() return (_position); } +glm::vec2 Camera::getDirection() +{ + return (glm::vec2(_pitch, _yaw)); +} + +glm::vec2 Camera::getDOV() +{ + return (glm::vec2(_aperture_size, _focus_distance)); +} + +GPUCamera Camera::getGPUData() +{ + GPUCamera data; + + data.aperture_size = _aperture_size; + data.focus_distance = _focus_distance; + data.camera_position = _position; + data.view_matrix = getViewMatrix(); + + return (data); +} + void Camera::setPosition(glm::vec3 position) { _position = position; +} + +void Camera::setDirection(float pitch, float yaw) +{ + _pitch = pitch; + _yaw = yaw; +} + +void Camera::setDOV(float aperture, float focus) +{ + _aperture_size = aperture; + _focus_distance = focus; } \ No newline at end of file diff --git a/srcs/class/Scene.cpp b/srcs/class/Scene.cpp index 2dcb454..76623e1 100644 --- a/srcs/class/Scene.cpp +++ b/srcs/class/Scene.cpp @@ -91,8 +91,8 @@ void Scene::updateGPUData() else if (obj->getType() == Object::Type::QUAD) { auto quad = static_cast(obj); - gpu_obj.vertex1 = quad->getEdge1(); - gpu_obj.vertex2 = quad->getEdge2(); + gpu_obj.vertex1 = quad->getUp(); + gpu_obj.vertex2 = quad->getRight(); } else if (obj->getType() == Object::Type::TRIANGLE) { @@ -110,8 +110,8 @@ void Scene::updateGPUData() else if (obj->getType() == Object::Type::PORTAL) { auto portal = static_cast(obj); - gpu_obj.vertex1 = portal->getEdge1(); - gpu_obj.vertex2 = portal->getEdge2(); + gpu_obj.vertex1 = portal->getUp(); + gpu_obj.vertex2 = portal->getRight(); gpu_obj.normal = portal->getNormal(); gpu_obj.transform = glm::mat4(portal->getTransform()); diff --git a/srcs/class/SceneParser.cpp b/srcs/class/SceneParser.cpp index c108d59..b5837a7 100644 --- a/srcs/class/SceneParser.cpp +++ b/srcs/class/SceneParser.cpp @@ -85,12 +85,30 @@ void SceneParser::parseMaterial(std::stringstream &line) void SceneParser::parseCamera(std::stringstream &line) { - float x,y,z; - + float x,y,z; + float yaw, pitch; + float aperture, focus; + if (!(line >> x >> y >> z)) throw std::runtime_error("Camera: Missing camera properties"); + if (!(line >> yaw >> pitch)) + { + yaw = 0; + pitch = -90; + } + + if (!(line >> aperture >> focus)) + { + aperture = 0.0; + focus = 1.0; + } + _scene->getCamera()->setPosition(glm::vec3(x, y, z)); + _scene->getCamera()->setDirection(yaw, pitch); + _scene->getCamera()->setDOV(aperture, focus); + + _scene->getCamera()->updateCameraVectors(); } bool SceneParser::parseLine(const std::string &line) diff --git a/srcs/class/Window.cpp b/srcs/class/Window.cpp index 1e9d345..c8e44de 100644 --- a/srcs/class/Window.cpp +++ b/srcs/class/Window.cpp @@ -110,6 +110,18 @@ void Window::keyCallback(GLFWwindow *window, int key, int scancode, int action, { Window* win = static_cast(glfwGetWindowUserPointer(window)); (void) win; (void) key; (void) scancode; (void) action; (void) mods; + + if (key == 67 && action == GLFW_PRESS) + { + glm::vec3 pos = win->_scene->getCamera()->getPosition(); + glm::vec2 dir = win->_scene->getCamera()->getDirection(); + glm::vec2 dov = win->_scene->getCamera()->getDOV(); + + std::cout << "\nCAM\t" << pos.x << " " << pos.y << " " << pos.z << "\t" + << dir.x << " " << dir.y << " " << "\t" + << dov.x << " " << dov.y << " " << "\t" + << std::endl; + } } void Window::display()