From 0cbcd608b2acfd998c2c1107ca50edc897d6e840 Mon Sep 17 00:00:00 2001 From: Benjamin Kyd Date: Fri, 20 Oct 2023 22:49:51 +0100 Subject: [PATCH] put some raytracing stuff about --- TODO | 2 +- libhart/scene/camera.hpp | 2 +- libhart/tracing/ray.hpp | 14 -- src/graphics.hpp | 4 +- src/inferno.cpp | 22 ++-- ...lumination.cpp => global_illumination.cpp} | 0 ...lumination.hpp => global_illumination.hpp} | 0 {libhart/tracing => src/renderer}/hit.hpp | 4 +- src/renderer/object_tracer.cpp | 18 +++ src/renderer/object_tracer.hpp | 13 ++ src/renderer/ray.cpp | 0 src/renderer/ray.hpp | 14 ++ src/renderer/ray_source.cpp | 120 ++++++++---------- src/renderer/ray_source.hpp | 56 ++++---- src/renderer/renderer.cpp | 17 ++- src/renderer/scenetracer.cpp | 0 src/renderer/scenetracer.hpp | 0 src/renderer/triangle.cpp | 0 src/renderer/triangle.hpp | 8 ++ 19 files changed, 159 insertions(+), 135 deletions(-) delete mode 100644 libhart/tracing/ray.hpp rename src/renderer/{globalillumination.cpp => global_illumination.cpp} (100%) rename src/renderer/{globalillumination.hpp => global_illumination.hpp} (100%) rename {libhart/tracing => src/renderer}/hit.hpp (67%) create mode 100644 src/renderer/object_tracer.cpp create mode 100644 src/renderer/object_tracer.hpp delete mode 100644 src/renderer/ray.cpp delete mode 100644 src/renderer/scenetracer.cpp delete mode 100644 src/renderer/scenetracer.hpp delete mode 100644 src/renderer/triangle.cpp diff --git a/TODO b/TODO index 5906ae5..ad1f543 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,3 @@ -[ ] The main thread is constantly polling for changes in the render texture, consider using a notification mechanism instead. For example, you could use a callback function that the renderer registers with the render texture, which is called whenever the texture is updated. +[x] The main thread is constantly polling for changes in the render texture, consider using a notification mechanism instead. For example, you could use a callback function that the renderer registers with the render texture, which is called whenever the texture is updated. [ ] diff --git a/libhart/scene/camera.hpp b/libhart/scene/camera.hpp index 1e3f004..9d284a6 100644 --- a/libhart/scene/camera.hpp +++ b/libhart/scene/camera.hpp @@ -15,7 +15,7 @@ typedef struct _CameraImpl { typedef struct Viewport { glm::ivec2 Raster = {1920, 1080}; - glm::ivec2 Ray = {1920, 1080}; + glm::ivec2 Ray = {200, 200}; } Viewports; typedef struct Camera { diff --git a/libhart/tracing/ray.hpp b/libhart/tracing/ray.hpp deleted file mode 100644 index c186b94..0000000 --- a/libhart/tracing/ray.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include - -namespace inferno { - -struct Ray -{ - glm::vec3 Origin; - glm::vec3 Direction; - uint32_t Reference; -}; - -} diff --git a/src/graphics.hpp b/src/graphics.hpp index 1cba674..60f9b44 100644 --- a/src/graphics.hpp +++ b/src/graphics.hpp @@ -21,6 +21,8 @@ extern "C" #include namespace inferno { +namespace graphics::rays { class Ray; -using RayField = std::vector; +} +using RayField = std::vector; } diff --git a/src/inferno.cpp b/src/inferno.cpp index 5f51cf7..61d2ba5 100644 --- a/src/inferno.cpp +++ b/src/inferno.cpp @@ -94,22 +94,28 @@ InfernoApp* inferno_create() graphics::shader_link(basicShader); basicMaterial->setGlShader(basicShader); - scene::Mesh* mesh = new scene::Mesh; - mesh->loadOBJ("res/lucy.obj"); - mesh->ready(); - mesh->setMaterial(basicMaterial); + // scene::Mesh* mesh = new scene::Mesh; + // mesh->loadOBJ("res/dragon-cornell-size.obj"); + // mesh->ready(); + // mesh->setMaterial(basicMaterial); + // scene::SceneObject* object = scene::scene_object_create(); + // scene::scene_object_add_mesh(object, mesh); + // scene::scene_add_object(app->Scene, object); - scene::SceneObject* object = scene::scene_object_create(); - scene::scene_object_add_mesh(object, mesh); + scene::Mesh* box = new scene::Mesh; + box->loadOBJ("res/cornell-box.obj"); + box->ready(); + box->setMaterial(basicMaterial); + scene::SceneObject* box_object = scene::scene_object_create(); + scene::scene_object_add_mesh(box_object, box); + scene::scene_add_object(app->Scene, box_object); - scene::scene_add_object(app->Scene, object); app->PreviewRenderer = graphics::preview_create(); graphics::preview_set_viewport(app->PreviewRenderer, app->Scene->Camera); app->RayRenderer = graphics::rayr_create(app->Scene); graphics::rayr_set_viewport(app->RayRenderer, app->Scene->Camera); - return app; } diff --git a/src/renderer/globalillumination.cpp b/src/renderer/global_illumination.cpp similarity index 100% rename from src/renderer/globalillumination.cpp rename to src/renderer/global_illumination.cpp diff --git a/src/renderer/globalillumination.hpp b/src/renderer/global_illumination.hpp similarity index 100% rename from src/renderer/globalillumination.hpp rename to src/renderer/global_illumination.hpp diff --git a/libhart/tracing/hit.hpp b/src/renderer/hit.hpp similarity index 67% rename from libhart/tracing/hit.hpp rename to src/renderer/hit.hpp index b990987..db9f383 100644 --- a/libhart/tracing/hit.hpp +++ b/src/renderer/hit.hpp @@ -2,15 +2,13 @@ #include -namespace inferno { +namespace inferno::graphics::rays { class Ray; struct HitInfo { Ray* Caller; - // indicie of hit ^ mesh idx of hit - int Identifier; glm::vec2 UV; glm::vec3 SurfaceNormal; float Distance; diff --git a/src/renderer/object_tracer.cpp b/src/renderer/object_tracer.cpp new file mode 100644 index 0000000..d231f9a --- /dev/null +++ b/src/renderer/object_tracer.cpp @@ -0,0 +1,18 @@ +#include "object_tracer.hpp" +#include "scene/object.hpp" + +#include + +namespace inferno::graphics::rays { + +HitInfo* object_ray_collide(scene::SceneObject* object, Ray* ray) +{ + HitInfo* info = nullptr; + for (auto* mesh : scene::scene_object_get_meshs(object)) { + // extract triangles and loop over them, if there is a hit - we return + } + return info; +} + +} + diff --git a/src/renderer/object_tracer.hpp b/src/renderer/object_tracer.hpp new file mode 100644 index 0000000..cdf2a96 --- /dev/null +++ b/src/renderer/object_tracer.hpp @@ -0,0 +1,13 @@ +#pragma once + +#include +#include +#include +#include + +namespace inferno::graphics::rays { + +HitInfo* object_ray_collide(scene::SceneObject* object, Ray* ray); + +} + diff --git a/src/renderer/ray.cpp b/src/renderer/ray.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/src/renderer/ray.hpp b/src/renderer/ray.hpp index e69de29..cc06c66 100644 --- a/src/renderer/ray.hpp +++ b/src/renderer/ray.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include + +namespace inferno::graphics::rays { + +struct Ray +{ + glm::vec3 Origin; + glm::vec3 Direction; + uint32_t Reference; +}; + +} diff --git a/src/renderer/ray_source.cpp b/src/renderer/ray_source.cpp index 62393e2..e6239ad 100644 --- a/src/renderer/ray_source.cpp +++ b/src/renderer/ray_source.cpp @@ -1,70 +1,50 @@ -// #include "ray_source.hpp" -// -// #include -// -// #include -// -// #include -// -// #include -// -// using namespace inferno; -// -// RaySource::RaySource(Camera* camera) -// : mReferenceCamera(camera) -// { -// this->generate(); -// } -// -// RaySource::~RaySource() -// { -// -// } -// -// void RaySource::generate() -// { -// // const float aspect = mReferenceCamera->getRayViewport().x / mReferenceCamera->getRayViewport().y; -// // float scale = tan(mReferenceCamera->FOV / 2.0f * helpers::PI / 180.0f); -// } -// -// ReferencedRayField RaySource::getInitialRays(bool MSAA) -// { -// if (mReferenceCamera->didUpdate()) -// { -// this->generate(); -// } -// -// RayField field; -// field.reserve(mReferenceCamera->getRayViewport().x * mReferenceCamera->getRayViewport().y); -// -// const float aspect = mReferenceCamera->getRayViewport().x / mReferenceCamera->getRayViewport().y; -// float scale = tan(mReferenceCamera->FOV / 2.0f * helpers::PI / 180.0f); -// -// glm::mat4 cameraToWorld = mReferenceCamera->getCameraLook(); -// glm::vec3 origin = mReferenceCamera->Position; -// -// std::unordered_map reference; -// -// uint32_t i = 0; -// for (int x = 0; x < mReferenceCamera->getRayViewport().x; x++) -// for (int y = 0; y < mReferenceCamera->getRayViewport().y; y++) -// { -// float Px = (2.0f * ((x + 0.5f) / mReferenceCamera->getRayViewport().x) - 1.0f) * scale * aspect; -// float Py = (2.0f * ((y + 0.5f) / mReferenceCamera->getRayViewport().y) - 1.0f) * scale; -// -// Ray* ray = new Ray{}; -// -// glm::vec4 dir4 = glm::vec4(Px, Py, -1.0f, 1.0f) * cameraToWorld; -// glm::vec3 dir3 = glm::vec3(dir4) / dir4.w; -// ray->Direction = glm::normalize(dir3); -// -// ray->Origin = origin; -// ray->Reference = i; -// reference[i] = {x, y}; -// -// field.push_back(ray); -// i++; -// } -// -// return { field, reference }; -// } +#include "ray_source.hpp" + +#include + +#include + +#include +#include + +namespace inferno::graphics::rays { + +ReferencedRayField generate_initial_rays(graphics::Camera* camera, bool MSAA) +{ + auto viewport = graphics::camera_ray_get_viewport(camera); + + RayField field; + field.reserve(viewport.x * viewport.y); + + const float aspect = static_cast(viewport.x) / static_cast(viewport.y); + float scale = tan(camera->FOV / 2.0f * helpers::PI / 180.0f); + + glm::mat4 cameraToWorld = graphics::camera_get_look(camera); + glm::vec3 origin = camera->Position; + + std::unordered_map reference; + + uint32_t i = 0; + for (int x = 0; x < viewport.x; x++) + for (int y = 0; y < viewport.y; y++) { + float Px = (2.0f * ((x + 0.5f) / viewport.x) - 1.0f) * scale * aspect; + float Py = (2.0f * ((y + 0.5f) / viewport.y) - 1.0f) * scale; + + Ray* ray = new Ray {}; + + glm::vec4 dir4 = glm::vec4(Px, Py, -1.0f, 1.0f) * cameraToWorld; + glm::vec3 dir3 = glm::vec3(dir4) / dir4.w; + ray->Direction = glm::normalize(dir3); + + ray->Origin = origin; + ray->Reference = i; + reference[i] = { x, y }; + + field.push_back(ray); + i++; + } + + return { field, reference }; +} + +} // namespace inferno::graphics::rays diff --git a/src/renderer/ray_source.hpp b/src/renderer/ray_source.hpp index 9ccce94..243e5f5 100644 --- a/src/renderer/ray_source.hpp +++ b/src/renderer/ray_source.hpp @@ -1,33 +1,23 @@ -// #pragma once -// -// #include -// #include -// -// #include -// -// #include -// -// namespace inferno { -// -// class Camera; -// -// struct ReferencedRayField { -// RayField Field; -// std::unordered_map Reference; -// }; -// -// -// class RaySource -// { -// public: -// RaySource(Camera* camera); -// ~RaySource(); -// -// void generate(); -// ReferencedRayField getInitialRays(bool MSAA); -// -// private: -// Camera* mReferenceCamera; -// }; -// -// } +#pragma once + +#include +#include + +#include + +#include + +namespace inferno::graphics { + class Camera; +} + +namespace inferno::graphics::rays { + +struct ReferencedRayField { + RayField Field; + std::unordered_map Reference; +}; + +ReferencedRayField generate_initial_rays(Camera* camera, bool MSAA); + +} diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 96fbb34..7c88128 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -2,11 +2,12 @@ #include +#include +#include +#include #include #include #include -#include -#include #include "ray_source.hpp" @@ -102,14 +103,22 @@ void rayr_prepare(RayRenderer* renderer) void rayr_draw(RayRenderer* renderer) { + rayr_prepare(renderer); + scene::scene_frame_tick(renderer->Scene); // TODO: Rays should definately be bump allocated if possible, this is KBs of // ray data and nothing else being reallocated every frame for no reason - // ReferencedRayField startRays = mRaySource->getInitialRays(true); + rays::ReferencedRayField startRays = rays::generate_initial_rays(scene::scene_get_camera(renderer->Scene), true); for (int x = 0; x < renderer->Viewport.x; x++) { for (int y = 0; y < renderer->Viewport.y; y++) { - renderer->RenderData[y * renderer->Viewport.x + x] = { 0.1f, 1.0f, 0.1f, 1.0f }; + rays::Ray* ray = startRays.Field[x * renderer->Viewport.y + y]; + renderer->RenderData[y * renderer->Viewport.x + x] = { ray->Direction.x, ray->Direction.y, ray->Direction.z, 1.0f }; + + // we want to iterate over every object in the scene and then ask that object for an intersection + for (auto& obj : scene::scene_get_renderables(renderer->Scene)) { + rays::object_ray_collide(obj, ray); + } } } } diff --git a/src/renderer/scenetracer.cpp b/src/renderer/scenetracer.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/src/renderer/scenetracer.hpp b/src/renderer/scenetracer.hpp deleted file mode 100644 index e69de29..0000000 diff --git a/src/renderer/triangle.cpp b/src/renderer/triangle.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/src/renderer/triangle.hpp b/src/renderer/triangle.hpp index e69de29..e0b96ff 100644 --- a/src/renderer/triangle.hpp +++ b/src/renderer/triangle.hpp @@ -0,0 +1,8 @@ +#pragma once + +namespace inferno::graphics::rays { + + +} + +