diff --git a/src/main.cpp b/src/main.cpp index 79abbf5..38cba7b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,7 +10,7 @@ int main() Window window(1920, 1080); scene.startRender( Camera{ - .position = glm::vec3(5, 5, 5), + .position = glm::vec3(3, 3, 3), .direction = glm::vec3(-1, -1, -1), }, RenderParameter{ diff --git a/src/scene/Renderer.cpp b/src/scene/Renderer.cpp index cb27890..81db0b3 100644 --- a/src/scene/Renderer.cpp +++ b/src/scene/Renderer.cpp @@ -7,10 +7,10 @@ Renderer::Renderer() { bvh.addDirectionalLight(DirectionalLight{ - .direction = glm::normalize(glm::vec3(-0.4f, -0.2f, -0.6f)), + .direction = glm::normalize(glm::vec3(-0.2f, -0.2f, -0.2f)), .color = glm::vec3(1, 1, 1), }); - bvh.addModels(ModelLoader::loadModel("../res/models/box.glb"), + bvh.addModels(ModelLoader::loadModel("../res/models/cube.fbx"), glm::mat4(glm::vec4(1.0f, 0.0f, 0.0f, 0.0f), glm::vec4(0.0f, 1.0f, 0.0f, 0.0f), glm::vec4(0.0f, 0.0f, 1.0f, 0.0f), glm::vec4(0.0f, 0.0f, 0.0f, 1.0f))); bvh.generate(); @@ -106,7 +106,7 @@ void Renderer::render(Camera camera, RenderParameter params) std::cout << std::chrono::duration_cast(end - start).count() << std::endl; for (uint32_t i = 0; i < accumulator.size(); ++i) { - image[i] = glm::pow(glm::max((accumulator[i] / float(samp)), 0.0f), glm::vec3(0.45f)); + image[i] = glm::pow(glm::max((accumulator[i] / float(samp+1)), 0.0f), glm::vec3(0.45f)); } } } diff --git a/src/scene/Scene.cpp b/src/scene/Scene.cpp index 1232868..42c37e8 100644 --- a/src/scene/Scene.cpp +++ b/src/scene/Scene.cpp @@ -39,7 +39,7 @@ void Scene::generate() indicesPool.push_back(model->indices[i]); edgesPool.push_back(model->edges[i * 2 + 0]); edgesPool.push_back(model->edges[i * 2 + 1]); - faceNormalsPool.push_back(model->faceNormals[i]); + faceNormalsPool.push_back(glm::normalize(model->faceNormals[i])); } pendingNodes.push_back(std::make_unique(model->boundingBox, ref)); models.pop_back(); @@ -81,18 +81,9 @@ extern glm::vec3 rnd01; void Scene::traceRay(Ray ray, Payload& payload, const float tmin, const float tmax) const noexcept { - auto results = generateIntersections(hierarchy, ray, tmin, tmax); - float closestT = std::numeric_limits::max(); - IntersectionInfo info; - for (uint32_t i = 0; i < results.size(); ++i) - { - if (results[i].hitInfo.t < closestT) - { - closestT = results[i].hitInfo.t; - info = results[i]; - } - } - if (closestT < std::numeric_limits::max()) + IntersectionInfo info = generateIntersections(hierarchy, ray, tmin, tmax); + + if (info.hitInfo.t < std::numeric_limits::max()) { // russian roulette ray termination float p = std::max(std::max(info.brdf.albedo.x, info.brdf.albedo.y), info.brdf.albedo.z); @@ -118,7 +109,7 @@ void Scene::traceRay(Ray ray, Payload& payload, const float tmin, const float tm // if there is an intersection, the light is occluded so no lighting if (!testIntersection(hierarchy, Ray(info.hitInfo.position, -d.direction), 1e-4, 1e20)) { - payload.accumulatedRadiance += info.brdf.evaluate(info.hitInfo, -ray.direction, d.direction, d.color); + payload.accumulatedRadiance += info.brdf.evaluate(info.hitInfo, -ray.direction, -d.direction, d.color); } } for (const auto& p : pointLights) @@ -165,7 +156,7 @@ bool Scene::testIntersection(const PNode& currentNode, const Ray ray, const floa return leftResults || rightResults; } -std::vector Scene::generateIntersections(const PNode& currentNode, const Ray ray, const float tmin, +IntersectionInfo Scene::generateIntersections(const PNode& currentNode, const Ray ray, const float tmin, float tmax) const noexcept { if (!currentNode->aabb.intersects(ray, tmin, tmax)) @@ -176,14 +167,10 @@ std::vector Scene::generateIntersections(const PNode& currentN { return intersectModel(currentNode->model, ray, tmin, tmax); } - auto leftResults = generateIntersections(currentNode->left, ray, tmin, tmax); - auto rightResults = generateIntersections(currentNode->right, ray, tmin, tmax); + auto leftResult = generateIntersections(currentNode->left, ray, tmin, tmax); + auto rightResult = generateIntersections(currentNode->right, ray, tmin, tmax); - for (auto& it : rightResults) - { - leftResults.push_back(std::move(it)); - } - return leftResults; + return leftResult.hitInfo.t < rightResult.hitInfo.t ? leftResult : rightResult; } bool Scene::testModel(const ModelReference& reference, const Ray ray, const float tmin, float tmax) const noexcept @@ -234,11 +221,10 @@ bool Scene::testModel(const ModelReference& reference, const Ray ray, const floa return false; } -std::vector Scene::intersectModel(const ModelReference& reference, const Ray ray, const float tmin, +IntersectionInfo Scene::intersectModel(const ModelReference& reference, const Ray ray, const float tmin, float tmax) const noexcept { - std::vector intersection = {}; - float distance = 0; + IntersectionInfo intersection = {}; for (size_t posIndex = 0, edgeIndex = 0, normalIndex = 0; posIndex < reference.numIndices; posIndex++, edgeIndex += 2, normalIndex++) { @@ -280,13 +266,16 @@ std::vector Scene::intersectModel(const ModelReference& refere if (resultVector.x < tmin || resultVector.x > tmax) continue; - intersection.push_back(IntersectionInfo{ + if (intersection.hitInfo.t < resultVector.x) + continue; + + intersection = IntersectionInfo{ .hitInfo = { .t = resultVector.x, .position = ray.origin + ray.direction * resultVector.x, .normal = n, - .normalLight = n, // todo: flip based on something, idk what + .normalLight = glm::dot(n, ray.direction) < 0 ? n : -n, .texCoords = texCoords, }, .brdf = @@ -294,8 +283,7 @@ std::vector Scene::intersectModel(const ModelReference& refere .albedo = glm::vec3(texCoords, 0.0f), .emissive = glm::vec3(0.0f, 0.0f, 0.0f), }, - }); - distance = resultVector.x; + }; } return intersection; diff --git a/src/scene/Scene.h b/src/scene/Scene.h index 0fa5101..1cb610c 100644 --- a/src/scene/Scene.h +++ b/src/scene/Scene.h @@ -62,7 +62,7 @@ private: // tests if a ray intersects any geometry, no hit information, for shadow rays bool testIntersection(const PNode& currentNode, const Ray ray, const float tmin, const float tmax) const noexcept; - std::vector generateIntersections(const PNode& currentNode, const Ray ray, const float tmin, const float tmax) const noexcept; + IntersectionInfo generateIntersections(const PNode& currentNode, const Ray ray, const float tmin, const float tmax) const noexcept; bool testModel(const ModelReference& reference, const Ray ray, const float tmin, const float tmax) const noexcept; - std::vector intersectModel(const ModelReference& reference, const Ray ray, const float tmin, const float tmax) const noexcept; + IntersectionInfo intersectModel(const ModelReference& reference, const Ray ray, const float tmin, const float tmax) const noexcept; }; \ No newline at end of file diff --git a/src/util/BRDF.cpp b/src/util/BRDF.cpp index 89a12a9..9bf723a 100644 --- a/src/util/BRDF.cpp +++ b/src/util/BRDF.cpp @@ -9,5 +9,6 @@ glm::vec3 BRDF::evaluate(HitInfo hit, glm::vec3 viewDir, glm::vec3 lightDir, glm glm::vec3 h = glm::normalize(lightDir + viewDir); float specular = pow(std::min(std::max(glm::dot(normal, h), 0.0f), 1.0f), shininess); - return (albedo * diffuse * lightColor) + (specularColor * specular); + return (albedo * diffuse * lightColor); + //+(specularColor * specular); } diff --git a/src/util/BRDF.h b/src/util/BRDF.h index fb57b78..fe456de 100644 --- a/src/util/BRDF.h +++ b/src/util/BRDF.h @@ -11,7 +11,7 @@ struct BRDF glm::vec3 albedo = glm::vec3(1, 1, 1); float alpha = 1; glm::vec3 specularColor = glm::vec3(1, 1, 1); - float shininess = 0; + float shininess = 0.04; glm::vec3 emissive = glm::vec3(0, 0, 0); MaterialType materialType; glm::vec3 evaluate(struct HitInfo hit, glm::vec3 viewDir, glm::vec3 lightDir, glm::vec3 lightColor); diff --git a/src/util/Ray.h b/src/util/Ray.h index 47f73d9..8f0669b 100644 --- a/src/util/Ray.h +++ b/src/util/Ray.h @@ -17,7 +17,7 @@ struct Ray struct HitInfo { - float t; + float t = std::numeric_limits::max(); glm::vec3 position; glm::vec3 normal; // not entirely sure what that does diff --git a/src/window/Window.cpp b/src/window/Window.cpp index 1d5d00c..e6a5f5a 100644 --- a/src/window/Window.cpp +++ b/src/window/Window.cpp @@ -14,6 +14,7 @@ Window::Window(int width, int height) : width(width), height(height) glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // We don't want the old OpenGL window = glfwCreateWindow(width, height, "RayTracer", nullptr, nullptr); + glfwSwapInterval(1); glfwMakeContextCurrent(window); IMGUI_CHECKVERSION();