diff --git a/renderer/README.md b/renderer/README.md index 0a34d32..55a3f38 100644 --- a/renderer/README.md +++ b/renderer/README.md @@ -19,7 +19,7 @@ --- -## Diagnostics (1920x1080, 500 samples) +## Diagnostics (1920x1080, 128 samples) diff --git a/renderer/core/include/scene.hpp b/renderer/core/include/scene.hpp index e08d882..b16fb49 100644 --- a/renderer/core/include/scene.hpp +++ b/renderer/core/include/scene.hpp @@ -19,10 +19,16 @@ class Scene { std::vector vertexIndices; std::vector vertices; std::vector texCoords; - glm::mat4 transform; std::vector primitives; - Mesh() : transform(glm::mat4(1.0f)) {} + Mesh() = default; + }; + + struct Object { + Mesh mesh; + glm::mat4 transform; + + Object() : transform(glm::mat4(1.0f)) {} }; struct TextureData { @@ -76,7 +82,7 @@ class Scene { Camera camera; Sun sun; - std::vector meshes; + std::vector objects; std::vector materials; glm::vec3 backgroundColor; @@ -87,7 +93,7 @@ class Scene { Camera getCamera() const noexcept; Sun getSun() const noexcept; glm::vec3 getBackgroundColor() const noexcept; - const std::vector& getMeshes() const noexcept; + const std::vector& getObjects() const noexcept; const std::vector& getMaterials() const noexcept; const std::vector& getTexturesData() const noexcept; void setCamera(const Camera& camera); diff --git a/renderer/core/src/render-engine.cpp b/renderer/core/src/render-engine.cpp index cc488ea..9e8328d 100644 --- a/renderer/core/src/render-engine.cpp +++ b/renderer/core/src/render-engine.cpp @@ -334,15 +334,15 @@ void RenderEngine::uploadGPUBuffers(const GPUData& gpuData, const BVH& bvh) { RenderEngine::GPUData RenderEngine::convertSceneToGPUData(const Scene& scene) { logger.debug("Preparing scene data for GPU"); GPUData data; - for (const auto& mesh : scene.getMeshes()) { + for (const auto& object : scene.getObjects()) { int indexOffset = data.vertices.size(); - for (const auto& v : mesh.vertices) data.vertices.push_back(mesh.transform * glm::vec4(v, 1.0)); - for (const auto& uv : mesh.texCoords) data.texCoords.push_back(glm::vec4(uv.x, uv.y, 1.0f, 1.0f)); + for (const auto& v : object.mesh.vertices) data.vertices.push_back(object.transform * glm::vec4(v, 1.0)); + for (const auto& uv : object.mesh.texCoords) data.texCoords.push_back(glm::vec4(uv.x, uv.y, 1.0f, 1.0f)); - for (const auto& primitive : mesh.primitives) { + for (const auto& primitive : object.mesh.primitives) { for (int i = primitive.startVertexIndex; i < primitive.vertexIndicesCount + primitive.startVertexIndex; i++) { - data.vertexIndices.push_back(mesh.vertexIndices[i] + indexOffset); + data.vertexIndices.push_back(object.mesh.vertexIndices[i] + indexOffset); } for (int i = 0; i < primitive.vertexIndicesCount / 3; i++) { data.materialIndices.push_back(primitive.materialId); diff --git a/renderer/core/src/scene-loader.cpp b/renderer/core/src/scene-loader.cpp index 7577306..7d06aa8 100644 --- a/renderer/core/src/scene-loader.cpp +++ b/renderer/core/src/scene-loader.cpp @@ -172,10 +172,11 @@ void SceneLoader::loadNode(const fastgltf::Node& node, const fastgltf::Asset& as /* Loading meshes*/ if (node.meshIndex.has_value()) { + Scene::Object object; const auto& gltfMesh = asset.meshes[node.meshIndex.value()]; - Scene::Mesh mesh = loadMesh(gltfMesh, asset); - mesh.transform = transform; - scene.meshes.push_back(std::move(mesh)); + object.mesh = loadMesh(gltfMesh, asset); + object.transform = transform; + scene.objects.push_back(std::move(object)); } for (const auto& child : node.children) { loadNode(asset.nodes[child], asset, scene, transform); @@ -326,9 +327,9 @@ Scene SceneLoader::loadGltf(const fastgltf::Asset& asset) { logger.warning("Camera was not found in file. Default camera will be applied"); glm::vec3 boxMax(-std::numeric_limits::infinity()), boxMin(std::numeric_limits::infinity()); bool empty = true; - for (const auto& mesh : scene.getMeshes()) { - for (auto v : mesh.vertices) { - v = glm::vec3(mesh.transform * glm::vec4(v, 1.0)); + for (const auto& object : scene.getObjects()) { + for (auto v : object.mesh.vertices) { + v = glm::vec3(object.transform * glm::vec4(v, 1.0)); empty = false; boxMax = glm::max(boxMax, v); boxMin = glm::min(boxMin, v); @@ -356,7 +357,7 @@ Scene SceneLoader::loadGltf(const fastgltf::Asset& asset) { for (const auto& material : asset.materials) { scene.materials.push_back(loadMaterial(material, scene.textures, asset)); } - logger.info(std::format("Scene loaded. Meshes: {}, Materials: {}, Textures: {}", scene.meshes.size(), + logger.info(std::format("Scene loaded. Meshes: {}, Materials: {}, Textures: {}", scene.objects.size(), scene.materials.size(), scene.textures.size())); return scene; } @@ -364,9 +365,9 @@ Scene SceneLoader::loadGltf(const fastgltf::Asset& asset) { void SceneLoader::addPlane(Scene& scene, float planeSize) { glm::vec3 boxMax(-std::numeric_limits::infinity()), boxMin(std::numeric_limits::infinity()); bool empty = true; - for (const auto& mesh : scene.getMeshes()) { - for (auto v : mesh.vertices) { - v = glm::vec3(mesh.transform * glm::vec4(v, 1.0)); + for (const auto& object : scene.getObjects()) { + for (auto v : object.mesh.vertices) { + v = glm::vec3(object.transform * glm::vec4(v, 1.0)); empty = false; boxMax = glm::max(boxMax, v); boxMin = glm::min(boxMin, v); @@ -378,13 +379,13 @@ void SceneLoader::addPlane(Scene& scene, float planeSize) { } else { center = glm::vec3(0, 0, 0); } - Scene::Mesh planeMesh; - planeMesh.transform = glm::mat4(1.0); - planeMesh.vertices = {glm::vec3(center.x - planeSize, boxMin.y, center.z + planeSize), - glm::vec3(center.x - planeSize, boxMin.y, center.z - planeSize), - glm::vec3(center.x + planeSize, boxMin.y, center.z - planeSize), - glm::vec3(center.x + planeSize, boxMin.y, center.z + planeSize)}; - planeMesh.vertexIndices = {3, 1, 0, 2, 1, 3}; + Scene::Object plane; + plane.transform = glm::mat4(1.0); + plane.mesh.vertices = {glm::vec3(center.x - planeSize, boxMin.y, center.z + planeSize), + glm::vec3(center.x - planeSize, boxMin.y, center.z - planeSize), + glm::vec3(center.x + planeSize, boxMin.y, center.z - planeSize), + glm::vec3(center.x + planeSize, boxMin.y, center.z + planeSize)}; + plane.mesh.vertexIndices = {3, 1, 0, 2, 1, 3}; Scene::Mesh::Primitive primitive1, primitive2; primitive1.startVertexIndex = 0; @@ -395,8 +396,8 @@ void SceneLoader::addPlane(Scene& scene, float planeSize) { primitive1.materialId = scene.materials.size() - 1; primitive2.materialId = scene.materials.size() - 1; - planeMesh.primitives.push_back(primitive1); - planeMesh.primitives.push_back(primitive2); + plane.mesh.primitives.push_back(primitive1); + plane.mesh.primitives.push_back(primitive2); - scene.meshes.push_back(planeMesh); + scene.objects.push_back(plane); } diff --git a/renderer/core/src/scene.cpp b/renderer/core/src/scene.cpp index 607d33e..0d3d9f2 100644 --- a/renderer/core/src/scene.cpp +++ b/renderer/core/src/scene.cpp @@ -5,7 +5,7 @@ Scene::Scene() : backgroundColor(0.0f, 0.0f, 0.0f) {} Scene::Camera Scene::getCamera() const noexcept { return camera; } glm::vec3 Scene::getBackgroundColor() const noexcept { return backgroundColor; } Scene::Sun Scene::getSun() const noexcept { return sun; } -const std::vector& Scene::getMeshes() const noexcept { return meshes; } +const std::vector& Scene::getObjects() const noexcept { return objects; } const std::vector& Scene::getMaterials() const noexcept { return materials; } const std::vector& Scene::getTexturesData() const noexcept { return textures; } void Scene::setCamera(const Scene::Camera& camera) { this->camera = camera; } diff --git a/renderer/images/fox-heat.png b/renderer/images/fox-heat.png index 75e3473..27617d0 100644 Binary files a/renderer/images/fox-heat.png and b/renderer/images/fox-heat.png differ diff --git a/renderer/images/fox-raw.png b/renderer/images/fox-raw.png index a575bf4..d9b2981 100644 Binary files a/renderer/images/fox-raw.png and b/renderer/images/fox-raw.png differ diff --git a/renderer/images/fox.png b/renderer/images/fox.png index 5e37fbb..fd667fb 100644 Binary files a/renderer/images/fox.png and b/renderer/images/fox.png differ diff --git a/renderer/shaders/path-tracing.glsl b/renderer/shaders/path-tracing.glsl index a8925fb..81990d5 100644 --- a/renderer/shaders/path-tracing.glsl +++ b/renderer/shaders/path-tracing.glsl @@ -511,13 +511,17 @@ void main() { float variance = 0.0; float error = 0.0; + float stdError = 0.0; if (N >= 2) { - variance = M2 / float(N - 1); - error = sqrt(variance / float(N)) / (abs(mean) + 0.0001); + float variance = M2 / float(N - 1); + stdError = sqrt(variance / float(N)); } - imageStore(heatMap, pixel, vec4(heatColor(error), 1.0)); + float lo = log(1e-3); + float hi = log(1e-2); + float t = clamp((log(max(stdError, 1e-8)) - lo) / (hi - lo), 0.0, 1.0); + imageStore(heatMap, pixel, vec4(heatColor(t), 1.0)); - if (N >= 32 && error < 0.01) { + if (N >= 32 && stdError < 0.001) { return; } diff --git a/renderer/tests/scene-loader/test-scene-loader.cpp b/renderer/tests/scene-loader/test-scene-loader.cpp index 5040f9e..45448de 100644 --- a/renderer/tests/scene-loader/test-scene-loader.cpp +++ b/renderer/tests/scene-loader/test-scene-loader.cpp @@ -24,9 +24,10 @@ TEST(SceneLoaderTest, loadSceneCorrectly) { EXPECT_NO_THROW(scene = loader.loadGltfFromFile("tests/data/test-scene.glb")); /* Testing geometry */ - const auto& meshes = scene.getMeshes(); - ASSERT_EQ(meshes.size(), 1); - const auto& mesh = meshes[0]; + const auto& objects = scene.getObjects(); + ASSERT_EQ(objects.size(), 1); + const auto& object = objects[0]; + const auto& mesh = object.mesh; std::vector expectedVertices = { glm::vec3(0.5, -0.5, 0.5), glm::vec3(-0.5, -0.5, 0.5), glm::vec3(0.5, 0.5, 0.5), @@ -62,7 +63,7 @@ TEST(SceneLoaderTest, loadSceneCorrectly) { {0.9397, 0.6840, 0, 2}, {0, 0, 1, 0}, {0.3420, -1.8794, 0, 0}, {0, 0, 0, 1}}; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { - EXPECT_NEAR(mesh.transform[i][j], expectedTransform[j][i], 0.001); + EXPECT_NEAR(object.transform[i][j], expectedTransform[j][i], 0.001); } }