From 351a5d842ea7f102a4f3a74b3a67c32025354178 Mon Sep 17 00:00:00 2001 From: IlyaShurupov Date: Tue, 18 Jun 2024 23:47:19 +0300 Subject: [PATCH] fix ray tracer projection plane --- 3DEditor/private/Editor.cpp | 3 ++- Containers/public/Buffer2D.hpp | 18 ++++++++++++++++++ Math/private/Camera.cpp | 4 ++-- Math/public/Camera.hpp | 6 ++++-- RayTracer/private/RayTracer.cpp | 20 +++++++++----------- RayTracer/tests/Test.cpp | 2 ++ 6 files changed, 37 insertions(+), 16 deletions(-) diff --git a/3DEditor/private/Editor.cpp b/3DEditor/private/Editor.cpp index e2de4e3..6406a9c 100644 --- a/3DEditor/private/Editor.cpp +++ b/3DEditor/private/Editor.cpp @@ -58,7 +58,7 @@ void Editor::loadDefaults() { void Editor::setViewportSize(const Vec2F& size) { // TODO remove - mScene.mCamera.rotate(0.01f, 0.0); + // mScene.mCamera.rotate(0.01f, 0.0); mScene.mRenderSettings.size = size; @@ -72,6 +72,7 @@ Editor::~Editor() { void Editor::renderPathFrame() { mPathRenderer.render(mScene, mPathTracerBuffers, mScene.mRenderSettings); + // mPathTracerBuffers.color.flipY(); { glBindTexture(GL_TEXTURE_2D, mPathRenderTexture); diff --git a/Containers/public/Buffer2D.hpp b/Containers/public/Buffer2D.hpp index cff02f1..d0a4431 100644 --- a/Containers/public/Buffer2D.hpp +++ b/Containers/public/Buffer2D.hpp @@ -59,6 +59,24 @@ namespace tp { tType* getBuff() const { return mBuff; } + void flipY() { + for (Index i = 0; i < mSize.x; i++) { + const auto lenIdx = mSize.y - 1; + for (Index j = 0; j < mSize.y / 2; j++) { + swap(get({i, j}), get({i, lenIdx - j})); + } + } + } + + void flipX() { + for (Index i = 0; i < mSize.y; i++) { + const auto lenIdx = mSize.x - 1; + for (Index j = 0; j < mSize.x / 2; j++) { + swap(get({i, j}), get({i, lenIdx - j})); + } + } + } + inline tType& get(const Index2D& at) { DEBUG_ASSERT(mBuff && at.x < mSize.x && at.y < mSize.y && at.x >= 0 && at.y >= 0) return *(mBuff + mSize.x * at.y + at.x); diff --git a/Math/private/Camera.cpp b/Math/private/Camera.cpp index f1cc43e..fffc32e 100644 --- a/Math/private/Camera.cpp +++ b/Math/private/Camera.cpp @@ -57,7 +57,7 @@ Mat4F Camera::calculateProjectionMatrix() const { return out; } -Vec3F Camera::project(Vec2F normalized) { +Vec3F Camera::project(Vec2F normalized) const { auto camMat = calculateTransformationMatrix(); auto inv = camMat.inv(); @@ -68,7 +68,7 @@ Vec3F Camera::project(Vec2F normalized) { return Vec3F(inv * world_pos4); } -Vec2F Camera::project(const Vec3F& world) { +Vec2F Camera::project(const Vec3F& world) const { Vec4F world_pos4(world.x, world.y, world.z, 1); Vec4F transformed = calculateViewMatrix() * world_pos4; transformed = calculateProjectionMatrix() * transformed; diff --git a/Math/public/Camera.hpp b/Math/public/Camera.hpp index 11f4b73..e4d4adc 100644 --- a/Math/public/Camera.hpp +++ b/Math/public/Camera.hpp @@ -39,8 +39,10 @@ namespace tp { [[nodiscard]] Mat4F calculateTransformationMatrix() const; [[nodiscard]] Mat calculateProjectionMatrix() const; [[nodiscard]] Mat calculateViewMatrix() const; - [[nodiscard]] Vec3F project(Vec2F normalized); - [[nodiscard]] Vec2F project(const Vec3F& world); + + // from -1 -1 is top left corner. z is distance to the target + [[nodiscard]] Vec3F project(Vec2F normalized) const; + [[nodiscard]] Vec2F project(const Vec3F& world) const; [[nodiscard]] static Vec2F project(const tp::Vec3F& world, const tp::Mat4F& viewMat, const tp::Mat4F& projMat); }; } diff --git a/RayTracer/private/RayTracer.cpp b/RayTracer/private/RayTracer.cpp index b975c59..994e5e8 100644 --- a/RayTracer/private/RayTracer.cpp +++ b/RayTracer/private/RayTracer.cpp @@ -127,24 +127,22 @@ void RayTracer::render(const Scene& scene, OutputBuffers& out, const RenderSetti mSettings = settings; auto pos = mScene->mCamera.getPos(); - auto fov = mScene->mCamera.getFOV(); - auto height = sqrt(mScene->mCamera.getRatio()); - auto width = 1.f / height; - auto forward = mScene->mCamera.getForward(); - auto up = mScene->mCamera.getUp(); - auto right = forward.cross(up); - auto planeCenter = pos + (forward * halnf(width / (2.f * tan(fov / 2.f)))); - auto planeCenterOffset = (up * (halnf) height / 2.f) - (right * (halnf) width / 2.f); + auto camera = mScene->mCamera; - auto planeLeftTop = planeCenter + planeCenterOffset; + const auto planeLeftTop = camera.project({ -1, -1 }); + const auto planeRightTop = camera.project({ 1, -1 }); + const auto planeRightBottom = camera.project({ 1, 1 }); + + const auto up = (planeRightBottom - planeRightTop); + const auto right = planeRightTop - planeLeftTop; RayCastData castData; Ray ray = { { 0, 0, 0 }, pos }; Vec3F iterPoint = { 0, 0, 0 }; - Vec3F deltaX = right * halnf(width / (alnf) mSettings.size.x); - Vec3F deltaY = up * halnf(-height / (alnf) mSettings.size.y); + Vec3F deltaX = right / halnf(mSettings.size.x); + Vec3F deltaY = up / halnf(mSettings.size.y); ualni maxIterations = mSettings.size.x * mSettings.size.y; ualni currIter = 0; diff --git a/RayTracer/tests/Test.cpp b/RayTracer/tests/Test.cpp index be65e18..8d37d54 100644 --- a/RayTracer/tests/Test.cpp +++ b/RayTracer/tests/Test.cpp @@ -93,6 +93,8 @@ SUITE(RayTracer) { RayTracer rt; rt.render(scene, output, settings); + output.color.flipY(); + CHECK(compareCols(output.color.get({ 6, 4 }), RGBA{ 0.560100f, 0.560100f, 0.560100f, 1.000000f })); CHECK(compareCols(output.color.get({ 6, 5 }), RGBA{ 0.353739f, 0.353739f, 0.353739f, 1.000000f })); CHECK(compareCols(output.color.get({ 6, 6 }), RGBA{ 0.242577f, 0.242577f, 0.242577f, 1.000000f }));