diff --git a/src/scene/Renderer.cpp b/src/scene/Renderer.cpp index 426111f..6b84ae6 100644 --- a/src/scene/Renderer.cpp +++ b/src/scene/Renderer.cpp @@ -93,7 +93,8 @@ void Renderer::render(Camera camera, RenderParameter params) if (intersection.has_value()) { - accumulator[w + h * params.width] = intersection->albedo; + + accumulator[w + h * params.width] = intersection->shadingInfo.albedo; } } co_return; diff --git a/src/scene/Scene.cpp b/src/scene/Scene.cpp index 348f929..7215bf8 100644 --- a/src/scene/Scene.cpp +++ b/src/scene/Scene.cpp @@ -80,9 +80,9 @@ std::optional Scene::traceRay(Ray ray) const IntersectionInfo info; for (uint32_t i = 0; i < results.size(); ++i) { - if (results[i].t < closestT) + if (results[i].hitInfo.t < closestT) { - closestT = results[i].t; + closestT = results[i].hitInfo.t; info = results[i]; } } @@ -128,14 +128,22 @@ std::optional Scene::intersectModel(const ModelReference& refe for (size_t posIndex = 0, edgeIndex = 0, normalIndex = 0; posIndex < reference.numIndices; posIndex++, edgeIndex += 2, normalIndex++) { - const auto p0 = positionPool[reference.positionOffset + indicesPool[reference.indicesOffset + posIndex].x]; - const auto p1 = positionPool[reference.positionOffset + indicesPool[reference.indicesOffset + posIndex].y]; - const auto p2 = positionPool[reference.positionOffset + indicesPool[reference.indicesOffset + posIndex].z]; + const auto i0 = indicesPool[reference.indicesOffset + posIndex].x; + const auto i1 = indicesPool[reference.indicesOffset + posIndex].y; + const auto i2 = indicesPool[reference.indicesOffset + posIndex].z; - const auto e0 = edgesPool[reference.indicesOffset + edgeIndex]; - const auto e1 = edgesPool[reference.indicesOffset + edgeIndex + 1]; + const auto& p0 = positionPool[reference.positionOffset + i0]; + const auto& p1 = positionPool[reference.positionOffset + i1]; + const auto& p2 = positionPool[reference.positionOffset + i2]; - const auto n = faceNormalsPool[reference.indicesOffset + normalIndex]; + const auto& t0 = texCoordsPool[reference.positionOffset + i0]; + const auto& t1 = texCoordsPool[reference.positionOffset + i1]; + const auto& t2 = texCoordsPool[reference.positionOffset + i2]; + + const auto& e0 = edgesPool[reference.indicesOffset + edgeIndex]; + const auto& e1 = edgesPool[reference.indicesOffset + edgeIndex + 1]; + + const auto& n = faceNormalsPool[reference.indicesOffset + normalIndex]; const auto s = ray.origin - p0; const auto s1 = glm::cross(ray.direction, e1); @@ -146,6 +154,8 @@ std::optional Scene::intersectModel(const ModelReference& refe const float b3 = 1.0f - resultVector.y - resultVector.z; + const auto texCoords = t0 * resultVector.y + t1 * resultVector.z + t2 * b3; + if (b3 < 0 || b3 > 1) continue; if (resultVector.y < 0 || resultVector.y > 1) @@ -158,10 +168,21 @@ std::optional Scene::intersectModel(const ModelReference& refe if (!intersection.has_value() || resultVector.x < distance) { - intersection = IntersectionInfo{.position = ray.origin + ray.direction * resultVector.x, - .normal = n, - .albedo = glm::vec3(0.7f, 0.7f, 0.7f), - .emissive = glm::vec3(0.0f, 0.0f, 0.0f),}; + intersection = IntersectionInfo{ + .hitInfo = + { + .t = resultVector.x, + .position = ray.origin + ray.direction * resultVector.x, + .normal = n, + .texCoords = texCoords, + }, + .shadingInfo = + { + .albedo = glm::vec3(texCoords, 0.0f), + .emissive = glm::vec3(0.0f, 0.0f, 0.0f), + .type = MaterialType::DIFFUSE, + }, + }; distance = resultVector.x; } } diff --git a/src/util/BRDF.cpp b/src/util/BRDF.cpp new file mode 100644 index 0000000..4087c7f --- /dev/null +++ b/src/util/BRDF.cpp @@ -0,0 +1,11 @@ +#include "BRDF.h" + +glm::vec3 BlinnPhong::evaluate(HitInfo hit, glm::vec3 viewDir, glm::vec3 lightDir, glm::vec3 lightColor) +{ + glm::vec3 normal = hit.normal; + float diffuse = std::max(glm::dot(normal, lightDir), 0.0f); + 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); +} \ No newline at end of file diff --git a/src/util/BRDF.h b/src/util/BRDF.h new file mode 100644 index 0000000..2cff04a --- /dev/null +++ b/src/util/BRDF.h @@ -0,0 +1,17 @@ +#pragma once +#include "Material.h" + +class BRDF +{ + virtual glm::vec3 evaluate(HitInfo hit, glm::vec3 viewDir, glm::vec3 lightDir, glm::vec3 lightColor) = 0; +}; + +class BlinnPhong : public BRDF +{ + glm::vec3 albedo = glm::vec3(1, 1, 1); + float alpha = 1; + glm::vec3 specularColor = glm::vec3(1, 1, 1); + float shininess = 0; + glm::vec3 emissive = glm::vec3(0, 0, 0); + virtual glm::vec3 evaluate(HitInfo hit, glm::vec3 viewDir, glm::vec3 lightDir, glm::vec3 lightColor); +}; \ No newline at end of file diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index fd1d686..455f720 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -1,5 +1,7 @@ target_sources(RayTracer PRIVATE + BRDF.h + BRDF.cpp Camera.h Material.h Material.cpp diff --git a/src/util/Material.cpp b/src/util/Material.cpp index 435d592..7622417 100644 --- a/src/util/Material.cpp +++ b/src/util/Material.cpp @@ -1 +1,6 @@ -#include "Material.h" \ No newline at end of file +#include "Material.h" + +std::unique_ptr Material::evaluate(HitInfo hitInfo) +{ + return std::make_unique(); +} diff --git a/src/util/Material.h b/src/util/Material.h index f4663c4..684f427 100644 --- a/src/util/Material.h +++ b/src/util/Material.h @@ -1,7 +1,20 @@ #pragma once +#include "Minimal.h" +#include "Texture.h" +#include "Ray.h" +#include "BRDF.h" + +enum class MaterialType +{ + DIFFUSE, + SPECULAR, + REFRACTIVE, +}; class Material { public: -private: + std::unique_ptr evaluate(HitInfo hitInfo); + PTexture albedoTexture; + PTexture emissiveTexture; }; \ No newline at end of file diff --git a/src/util/Model.h b/src/util/Model.h index d41c7b4..eee1ce6 100644 --- a/src/util/Model.h +++ b/src/util/Model.h @@ -1,20 +1,14 @@ #pragma once #include "Minimal.h" +#include "Material.h" #include "scene/AABB.h" #include #include -// material infos -// shading parameter -// hit data struct IntersectionInfo { - float t; - glm::vec3 position; - glm::vec3 normal; - glm::vec3 albedo; - glm::vec3 emissive; - //.... + HitInfo hitInfo; + MaterialInfo shadingInfo; }; class Model { diff --git a/src/util/Ray.h b/src/util/Ray.h index 361293c..d7ae4db 100644 --- a/src/util/Ray.h +++ b/src/util/Ray.h @@ -1,8 +1,24 @@ #pragma once #include +struct Payload +{ + glm::vec3 accumulatedRadiance = glm::vec3(0); + glm::vec3 accumulatedMaterial = glm::vec3(0); +}; + struct Ray { glm::vec3 origin; glm::vec3 direction; + uint32_t depth = 0; + Payload payload; +}; + +struct HitInfo +{ + float t; + glm::vec3 position; + glm::vec3 normal; + glm::vec2 texCoords; }; \ No newline at end of file