From 93a90e029149fa1dd699bc805911b5779d984f33 Mon Sep 17 00:00:00 2001 From: IlyaShurupov Date: Thu, 19 Oct 2023 19:11:29 +0300 Subject: [PATCH] RT Multisampling --- RayTracer/applications/SceneLoad.cpp | 11 +++ RayTracer/applications/rsc/cube/script.lua | 16 +++- RayTracer/applications/rsc/normals/script.lua | 18 ++++ RayTracer/applications/rsc/scene/script.lua | 3 +- RayTracer/private/RayTracer.cpp | 82 +++++++++++++------ RayTracer/public/RayTracer.hpp | 1 + TODO | 26 ++++-- 7 files changed, 120 insertions(+), 37 deletions(-) diff --git a/RayTracer/applications/SceneLoad.cpp b/RayTracer/applications/SceneLoad.cpp index f7996b1..18e7918 100644 --- a/RayTracer/applications/SceneLoad.cpp +++ b/RayTracer/applications/SceneLoad.cpp @@ -78,6 +78,17 @@ int readRenderSettings(lua_State* L, tp::RayTracer::RenderSettings& settings) { } lua_pop(L, 1); // Pop the 'spray' field + // Read depth field + lua_getfield(L, -1, "multisampling"); + if (lua_isnumber(L, -1)) { + settings.multisampling = (int) lua_tonumber(L, -1); + } else { + printf("RenderSettings 'depth' field is missing or not a number.\n"); + lua_pop(L, 1); // Pop the 'depth' field + return 0; // Error + } + lua_pop(L, 1); // Pop the 'depth' field + return 1; // Success } diff --git a/RayTracer/applications/rsc/cube/script.lua b/RayTracer/applications/rsc/cube/script.lua index 887b884..2fd4b9b 100644 --- a/RayTracer/applications/rsc/cube/script.lua +++ b/RayTracer/applications/rsc/cube/script.lua @@ -9,7 +9,17 @@ Camera = { Lights = { { - pos = { 4, 2, 3 }, - intensity = 5 - } + pos = { -0.5, 3.5, 1 }, + intensity = 1 + }, + { + pos = { 0, 0, 1 }, + intensity = 0.5 + }, +} + +RenderSettings = { + depth = 1, + spray = 10, + multisampling = 1, } \ No newline at end of file diff --git a/RayTracer/applications/rsc/normals/script.lua b/RayTracer/applications/rsc/normals/script.lua index 7170e33..09e45ab 100644 --- a/RayTracer/applications/rsc/normals/script.lua +++ b/RayTracer/applications/rsc/normals/script.lua @@ -6,3 +6,21 @@ Camera = { size_x = 400, size_y = 600, } + + +Lights = { + { + pos = { -0.5, 3.5, 1 }, + intensity = 1 + }, + { + pos = { 0, 0, 1 }, + intensity = 0.5 + }, +} + +RenderSettings = { + depth = 1, + spray = 10, + multisampling = 1, +} \ No newline at end of file diff --git a/RayTracer/applications/rsc/scene/script.lua b/RayTracer/applications/rsc/scene/script.lua index ac2cd3b..f0146f9 100644 --- a/RayTracer/applications/rsc/scene/script.lua +++ b/RayTracer/applications/rsc/scene/script.lua @@ -20,5 +20,6 @@ Lights = { RenderSettings = { depth = 1, - spray = 10, + spray = 3, + multisampling = 16, } \ No newline at end of file diff --git a/RayTracer/private/RayTracer.cpp b/RayTracer/private/RayTracer.cpp index de01eb1..0964dcf 100644 --- a/RayTracer/private/RayTracer.cpp +++ b/RayTracer/private/RayTracer.cpp @@ -156,50 +156,80 @@ void RayTracer::render(const Scene& scene, OutputBuffers& out, const RenderSetti ualni currIter = 0; halnf maxDepth = 0; - halnf minDepth = mScene->mCamera.getFar(); + halnf minDepth = mScene->mCamera.getFar() * mSettings.multisampling; + + auto accumulateColor = [](RGBA& col, const RGBA& in) { + col.r += in.r; + col.g += in.g; + col.b += in.b; + col.a = 1; + }; + + auto divideColor = [](RGBA& col, const halnf num) { + col.r /= num; + col.g /= num; + col.b /= num; + }; for (auto i = 0; i < mSettings.size.x; i++) { for (auto j = 0; j < mSettings.size.y; j++) { - iterPoint = planeLeftTop + ((deltaX * (halnf) i) + (deltaY * (halnf) j)); - ray.dir = (iterPoint - pos).unitV(); + for (auto sample = 0; sample < mSettings.multisampling; sample++) { + auto randX = randomFloat(); + auto randY = randomFloat(); - castRay(ray, castData, mScene->mCamera.getFar()); + iterPoint = planeLeftTop + ((deltaX * (halnf) (i + randX)) + (deltaY * (halnf) (j + randY))); + ray.dir = (iterPoint - pos).unitV(); - if (castData.hit) { - LightData lightData; - cycle(castData, lightData, mSettings.depth); + castRay(ray, castData, mScene->mCamera.getFar()); - const auto normal = castData.trig->getNormal(); - const auto depth = (halnf) (castData.hitPos - ray.pos).length(); + if (castData.hit) { + LightData lightData; + cycle(castData, lightData, mSettings.depth); - lightData.intensity = clamp(lightData.intensity, 0.f, 1.f); - RGBA col = {lightData.intensity, lightData.intensity, lightData.intensity, 1.f}; + const auto normal = castData.trig->getNormal(); + const auto depth = (halnf) (castData.hitPos - ray.pos).length(); - out.color.set({i, j}, col); - out.normals.set({i, j}, {normal.x * 0.5f + 0.5f, normal.y * 0.5f + 0.5f, normal.z * 0.5f + 0.5f, 1.f}); - out.depth.set({i, j}, {depth, depth, depth, 1.f}); + lightData.intensity = clamp(lightData.intensity, 0.f, 1.f); + RGBA col = {lightData.intensity, lightData.intensity, lightData.intensity, 1.f}; - if (maxDepth < depth) { - maxDepth = depth; - } - if (minDepth > depth) { - minDepth = depth; + accumulateColor(out.color.get({i, j}), col); + accumulateColor(out.normals.get({i, j}), {normal.x * 0.5f + 0.5f, normal.y * 0.5f + 0.5f, normal.z * 0.5f + 0.5f, 1.f}); + accumulateColor(out.depth.get({i, j}), {depth, depth, depth, 1.f}); + + } else { + out.color.set({i, j}, 0.f); + out.normals.set({i, j}, 0.f); + out.depth.set({i, j}, 0.f); } - } else { - out.color.set({i, j}, 0.f); - out.normals.set({i, j}, 0.f); - out.depth.set({i, j}, 0.f); + // auto tmp = buff.get({i, j}); + // printf(" %f, %f, %f, %f, ", tmp.r, tmp.g, tmp.b, tmp.a); } - // auto tmp = buff.get({i, j}); - // printf(" %f, %f, %f, %f, ", tmp.r, tmp.g, tmp.b, tmp.a); - mProgress.percentage = (halnf) currIter / (halnf) maxIterations; currIter++; } } + for (auto i = 0; i < mSettings.size.x * mSettings.size.y; i++) { + divideColor(out.color.getBuff()[i], (halnf) mSettings.multisampling); + divideColor(out.normals.getBuff()[i], (halnf) mSettings.multisampling); + divideColor(out.depth.getBuff()[i], (halnf) mSettings.multisampling); + } + + for (auto i = 0; i < mSettings.size.x * mSettings.size.y; i++) { + if (!out.depth.getBuff()[i].a) { + continue; + } + const auto depth = out.depth.getBuff()[i].r; + if (maxDepth < depth) { + maxDepth = depth; + } + if (minDepth > depth) { + minDepth = depth; + } + } + for (auto i = 0; i < mSettings.size.x * mSettings.size.y; i++) { auto& col = out.depth.getBuff()[i]; if (col.a == 1.f) { diff --git a/RayTracer/public/RayTracer.hpp b/RayTracer/public/RayTracer.hpp index 9506f14..3af6e81 100644 --- a/RayTracer/public/RayTracer.hpp +++ b/RayTracer/public/RayTracer.hpp @@ -48,6 +48,7 @@ namespace tp { struct RenderSettings { uhalni depth = 2; uhalni spray = 1; + ualni multisampling = 1; Vec2I size; }; diff --git a/TODO b/TODO index 073e706..fc8f9a9 100644 --- a/TODO +++ b/TODO @@ -9,14 +9,26 @@ Make two grammars Regular and Context-free For each grammar make grammar rules parser, example sentence generation and sentence parsing Make automations itself a universal tool - NFA DFA conversions -RayTracer: - Core: - Normals - Lua: - Camera Settings - Light Sources Settings (Point, Direction, Spot) +Math: + FFT +RayTracer: + Features: + Normals flag + Material, Normals per trig info + + Quality: + Render eq + Materials + Lenses + Exposure + + Efficiency: + Casting Accelerators + Important sampling + Threading + Parser: CF Grammar: optimize generation of sentences @@ -72,4 +84,4 @@ Utils: Save leaks and then use in debugging to break when the same call occurs? TextEditor: - Implement \ No newline at end of file + Implement