From 2afb65dc40cad1bd72691147a30f94bfe5fe5359 Mon Sep 17 00:00:00 2001 From: grandch Date: Tue, 13 Jun 2023 11:09:08 +0200 Subject: [PATCH 01/56] [core] add sample,pdf, bsdf methods for lambertian model --- src/Core/Material/MaterialModel.cpp | 36 +++++++++++++++++++++++ src/Core/Material/MaterialModel.hpp | 13 ++++++++ src/Core/Material/SimpleMaterialModel.cpp | 36 +++++++++++++++++++++++ src/Core/Material/SimpleMaterialModel.hpp | 4 +++ 4 files changed, 89 insertions(+) diff --git a/src/Core/Material/MaterialModel.cpp b/src/Core/Material/MaterialModel.cpp index bfd24b816d7..c1397cd2bec 100644 --- a/src/Core/Material/MaterialModel.cpp +++ b/src/Core/Material/MaterialModel.cpp @@ -1,5 +1,6 @@ #include #include +#include "MaterialModel.hpp" namespace Ra { namespace Core { @@ -8,6 +9,41 @@ void MaterialModel::displayInfo() const { using namespace Core::Utils; // log LOG( logERROR ) << "MaterialModel : unknown material type : " << m_materialType; } + +Utils::Color MaterialModel::evalBSDF( Vector3f w_i, Vector3f w_o, Vector3f normal, Vector2f uv ) { + return Utils::Color(); +} + +std::optional MaterialModel::sample( Vector3f inDir, Vector3f normal, Vector2f u ) { + return std::optional(); +} + +Scalar MaterialModel::PDF( Vector3f inDir, Vector3f outDir, Vector3f normal ) { + return 0.0f; +} + +void MaterialModel::coordinateSystem( Vector3f normal, Vector3f* tangent, Vector3f* bitangent ) { + if (std::abs(normal[0]) > std::abs(normal[1])) { + Scalar invLen = 1 / std::sqrt(normal[0] * normal[0] + normal[2] * normal[2]); + *tangent = Vector3f(-normal[2] * invLen, 0, normal[0] * invLen); + } else { + Scalar invLen = 1 / std::sqrt(normal[1] * normal[1] + normal[2] * normal[2]); + *tangent = Vector3f(0, normal[2] * invLen, -normal[1] * invLen); + } + *bitangent = normal.cross(*tangent); +} + +Vector3f MaterialModel::randomInHemisphere( Vector3f normal ) { + Vector3f vec = Vector3f::Random(3,1); + vec /= vec.norm(); + + if(vec.dot(normal) > 0) { + return vec; + } + + return -vec; +} + } // namespace Material } // namespace Core } // namespace Ra diff --git a/src/Core/Material/MaterialModel.hpp b/src/Core/Material/MaterialModel.hpp index 688ef8ff778..4da1cc8fd30 100644 --- a/src/Core/Material/MaterialModel.hpp +++ b/src/Core/Material/MaterialModel.hpp @@ -1,10 +1,15 @@ #pragma once #include +#include +#include #include #include +#include +#include + namespace Ra { namespace Core { namespace Material { @@ -30,6 +35,14 @@ class RA_CORE_API MaterialModel : public Utils::ObservableVoid /// DEBUG virtual void displayInfo() const; + virtual Utils::Color evalBSDF(Vector3f w_i, Vector3f w_o, Vector3f normal, Vector2f uv); + virtual std::optional sample(Vector3f inDir, Vector3f normal, Vector2f u); + virtual Scalar PDF(Vector3f inDir, Vector3f outDir, Vector3f normal); + + void coordinateSystem(Vector3f normal, Vector3f* tangent, Vector3f* bitangent); + + Vector3f randomInHemisphere(Vector3f normal); + private: std::string m_materialType; std::string m_name; diff --git a/src/Core/Material/SimpleMaterialModel.cpp b/src/Core/Material/SimpleMaterialModel.cpp index 37e3248e21a..0a284cd78cb 100644 --- a/src/Core/Material/SimpleMaterialModel.cpp +++ b/src/Core/Material/SimpleMaterialModel.cpp @@ -1,6 +1,7 @@ #include #include +#include "SimpleMaterialModel.hpp" namespace Ra { namespace Core { @@ -36,6 +37,41 @@ void LambertianMaterialModel::displayInfo() const { print( hasNormalTexture(), " Normal Texture : ", m_texNormal ); print( hasOpacityTexture(), " Alpha Texture : ", m_texOpacity ); } + +Utils::Color Material::LambertianMaterialModel::evalBSDF( Vector3f w_i, + Vector3f w_o, + Vector3f normal, + Vector2f uv ) { + if(w_i.dot(normal) <= 0 || w_o.dot(normal) <= 0) { + return Utils::Color::Black(); + } + + return m_kd * ( 1 / M_PI ); +} + +std::optional LambertianMaterialModel::sample( Vector3f inDir, Vector3f normal, Vector2f u ) { + // create local to normal coordinate system + Vector3f tangent, bitangent, wi; + coordinateSystem(normal, &tangent, &bitangent); + + // sample point on hemisphere with cosine-weighted distribution + Scalar r = std::sqrt(u[0]); + Scalar phi = 2 * M_PI * u[1]; + + wi[0] = r * std::cos(phi); + wi[1] = r * std::sin(phi); + wi[2] = std::sqrt(std::max(0.f, 1 - wi[0]*wi[0] - wi[1]*wi[1])); + + // transform sampled point from local to world coodinate system + Vector3 result(wi.dot(tangent), wi.dot(bitangent), wi.dot(normal)); + + return wi; +} + +Scalar LambertianMaterialModel::PDF( Vector3f inDir, Vector3f outDir, Vector3f normal ) { + return std::abs(outDir.dot(normal)) * ( 1.0 / M_PI ); +} + } // namespace Material } // namespace Core } // namespace Ra diff --git a/src/Core/Material/SimpleMaterialModel.hpp b/src/Core/Material/SimpleMaterialModel.hpp index 83d3126344d..ec9102335e1 100644 --- a/src/Core/Material/SimpleMaterialModel.hpp +++ b/src/Core/Material/SimpleMaterialModel.hpp @@ -47,6 +47,10 @@ class RA_CORE_API LambertianMaterialModel : public SimpleMaterialModel /// QUERY bool hasNormalTexture() const { return m_hasTexNormal; } + Utils::Color evalBSDF(Vector3f w_i, Vector3f w_o, Vector3f normal, Vector2f uv) override; + std::optional sample(Vector3f inDir, Vector3f normal, Vector2f u) override; + Scalar PDF(Vector3f inDir, Vector3f outDir, Vector3f normal) override; + /// DATA MEMBERS std::string m_texNormal; bool m_hasTexNormal { false }; From efd38e97641a637e5268e405bb15120ad9bfe9d4 Mon Sep 17 00:00:00 2001 From: grandch Date: Thu, 15 Jun 2023 18:39:09 +0200 Subject: [PATCH 02/56] [core] add bsdf, sample and pdf implementation for blinnphong model --- src/Core/Material/BlinnPhongMaterialModel.cpp | 75 ++++++++++++++++++- src/Core/Material/BlinnPhongMaterialModel.hpp | 6 ++ src/Core/Material/MaterialModel.cpp | 36 ++++++++- src/Core/Material/MaterialModel.hpp | 8 +- src/Core/Material/SimpleMaterialModel.cpp | 18 ++--- src/Core/Material/SimpleMaterialModel.hpp | 2 +- 6 files changed, 127 insertions(+), 18 deletions(-) diff --git a/src/Core/Material/BlinnPhongMaterialModel.cpp b/src/Core/Material/BlinnPhongMaterialModel.cpp index 5ff3a48a53e..98e730e956a 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.cpp +++ b/src/Core/Material/BlinnPhongMaterialModel.cpp @@ -1,6 +1,8 @@ #include - #include +#include "BlinnPhongMaterialModel.hpp" + +#include namespace Ra { namespace Core { @@ -24,6 +26,77 @@ void BlinnPhongMaterialModel::displayInfo() const { print( hasNormalTexture(), " Normal Texture : ", m_texNormal ); print( hasOpacityTexture(), " Alpha Texture : ", m_texOpacity ); } +Utils::Color Material::BlinnPhongMaterialModel::evalBSDF( Vector3f w_i, + Vector3f w_o, + Vector3f normal, + Vector2f uv ) { + // diffuse lambertien component + Utils::Color diffuse = m_kd / M_PI; + + // Blinn-Phong specular component + Vector3f halfway = w_i + w_o; + halfway.normalize(); + Scalar specularIntensity = (m_ns + 2.0f) / (2.0f * M_PI) * std::pow(normal.dot(halfway), m_ns); + Utils::Color specular = m_ks * specularIntensity; + + // Combine the diffuse and specular components + Utils::Color bsdf = diffuse + specular; +} + +std::optional> +BlinnPhongMaterialModel::sample( Vector3f inDir, Vector3f normal, Vector2f u ) { + /* + compute intensity of diffuse and specular + compute norm (max(1, Idiffuse + Ispecular)) + normalize Idiffuse and Ispecular + */ + + Vector3f nextDir, halfway; + + Scalar dIntensity = (m_kd.x() + m_kd.y() + m_kd.z()) / 3.f; + Scalar sIntensity = (m_ks.x() + m_ks.y() + m_ks.z()) / 3.f; + Scalar diffSpecNorm = std::max(1.f, dIntensity + sIntensity); + + dIntensity /= diffSpecNorm; + sIntensity /= diffSpecNorm; + + std::uniform_real_distribution unifDistributionRand{0, 1}; + std::minstd_rand randomEngine(std::time(nullptr)); + Scalar distrib = unifDistributionRand(randomEngine); + + // diffuse part + if(distrib < dIntensity) { + nextDir = sampleHemisphereCosineWeighted(u); + std::pair result {nextDir, cosineWeightedPDF(nextDir, normal)}; + return result; + } else if(distrib > dIntensity && distrib < dIntensity + sIntensity) { // specular part + nextDir = sampleSpecular(inDir, u); + // compute specular pdf + std::pair result; + return result; + } else { // no next dir + return {}; + } +} + +Scalar BlinnPhongMaterialModel::PDF( Vector3f inDir, Vector3f outDir, Vector3f normal ) { + Scalar dIntensity = (m_kd.x() + m_kd.y() + m_kd.z()) / 3.f; + Scalar sIntensity = (m_ks.x() + m_ks.y() + m_ks.z()) / 3.f; + Scalar diffSpecNorm = std::max(1.f, dIntensity + sIntensity); + + dIntensity /= diffSpecNorm; + sIntensity /= diffSpecNorm; + + return std::clamp(dIntensity * cosineWeightedPDF(outDir, normal) + sIntensity * specularPDF(outDir, normal), Scalar(0), Scalar(1)); +} + +Scalar BlinnPhongMaterialModel::specularPDF( Vector3f dir, Vector3f normal ) { + Scalar cosTheta = normal.dot(dir); + Scalar result = ((m_ns + 1) / (2.0f * M_PI)) * std::pow(cosTheta, m_ns); + + return result; +} + } // namespace Material } // namespace Core } // namespace Ra diff --git a/src/Core/Material/BlinnPhongMaterialModel.hpp b/src/Core/Material/BlinnPhongMaterialModel.hpp index 0fe93db1920..1555211a4c3 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.hpp +++ b/src/Core/Material/BlinnPhongMaterialModel.hpp @@ -30,6 +30,12 @@ class RA_CORE_API BlinnPhongMaterialModel : public MaterialModel bool hasOpacityTexture() const { return m_hasTexOpacity; } + Utils::Color evalBSDF(Vector3f w_i, Vector3f w_o, Vector3f normal, Vector2f uv) override; + std::optional> sample(Vector3f inDir, Vector3f normal, Vector2f u) override; + Scalar PDF(Vector3f inDir, Vector3f outDir, Vector3f normal) override; + + Scalar specularPDF(Vector3f dir, Vector3f normal); + /// DATA MEMBERS Core::Utils::Color m_kd { 0.7_ra, 0.7_ra, 0.7_ra }; Core::Utils::Color m_ks { 0.3_ra, 0.3_ra, 0.3_ra }; diff --git a/src/Core/Material/MaterialModel.cpp b/src/Core/Material/MaterialModel.cpp index c1397cd2bec..0ad712c0974 100644 --- a/src/Core/Material/MaterialModel.cpp +++ b/src/Core/Material/MaterialModel.cpp @@ -14,8 +14,8 @@ Utils::Color MaterialModel::evalBSDF( Vector3f w_i, Vector3f w_o, Vector3f norma return Utils::Color(); } -std::optional MaterialModel::sample( Vector3f inDir, Vector3f normal, Vector2f u ) { - return std::optional(); +std::optional> MaterialModel::sample( Vector3f inDir, Vector3f normal, Vector2f u ) { + return {}; } Scalar MaterialModel::PDF( Vector3f inDir, Vector3f outDir, Vector3f normal ) { @@ -33,7 +33,29 @@ void MaterialModel::coordinateSystem( Vector3f normal, Vector3f* tangent, Vector *bitangent = normal.cross(*tangent); } -Vector3f MaterialModel::randomInHemisphere( Vector3f normal ) { +Vector3f MaterialModel::sampleSpecular(Vector3f inDir, Vector2f u) { + Vector3f nextDir, halfway; + + halfway = sampleHemisphereCosineWeighted(u); + nextDir = inDir - 2.0f * inDir.dot(halfway) * halfway; + + return nextDir; +} + +Vector3f MaterialModel::sampleHemisphereCosineWeighted( Vector2f u ) { + Vector3f point; + + Scalar r = std::sqrt(u[0]); + Scalar phi = 2 * M_PI * u[1]; + + point[0] = r * std::cos(phi); + point[1] = r * std::sin(phi); + point[2] = std::sqrt(std::max(0.f, 1 - point[0]*point[0] - point[1]*point[1])); + + return point; +} + +Vector3f MaterialModel::sampleHemisphere( Vector3f normal ) { Vector3f vec = Vector3f::Random(3,1); vec /= vec.norm(); @@ -44,6 +66,14 @@ Vector3f MaterialModel::randomInHemisphere( Vector3f normal ) { return -vec; } +Scalar MaterialModel::cosineWeightedPDF( Vector3f dir, Vector3f normal ) { + dir.normalize(); + + Scalar cosTheta = dir.dot(normal); + + return cosTheta / M_PI; +} + } // namespace Material } // namespace Core } // namespace Ra diff --git a/src/Core/Material/MaterialModel.hpp b/src/Core/Material/MaterialModel.hpp index 4da1cc8fd30..8cb38132417 100644 --- a/src/Core/Material/MaterialModel.hpp +++ b/src/Core/Material/MaterialModel.hpp @@ -36,12 +36,16 @@ class RA_CORE_API MaterialModel : public Utils::ObservableVoid virtual void displayInfo() const; virtual Utils::Color evalBSDF(Vector3f w_i, Vector3f w_o, Vector3f normal, Vector2f uv); - virtual std::optional sample(Vector3f inDir, Vector3f normal, Vector2f u); + virtual std::optional> sample(Vector3f inDir, Vector3f normal, Vector2f u); virtual Scalar PDF(Vector3f inDir, Vector3f outDir, Vector3f normal); void coordinateSystem(Vector3f normal, Vector3f* tangent, Vector3f* bitangent); - Vector3f randomInHemisphere(Vector3f normal); + Vector3f sampleSpecular(Vector3f inDir, Vector2f u); + Vector3f sampleHemisphereCosineWeighted(Vector2f u); + Vector3f sampleHemisphere(Vector3f normal); + + Scalar cosineWeightedPDF(Vector3f dir, Vector3f normal); private: std::string m_materialType; diff --git a/src/Core/Material/SimpleMaterialModel.cpp b/src/Core/Material/SimpleMaterialModel.cpp index 0a284cd78cb..27281e33eb1 100644 --- a/src/Core/Material/SimpleMaterialModel.cpp +++ b/src/Core/Material/SimpleMaterialModel.cpp @@ -49,27 +49,23 @@ Utils::Color Material::LambertianMaterialModel::evalBSDF( Vector3f w_i, return m_kd * ( 1 / M_PI ); } -std::optional LambertianMaterialModel::sample( Vector3f inDir, Vector3f normal, Vector2f u ) { +std::optional> LambertianMaterialModel::sample( Vector3f inDir, Vector3f normal, Vector2f u ) { // create local to normal coordinate system - Vector3f tangent, bitangent, wi; + Vector3f tangent, bitangent, point; coordinateSystem(normal, &tangent, &bitangent); // sample point on hemisphere with cosine-weighted distribution - Scalar r = std::sqrt(u[0]); - Scalar phi = 2 * M_PI * u[1]; - - wi[0] = r * std::cos(phi); - wi[1] = r * std::sin(phi); - wi[2] = std::sqrt(std::max(0.f, 1 - wi[0]*wi[0] - wi[1]*wi[1])); + point = sampleHemisphereCosineWeighted(u); // transform sampled point from local to world coodinate system - Vector3 result(wi.dot(tangent), wi.dot(bitangent), wi.dot(normal)); + Vector3 wi(point.dot(tangent), point.dot(bitangent), point.dot(normal)); + std::pair result {wi, PDF(inDir, wi, normal)}; - return wi; + return result; } Scalar LambertianMaterialModel::PDF( Vector3f inDir, Vector3f outDir, Vector3f normal ) { - return std::abs(outDir.dot(normal)) * ( 1.0 / M_PI ); + return cosineWeightedPDF(outDir, normal); } } // namespace Material diff --git a/src/Core/Material/SimpleMaterialModel.hpp b/src/Core/Material/SimpleMaterialModel.hpp index ec9102335e1..2fd718d5c0e 100644 --- a/src/Core/Material/SimpleMaterialModel.hpp +++ b/src/Core/Material/SimpleMaterialModel.hpp @@ -48,7 +48,7 @@ class RA_CORE_API LambertianMaterialModel : public SimpleMaterialModel bool hasNormalTexture() const { return m_hasTexNormal; } Utils::Color evalBSDF(Vector3f w_i, Vector3f w_o, Vector3f normal, Vector2f uv) override; - std::optional sample(Vector3f inDir, Vector3f normal, Vector2f u) override; + std::optional> sample(Vector3f inDir, Vector3f normal, Vector2f u) override; Scalar PDF(Vector3f inDir, Vector3f outDir, Vector3f normal) override; /// DATA MEMBERS From 15719a5443eaec72df7327499f793db2661b979b Mon Sep 17 00:00:00 2001 From: grandch Date: Mon, 19 Jun 2023 16:27:58 +0200 Subject: [PATCH 03/56] [core] change randomEngine for a static member --- src/Core/Material/BlinnPhongMaterialModel.cpp | 8 ++++++-- src/Core/Material/BlinnPhongMaterialModel.hpp | 7 +++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/Core/Material/BlinnPhongMaterialModel.cpp b/src/Core/Material/BlinnPhongMaterialModel.cpp index 98e730e956a..0486f3a59b5 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.cpp +++ b/src/Core/Material/BlinnPhongMaterialModel.cpp @@ -61,8 +61,7 @@ BlinnPhongMaterialModel::sample( Vector3f inDir, Vector3f normal, Vector2f u ) { sIntensity /= diffSpecNorm; std::uniform_real_distribution unifDistributionRand{0, 1}; - std::minstd_rand randomEngine(std::time(nullptr)); - Scalar distrib = unifDistributionRand(randomEngine); + Scalar distrib = unifDistributionRand(m_randomEngine); // diffuse part if(distrib < dIntensity) { @@ -97,6 +96,11 @@ Scalar BlinnPhongMaterialModel::specularPDF( Vector3f dir, Vector3f normal ) { return result; } +std::minstd_rand BlinnPhongMaterialModel::getRandomEngine() { + + return m_randomEngine; +} + } // namespace Material } // namespace Core } // namespace Ra diff --git a/src/Core/Material/BlinnPhongMaterialModel.hpp b/src/Core/Material/BlinnPhongMaterialModel.hpp index 1555211a4c3..f2d38bebd7d 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.hpp +++ b/src/Core/Material/BlinnPhongMaterialModel.hpp @@ -2,6 +2,7 @@ #include #include +#include namespace Ra { namespace Core { @@ -36,6 +37,8 @@ class RA_CORE_API BlinnPhongMaterialModel : public MaterialModel Scalar specularPDF(Vector3f dir, Vector3f normal); + static std::minstd_rand getRandomEngine(); + /// DATA MEMBERS Core::Utils::Color m_kd { 0.7_ra, 0.7_ra, 0.7_ra }; Core::Utils::Color m_ks { 0.3_ra, 0.3_ra, 0.3_ra }; @@ -51,8 +54,12 @@ class RA_CORE_API BlinnPhongMaterialModel : public MaterialModel bool m_hasTexShininess { false }; bool m_hasTexNormal { false }; bool m_hasTexOpacity { false }; + + static std::minstd_rand m_randomEngine; }; +std::minstd_rand BlinnPhongMaterialModel::m_randomEngine = std::minstd_rand(std::time(nullptr)); + } // namespace Material } // namespace Core } // namespace Ra From ec36b7ac4601ef30d178df00e784f9bc95057a15 Mon Sep 17 00:00:00 2001 From: grandch Date: Tue, 20 Jun 2023 10:48:07 +0200 Subject: [PATCH 04/56] [core] first review fix --- src/Core/Material/BlinnPhongMaterialModel.cpp | 49 +++++++++++-------- src/Core/Material/BlinnPhongMaterialModel.hpp | 7 +-- src/Core/Material/MaterialModel.cpp | 43 +++++++--------- src/Core/Material/MaterialModel.hpp | 5 +- src/Core/Material/SimpleMaterialModel.cpp | 8 +-- 5 files changed, 57 insertions(+), 55 deletions(-) diff --git a/src/Core/Material/BlinnPhongMaterialModel.cpp b/src/Core/Material/BlinnPhongMaterialModel.cpp index 0486f3a59b5..7566a4acb5b 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.cpp +++ b/src/Core/Material/BlinnPhongMaterialModel.cpp @@ -1,6 +1,5 @@ #include #include -#include "BlinnPhongMaterialModel.hpp" #include @@ -45,17 +44,14 @@ Utils::Color Material::BlinnPhongMaterialModel::evalBSDF( Vector3f w_i, std::optional> BlinnPhongMaterialModel::sample( Vector3f inDir, Vector3f normal, Vector2f u ) { - /* - compute intensity of diffuse and specular - compute norm (max(1, Idiffuse + Ispecular)) - normalize Idiffuse and Ispecular - */ + Vector3f halfway, tangent, bitangent; - Vector3f nextDir, halfway; + coordinateSystem(normal, &tangent, &bitangent); - Scalar dIntensity = (m_kd.x() + m_kd.y() + m_kd.z()) / 3.f; - Scalar sIntensity = (m_ks.x() + m_ks.y() + m_ks.z()) / 3.f; - Scalar diffSpecNorm = std::max(1.f, dIntensity + sIntensity); + Vector3 rgbToLuminance { 0.2126_ra , 0.7152_ra, 0.0722_ra }; + Scalar dIntensity = m_kd.rgb().dot( rgbToLuminance ); + Scalar sIntensity = m_ks.rgb().dot( rgbToLuminance ); + Scalar diffSpecNorm = std::max(1_ra, dIntensity + sIntensity); dIntensity /= diffSpecNorm; sIntensity /= diffSpecNorm; @@ -65,13 +61,14 @@ BlinnPhongMaterialModel::sample( Vector3f inDir, Vector3f normal, Vector2f u ) { // diffuse part if(distrib < dIntensity) { - nextDir = sampleHemisphereCosineWeighted(u); - std::pair result {nextDir, cosineWeightedPDF(nextDir, normal)}; + std::pair smpl = sampleHemisphereCosineWeighted(u); + Vector3 wi(smpl.first.dot(tangent), smpl.first.dot(bitangent), smpl.first.dot(normal)); + std::pair result {wi, smpl.second}; return result; - } else if(distrib > dIntensity && distrib < dIntensity + sIntensity) { // specular part - nextDir = sampleSpecular(inDir, u); - // compute specular pdf - std::pair result; + } else if(distrib < dIntensity + sIntensity) { // specular part + std::pair smpl = sampleSpecular(inDir, u); + Vector3 wi(smpl.first.dot(tangent), smpl.first.dot(bitangent), smpl.first.dot(normal)); + std::pair result {wi, smpl.second}; return result; } else { // no next dir return {}; @@ -79,14 +76,24 @@ BlinnPhongMaterialModel::sample( Vector3f inDir, Vector3f normal, Vector2f u ) { } Scalar BlinnPhongMaterialModel::PDF( Vector3f inDir, Vector3f outDir, Vector3f normal ) { - Scalar dIntensity = (m_kd.x() + m_kd.y() + m_kd.z()) / 3.f; - Scalar sIntensity = (m_ks.x() + m_ks.y() + m_ks.z()) / 3.f; - Scalar diffSpecNorm = std::max(1.f, dIntensity + sIntensity); + Vector3 rgbToLuminance { 0.2126_ra , 0.7152_ra, 0.0722_ra }; + Scalar dIntensity = m_kd.rgb().dot( rgbToLuminance ); + Scalar sIntensity = m_ks.rgb().dot( rgbToLuminance ); + Scalar diffSpecNorm = std::max(1_ra, dIntensity + sIntensity); dIntensity /= diffSpecNorm; sIntensity /= diffSpecNorm; - return std::clamp(dIntensity * cosineWeightedPDF(outDir, normal) + sIntensity * specularPDF(outDir, normal), Scalar(0), Scalar(1)); + return std::clamp(dIntensity * cosineWeightedPDF(outDir, normal) + sIntensity * specularPDF(outDir, normal), 0_ra, 1_ra); +} + +std::pair BlinnPhongMaterialModel::sampleSpecular(Vector3f inDir, Vector2f u) { + Vector3f nextDir; + + std::pair halfway = sampleHemisphereCosineWeighted(u); + nextDir = inDir - 2.0f * inDir.dot(halfway.first) * halfway.first; + + return {nextDir, 0_ra}; } Scalar BlinnPhongMaterialModel::specularPDF( Vector3f dir, Vector3f normal ) { @@ -96,7 +103,7 @@ Scalar BlinnPhongMaterialModel::specularPDF( Vector3f dir, Vector3f normal ) { return result; } -std::minstd_rand BlinnPhongMaterialModel::getRandomEngine() { +std::mt19937 BlinnPhongMaterialModel::getRandomEngine() { return m_randomEngine; } diff --git a/src/Core/Material/BlinnPhongMaterialModel.hpp b/src/Core/Material/BlinnPhongMaterialModel.hpp index f2d38bebd7d..e97119e30a9 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.hpp +++ b/src/Core/Material/BlinnPhongMaterialModel.hpp @@ -35,9 +35,10 @@ class RA_CORE_API BlinnPhongMaterialModel : public MaterialModel std::optional> sample(Vector3f inDir, Vector3f normal, Vector2f u) override; Scalar PDF(Vector3f inDir, Vector3f outDir, Vector3f normal) override; + std::pair sampleSpecular(Vector3f inDir, Vector2f u); Scalar specularPDF(Vector3f dir, Vector3f normal); - static std::minstd_rand getRandomEngine(); + static std::mt19937 getRandomEngine(); /// DATA MEMBERS Core::Utils::Color m_kd { 0.7_ra, 0.7_ra, 0.7_ra }; @@ -55,10 +56,10 @@ class RA_CORE_API BlinnPhongMaterialModel : public MaterialModel bool m_hasTexNormal { false }; bool m_hasTexOpacity { false }; - static std::minstd_rand m_randomEngine; + static std::mt19937 m_randomEngine; }; -std::minstd_rand BlinnPhongMaterialModel::m_randomEngine = std::minstd_rand(std::time(nullptr)); +std::mt19937 BlinnPhongMaterialModel::m_randomEngine = std::mt19937 (std::time(nullptr)); } // namespace Material } // namespace Core diff --git a/src/Core/Material/MaterialModel.cpp b/src/Core/Material/MaterialModel.cpp index 0ad712c0974..eab6c4c73ad 100644 --- a/src/Core/Material/MaterialModel.cpp +++ b/src/Core/Material/MaterialModel.cpp @@ -33,37 +33,32 @@ void MaterialModel::coordinateSystem( Vector3f normal, Vector3f* tangent, Vector *bitangent = normal.cross(*tangent); } -Vector3f MaterialModel::sampleSpecular(Vector3f inDir, Vector2f u) { - Vector3f nextDir, halfway; - - halfway = sampleHemisphereCosineWeighted(u); - nextDir = inDir - 2.0f * inDir.dot(halfway) * halfway; - - return nextDir; -} - -Vector3f MaterialModel::sampleHemisphereCosineWeighted( Vector2f u ) { - Vector3f point; +std::pair MaterialModel::sampleHemisphereCosineWeighted( Vector2f u ) { + Vector3f dir; - Scalar r = std::sqrt(u[0]); - Scalar phi = 2 * M_PI * u[1]; + Scalar cosTheta = std::sqrt(u[0]); + Scalar sinTheta = std::sqrt(1-u[0]); + Scalar phi = 2 * Math::Pi * u[1]; - point[0] = r * std::cos(phi); - point[1] = r * std::sin(phi); - point[2] = std::sqrt(std::max(0.f, 1 - point[0]*point[0] - point[1]*point[1])); + dir[0] = sinTheta * std::cos(phi); + dir[1] = sinTheta * std::sin(phi); + dir[2] = cosTheta; - return point; + return {dir, cosTheta/Math::Pi}; } -Vector3f MaterialModel::sampleHemisphere( Vector3f normal ) { - Vector3f vec = Vector3f::Random(3,1); - vec /= vec.norm(); +std::pair MaterialModel::sampleHemisphere( Vector2 u ) { + Vector3f dir; + + Scalar cosTheta = u[0]; + Scalar sinTheta = 1-u[0]; + Scalar phi = 2 * Math::Pi * u[1]; - if(vec.dot(normal) > 0) { - return vec; - } + dir[0] = sinTheta * std::cos(phi); + dir[1] = sinTheta * std::sin(phi); + dir[2] = cosTheta; - return -vec; + return {dir, 1_ra/(2_ra*Math::Pi)}; } Scalar MaterialModel::cosineWeightedPDF( Vector3f dir, Vector3f normal ) { diff --git a/src/Core/Material/MaterialModel.hpp b/src/Core/Material/MaterialModel.hpp index 8cb38132417..65ac85a5e75 100644 --- a/src/Core/Material/MaterialModel.hpp +++ b/src/Core/Material/MaterialModel.hpp @@ -41,9 +41,8 @@ class RA_CORE_API MaterialModel : public Utils::ObservableVoid void coordinateSystem(Vector3f normal, Vector3f* tangent, Vector3f* bitangent); - Vector3f sampleSpecular(Vector3f inDir, Vector2f u); - Vector3f sampleHemisphereCosineWeighted(Vector2f u); - Vector3f sampleHemisphere(Vector3f normal); + std::pair sampleHemisphereCosineWeighted(Vector2f u); + std::pair sampleHemisphere(Vector2 u); Scalar cosineWeightedPDF(Vector3f dir, Vector3f normal); diff --git a/src/Core/Material/SimpleMaterialModel.cpp b/src/Core/Material/SimpleMaterialModel.cpp index 27281e33eb1..98ce5a83ac8 100644 --- a/src/Core/Material/SimpleMaterialModel.cpp +++ b/src/Core/Material/SimpleMaterialModel.cpp @@ -51,15 +51,15 @@ Utils::Color Material::LambertianMaterialModel::evalBSDF( Vector3f w_i, std::optional> LambertianMaterialModel::sample( Vector3f inDir, Vector3f normal, Vector2f u ) { // create local to normal coordinate system - Vector3f tangent, bitangent, point; + Vector3f tangent, bitangent; coordinateSystem(normal, &tangent, &bitangent); // sample point on hemisphere with cosine-weighted distribution - point = sampleHemisphereCosineWeighted(u); + std::pair smpl = sampleHemisphereCosineWeighted(u); // transform sampled point from local to world coodinate system - Vector3 wi(point.dot(tangent), point.dot(bitangent), point.dot(normal)); - std::pair result {wi, PDF(inDir, wi, normal)}; + Vector3 wi(smpl.first.dot(tangent), smpl.first.dot(bitangent), smpl.first.dot(normal)); + std::pair result {wi, smpl.second}; return result; } From 0e3ac218c4b383a8f310de0259a93e5ff98bf33f Mon Sep 17 00:00:00 2001 From: grandch Date: Tue, 20 Jun 2023 11:04:38 +0200 Subject: [PATCH 05/56] [core] Vector3f to Vector3 --- src/Core/Material/BlinnPhongMaterialModel.cpp | 34 +++++++++---------- src/Core/Material/BlinnPhongMaterialModel.hpp | 10 +++--- src/Core/Material/MaterialModel.cpp | 22 ++++++------ src/Core/Material/MaterialModel.hpp | 14 ++++---- src/Core/Material/SimpleMaterialModel.cpp | 18 +++++----- src/Core/Material/SimpleMaterialModel.hpp | 6 ++-- 6 files changed, 52 insertions(+), 52 deletions(-) diff --git a/src/Core/Material/BlinnPhongMaterialModel.cpp b/src/Core/Material/BlinnPhongMaterialModel.cpp index 7566a4acb5b..4c9f5960b00 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.cpp +++ b/src/Core/Material/BlinnPhongMaterialModel.cpp @@ -25,15 +25,15 @@ void BlinnPhongMaterialModel::displayInfo() const { print( hasNormalTexture(), " Normal Texture : ", m_texNormal ); print( hasOpacityTexture(), " Alpha Texture : ", m_texOpacity ); } -Utils::Color Material::BlinnPhongMaterialModel::evalBSDF( Vector3f w_i, - Vector3f w_o, - Vector3f normal, - Vector2f uv ) { +Utils::Color Material::BlinnPhongMaterialModel::evalBSDF( Vector3 w_i, + Vector3 w_o, + Vector3 normal, + Vector2 uv ) { // diffuse lambertien component Utils::Color diffuse = m_kd / M_PI; // Blinn-Phong specular component - Vector3f halfway = w_i + w_o; + Vector3 halfway = w_i + w_o; halfway.normalize(); Scalar specularIntensity = (m_ns + 2.0f) / (2.0f * M_PI) * std::pow(normal.dot(halfway), m_ns); Utils::Color specular = m_ks * specularIntensity; @@ -42,9 +42,9 @@ Utils::Color Material::BlinnPhongMaterialModel::evalBSDF( Vector3f w_i, Utils::Color bsdf = diffuse + specular; } -std::optional> -BlinnPhongMaterialModel::sample( Vector3f inDir, Vector3f normal, Vector2f u ) { - Vector3f halfway, tangent, bitangent; +std::optional> +BlinnPhongMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector2 u ) { + Vector3 halfway, tangent, bitangent; coordinateSystem(normal, &tangent, &bitangent); @@ -61,21 +61,21 @@ BlinnPhongMaterialModel::sample( Vector3f inDir, Vector3f normal, Vector2f u ) { // diffuse part if(distrib < dIntensity) { - std::pair smpl = sampleHemisphereCosineWeighted(u); + std::pair smpl = sampleHemisphereCosineWeighted(u); Vector3 wi(smpl.first.dot(tangent), smpl.first.dot(bitangent), smpl.first.dot(normal)); - std::pair result {wi, smpl.second}; + std::pair result {wi, smpl.second}; return result; } else if(distrib < dIntensity + sIntensity) { // specular part - std::pair smpl = sampleSpecular(inDir, u); + std::pair smpl = sampleSpecular(inDir, u); Vector3 wi(smpl.first.dot(tangent), smpl.first.dot(bitangent), smpl.first.dot(normal)); - std::pair result {wi, smpl.second}; + std::pair result {wi, smpl.second}; return result; } else { // no next dir return {}; } } -Scalar BlinnPhongMaterialModel::PDF( Vector3f inDir, Vector3f outDir, Vector3f normal ) { +Scalar BlinnPhongMaterialModel::PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) { Vector3 rgbToLuminance { 0.2126_ra , 0.7152_ra, 0.0722_ra }; Scalar dIntensity = m_kd.rgb().dot( rgbToLuminance ); Scalar sIntensity = m_ks.rgb().dot( rgbToLuminance ); @@ -87,16 +87,16 @@ Scalar BlinnPhongMaterialModel::PDF( Vector3f inDir, Vector3f outDir, Vector3f n return std::clamp(dIntensity * cosineWeightedPDF(outDir, normal) + sIntensity * specularPDF(outDir, normal), 0_ra, 1_ra); } -std::pair BlinnPhongMaterialModel::sampleSpecular(Vector3f inDir, Vector2f u) { - Vector3f nextDir; +std::pair BlinnPhongMaterialModel::sampleSpecular(Vector3 inDir, Vector2 u) { + Vector3 nextDir; - std::pair halfway = sampleHemisphereCosineWeighted(u); + std::pair halfway = sampleHemisphereCosineWeighted(u); nextDir = inDir - 2.0f * inDir.dot(halfway.first) * halfway.first; return {nextDir, 0_ra}; } -Scalar BlinnPhongMaterialModel::specularPDF( Vector3f dir, Vector3f normal ) { +Scalar BlinnPhongMaterialModel::specularPDF( Vector3 dir, Vector3 normal ) { Scalar cosTheta = normal.dot(dir); Scalar result = ((m_ns + 1) / (2.0f * M_PI)) * std::pow(cosTheta, m_ns); diff --git a/src/Core/Material/BlinnPhongMaterialModel.hpp b/src/Core/Material/BlinnPhongMaterialModel.hpp index e97119e30a9..7ce516d2371 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.hpp +++ b/src/Core/Material/BlinnPhongMaterialModel.hpp @@ -31,12 +31,12 @@ class RA_CORE_API BlinnPhongMaterialModel : public MaterialModel bool hasOpacityTexture() const { return m_hasTexOpacity; } - Utils::Color evalBSDF(Vector3f w_i, Vector3f w_o, Vector3f normal, Vector2f uv) override; - std::optional> sample(Vector3f inDir, Vector3f normal, Vector2f u) override; - Scalar PDF(Vector3f inDir, Vector3f outDir, Vector3f normal) override; + Utils::Color evalBSDF(Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv) override; + std::optional> sample(Vector3 inDir, Vector3 normal, Vector2 u) override; + Scalar PDF(Vector3 inDir, Vector3 outDir, Vector3 normal) override; - std::pair sampleSpecular(Vector3f inDir, Vector2f u); - Scalar specularPDF(Vector3f dir, Vector3f normal); + std::pair sampleSpecular(Vector3 inDir, Vector2 u); + Scalar specularPDF(Vector3 dir, Vector3 normal); static std::mt19937 getRandomEngine(); diff --git a/src/Core/Material/MaterialModel.cpp b/src/Core/Material/MaterialModel.cpp index eab6c4c73ad..18a0839c516 100644 --- a/src/Core/Material/MaterialModel.cpp +++ b/src/Core/Material/MaterialModel.cpp @@ -10,31 +10,31 @@ void MaterialModel::displayInfo() const { LOG( logERROR ) << "MaterialModel : unknown material type : " << m_materialType; } -Utils::Color MaterialModel::evalBSDF( Vector3f w_i, Vector3f w_o, Vector3f normal, Vector2f uv ) { +Utils::Color MaterialModel::evalBSDF( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) { return Utils::Color(); } -std::optional> MaterialModel::sample( Vector3f inDir, Vector3f normal, Vector2f u ) { +std::optional> MaterialModel::sample( Vector3 inDir, Vector3 normal, Vector2 u ) { return {}; } -Scalar MaterialModel::PDF( Vector3f inDir, Vector3f outDir, Vector3f normal ) { +Scalar MaterialModel::PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) { return 0.0f; } -void MaterialModel::coordinateSystem( Vector3f normal, Vector3f* tangent, Vector3f* bitangent ) { +void MaterialModel::coordinateSystem( Vector3 normal, Vector3* tangent, Vector3* bitangent ) { if (std::abs(normal[0]) > std::abs(normal[1])) { Scalar invLen = 1 / std::sqrt(normal[0] * normal[0] + normal[2] * normal[2]); - *tangent = Vector3f(-normal[2] * invLen, 0, normal[0] * invLen); + *tangent = Vector3(-normal[2] * invLen, 0, normal[0] * invLen); } else { Scalar invLen = 1 / std::sqrt(normal[1] * normal[1] + normal[2] * normal[2]); - *tangent = Vector3f(0, normal[2] * invLen, -normal[1] * invLen); + *tangent = Vector3(0, normal[2] * invLen, -normal[1] * invLen); } *bitangent = normal.cross(*tangent); } -std::pair MaterialModel::sampleHemisphereCosineWeighted( Vector2f u ) { - Vector3f dir; +std::pair MaterialModel::sampleHemisphereCosineWeighted( Vector2 u ) { + Vector3 dir; Scalar cosTheta = std::sqrt(u[0]); Scalar sinTheta = std::sqrt(1-u[0]); @@ -47,8 +47,8 @@ std::pair MaterialModel::sampleHemisphereCosineWeighted( Vecto return {dir, cosTheta/Math::Pi}; } -std::pair MaterialModel::sampleHemisphere( Vector2 u ) { - Vector3f dir; +std::pair MaterialModel::sampleHemisphere( Vector2 u ) { + Vector3 dir; Scalar cosTheta = u[0]; Scalar sinTheta = 1-u[0]; @@ -61,7 +61,7 @@ std::pair MaterialModel::sampleHemisphere( Vector2 u ) { return {dir, 1_ra/(2_ra*Math::Pi)}; } -Scalar MaterialModel::cosineWeightedPDF( Vector3f dir, Vector3f normal ) { +Scalar MaterialModel::cosineWeightedPDF( Vector3 dir, Vector3 normal ) { dir.normalize(); Scalar cosTheta = dir.dot(normal); diff --git a/src/Core/Material/MaterialModel.hpp b/src/Core/Material/MaterialModel.hpp index 65ac85a5e75..4d119f0bb6d 100644 --- a/src/Core/Material/MaterialModel.hpp +++ b/src/Core/Material/MaterialModel.hpp @@ -35,16 +35,16 @@ class RA_CORE_API MaterialModel : public Utils::ObservableVoid /// DEBUG virtual void displayInfo() const; - virtual Utils::Color evalBSDF(Vector3f w_i, Vector3f w_o, Vector3f normal, Vector2f uv); - virtual std::optional> sample(Vector3f inDir, Vector3f normal, Vector2f u); - virtual Scalar PDF(Vector3f inDir, Vector3f outDir, Vector3f normal); + virtual Utils::Color evalBSDF(Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv); + virtual std::optional> sample(Vector3 inDir, Vector3 normal, Vector2 u); + virtual Scalar PDF(Vector3 inDir, Vector3 outDir, Vector3 normal); - void coordinateSystem(Vector3f normal, Vector3f* tangent, Vector3f* bitangent); + void coordinateSystem(Vector3 normal, Vector3* tangent, Vector3* bitangent); - std::pair sampleHemisphereCosineWeighted(Vector2f u); - std::pair sampleHemisphere(Vector2 u); + std::pair sampleHemisphereCosineWeighted(Vector2 u); + std::pair sampleHemisphere(Vector2 u); - Scalar cosineWeightedPDF(Vector3f dir, Vector3f normal); + Scalar cosineWeightedPDF(Vector3 dir, Vector3 normal); private: std::string m_materialType; diff --git a/src/Core/Material/SimpleMaterialModel.cpp b/src/Core/Material/SimpleMaterialModel.cpp index 98ce5a83ac8..bdf7f19a8c5 100644 --- a/src/Core/Material/SimpleMaterialModel.cpp +++ b/src/Core/Material/SimpleMaterialModel.cpp @@ -38,10 +38,10 @@ void LambertianMaterialModel::displayInfo() const { print( hasOpacityTexture(), " Alpha Texture : ", m_texOpacity ); } -Utils::Color Material::LambertianMaterialModel::evalBSDF( Vector3f w_i, - Vector3f w_o, - Vector3f normal, - Vector2f uv ) { +Utils::Color Material::LambertianMaterialModel::evalBSDF( Vector3 w_i, + Vector3 w_o, + Vector3 normal, + Vector2 uv ) { if(w_i.dot(normal) <= 0 || w_o.dot(normal) <= 0) { return Utils::Color::Black(); } @@ -49,22 +49,22 @@ Utils::Color Material::LambertianMaterialModel::evalBSDF( Vector3f w_i, return m_kd * ( 1 / M_PI ); } -std::optional> LambertianMaterialModel::sample( Vector3f inDir, Vector3f normal, Vector2f u ) { +std::optional> LambertianMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector2 u ) { // create local to normal coordinate system - Vector3f tangent, bitangent; + Vector3 tangent, bitangent; coordinateSystem(normal, &tangent, &bitangent); // sample point on hemisphere with cosine-weighted distribution - std::pair smpl = sampleHemisphereCosineWeighted(u); + std::pair smpl = sampleHemisphereCosineWeighted(u); // transform sampled point from local to world coodinate system Vector3 wi(smpl.first.dot(tangent), smpl.first.dot(bitangent), smpl.first.dot(normal)); - std::pair result {wi, smpl.second}; + std::pair result {wi, smpl.second}; return result; } -Scalar LambertianMaterialModel::PDF( Vector3f inDir, Vector3f outDir, Vector3f normal ) { +Scalar LambertianMaterialModel::PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) { return cosineWeightedPDF(outDir, normal); } diff --git a/src/Core/Material/SimpleMaterialModel.hpp b/src/Core/Material/SimpleMaterialModel.hpp index 2fd718d5c0e..07ed53a3356 100644 --- a/src/Core/Material/SimpleMaterialModel.hpp +++ b/src/Core/Material/SimpleMaterialModel.hpp @@ -47,9 +47,9 @@ class RA_CORE_API LambertianMaterialModel : public SimpleMaterialModel /// QUERY bool hasNormalTexture() const { return m_hasTexNormal; } - Utils::Color evalBSDF(Vector3f w_i, Vector3f w_o, Vector3f normal, Vector2f uv) override; - std::optional> sample(Vector3f inDir, Vector3f normal, Vector2f u) override; - Scalar PDF(Vector3f inDir, Vector3f outDir, Vector3f normal) override; + Utils::Color evalBSDF(Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv) override; + std::optional> sample(Vector3 inDir, Vector3 normal, Vector2 u) override; + Scalar PDF(Vector3 inDir, Vector3 outDir, Vector3 normal) override; /// DATA MEMBERS std::string m_texNormal; From 055f30bbea02911c993300f788c577df855556af Mon Sep 17 00:00:00 2001 From: grandch Date: Tue, 20 Jun 2023 15:13:21 +0200 Subject: [PATCH 06/56] [core] fix blinnphong sampling, add roughness conv --- src/Core/Material/BlinnPhongMaterialModel.cpp | 37 +++++++++++++------ src/Core/Material/BlinnPhongMaterialModel.hpp | 6 ++- src/Core/Material/SimpleMaterialModel.cpp | 2 +- 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/Core/Material/BlinnPhongMaterialModel.cpp b/src/Core/Material/BlinnPhongMaterialModel.cpp index 4c9f5960b00..c7f8d74115c 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.cpp +++ b/src/Core/Material/BlinnPhongMaterialModel.cpp @@ -2,6 +2,7 @@ #include #include +#include "BlinnPhongMaterialModel.hpp" namespace Ra { namespace Core { @@ -59,6 +60,8 @@ BlinnPhongMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector2 u ) { std::uniform_real_distribution unifDistributionRand{0, 1}; Scalar distrib = unifDistributionRand(m_randomEngine); + Scalar roughness = getRoughness(); + // diffuse part if(distrib < dIntensity) { std::pair smpl = sampleHemisphereCosineWeighted(u); @@ -66,7 +69,7 @@ BlinnPhongMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector2 u ) { std::pair result {wi, smpl.second}; return result; } else if(distrib < dIntensity + sIntensity) { // specular part - std::pair smpl = sampleSpecular(inDir, u); + std::pair smpl = sampleSpecular(u, roughness); Vector3 wi(smpl.first.dot(tangent), smpl.first.dot(bitangent), smpl.first.dot(normal)); std::pair result {wi, smpl.second}; return result; @@ -87,20 +90,32 @@ Scalar BlinnPhongMaterialModel::PDF( Vector3 inDir, Vector3 outDir, Vector3 norm return std::clamp(dIntensity * cosineWeightedPDF(outDir, normal) + sIntensity * specularPDF(outDir, normal), 0_ra, 1_ra); } -std::pair BlinnPhongMaterialModel::sampleSpecular(Vector3 inDir, Vector2 u) { - Vector3 nextDir; - - std::pair halfway = sampleHemisphereCosineWeighted(u); - nextDir = inDir - 2.0f * inDir.dot(halfway.first) * halfway.first; - - return {nextDir, 0_ra}; +std::pair BlinnPhongMaterialModel::sampleSpecular(Vector2 u, Scalar roughness) { + Vector3 dir; + + Scalar cosTheta = std::pow(u[0], 1_ra / ( roughness + 2 ) ); + Scalar sinTheta = 1-u[0]; + Scalar phi = 2 * Math::Pi * u[1]; + + dir[0] = sinTheta * std::cos(phi); + dir[1] = sinTheta * std::sin(phi); + dir[2] = cosTheta; + + return {dir, (roughness+2) * std::pow(u[0], roughness) / 2 * Math::Pi}; } -Scalar BlinnPhongMaterialModel::specularPDF( Vector3 dir, Vector3 normal ) { +Scalar BlinnPhongMaterialModel::specularPDF( Vector3 dir, Vector3 normal, Scalar roughness ) { Scalar cosTheta = normal.dot(dir); - Scalar result = ((m_ns + 1) / (2.0f * M_PI)) * std::pow(cosTheta, m_ns); + return (roughness+2) * std::pow(cosTheta, roughness) / 2 * Math::Pi; +} - return result; +Scalar BlinnPhongMaterialModel::getRoughness() { + Scalar ns = m_ns; + if (ns > 1) { + ns /= 128_ra; + } + Scalar r = std::clamp(1 - ns, 0.04_ra, 0.96_ra); + return 1 - m_ns; } std::mt19937 BlinnPhongMaterialModel::getRandomEngine() { diff --git a/src/Core/Material/BlinnPhongMaterialModel.hpp b/src/Core/Material/BlinnPhongMaterialModel.hpp index 7ce516d2371..813f77e05b0 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.hpp +++ b/src/Core/Material/BlinnPhongMaterialModel.hpp @@ -35,8 +35,10 @@ class RA_CORE_API BlinnPhongMaterialModel : public MaterialModel std::optional> sample(Vector3 inDir, Vector3 normal, Vector2 u) override; Scalar PDF(Vector3 inDir, Vector3 outDir, Vector3 normal) override; - std::pair sampleSpecular(Vector3 inDir, Vector2 u); - Scalar specularPDF(Vector3 dir, Vector3 normal); + std::pair sampleSpecular(Vector2 u, Scalar roughness); + Scalar specularPDF(Vector3 dir, Vector3 normal, Scalar roughness); + + Scalar getRoughness(); static std::mt19937 getRandomEngine(); diff --git a/src/Core/Material/SimpleMaterialModel.cpp b/src/Core/Material/SimpleMaterialModel.cpp index bdf7f19a8c5..e87846a2fa4 100644 --- a/src/Core/Material/SimpleMaterialModel.cpp +++ b/src/Core/Material/SimpleMaterialModel.cpp @@ -46,7 +46,7 @@ Utils::Color Material::LambertianMaterialModel::evalBSDF( Vector3 w_i, return Utils::Color::Black(); } - return m_kd * ( 1 / M_PI ); + return m_kd / M_PI; } std::optional> LambertianMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector2 u ) { From f2b9bcfeab46b59bfa1443b07a0e6325d838a9ee Mon Sep 17 00:00:00 2001 From: grandch Date: Tue, 20 Jun 2023 15:57:40 +0200 Subject: [PATCH 07/56] [ocre] doc evalBSDF --- src/Core/Material/MaterialModel.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Core/Material/MaterialModel.hpp b/src/Core/Material/MaterialModel.hpp index 4d119f0bb6d..b11f74ee218 100644 --- a/src/Core/Material/MaterialModel.hpp +++ b/src/Core/Material/MaterialModel.hpp @@ -35,6 +35,10 @@ class RA_CORE_API MaterialModel : public Utils::ObservableVoid /// DEBUG virtual void displayInfo() const; + /** Compute BSDF value for a set of directions and texture coordinates. + * w_i : incident direction, w_o : outgoing direction, normal : geometric normal direction. + * w_i, w_o and normal are in world space. + */ virtual Utils::Color evalBSDF(Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv); virtual std::optional> sample(Vector3 inDir, Vector3 normal, Vector2 u); virtual Scalar PDF(Vector3 inDir, Vector3 outDir, Vector3 normal); From 8f320afc2df6f3f35e36e9ac03eb1bb7703c4114 Mon Sep 17 00:00:00 2001 From: grandch Date: Tue, 20 Jun 2023 16:47:06 +0200 Subject: [PATCH 08/56] [core] clang format --- src/Core/Material/BlinnPhongMaterialModel.cpp | 82 ++++++++++--------- src/Core/Material/BlinnPhongMaterialModel.hpp | 13 +-- src/Core/Material/MaterialModel.cpp | 52 ++++++------ src/Core/Material/MaterialModel.hpp | 19 +++-- src/Core/Material/SimpleMaterialModel.cpp | 19 ++--- src/Core/Material/SimpleMaterialModel.hpp | 7 +- 6 files changed, 101 insertions(+), 91 deletions(-) diff --git a/src/Core/Material/BlinnPhongMaterialModel.cpp b/src/Core/Material/BlinnPhongMaterialModel.cpp index c7f8d74115c..fa30c7d4d5e 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.cpp +++ b/src/Core/Material/BlinnPhongMaterialModel.cpp @@ -1,8 +1,8 @@ #include #include -#include #include "BlinnPhongMaterialModel.hpp" +#include namespace Ra { namespace Core { @@ -36,7 +36,8 @@ Utils::Color Material::BlinnPhongMaterialModel::evalBSDF( Vector3 w_i, // Blinn-Phong specular component Vector3 halfway = w_i + w_o; halfway.normalize(); - Scalar specularIntensity = (m_ns + 2.0f) / (2.0f * M_PI) * std::pow(normal.dot(halfway), m_ns); + Scalar specularIntensity = + ( m_ns + 2.0f ) / ( 2.0f * M_PI ) * std::pow( normal.dot( halfway ), m_ns ); Utils::Color specular = m_ks * specularIntensity; // Combine the diffuse and specular components @@ -47,74 +48,79 @@ std::optional> BlinnPhongMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector2 u ) { Vector3 halfway, tangent, bitangent; - coordinateSystem(normal, &tangent, &bitangent); + coordinateSystem( normal, &tangent, &bitangent ); - Vector3 rgbToLuminance { 0.2126_ra , 0.7152_ra, 0.0722_ra }; - Scalar dIntensity = m_kd.rgb().dot( rgbToLuminance ); - Scalar sIntensity = m_ks.rgb().dot( rgbToLuminance ); - Scalar diffSpecNorm = std::max(1_ra, dIntensity + sIntensity); + Vector3 rgbToLuminance { 0.2126_ra, 0.7152_ra, 0.0722_ra }; + Scalar dIntensity = m_kd.rgb().dot( rgbToLuminance ); + Scalar sIntensity = m_ks.rgb().dot( rgbToLuminance ); + Scalar diffSpecNorm = std::max( 1_ra, dIntensity + sIntensity ); dIntensity /= diffSpecNorm; sIntensity /= diffSpecNorm; - std::uniform_real_distribution unifDistributionRand{0, 1}; - Scalar distrib = unifDistributionRand(m_randomEngine); + std::uniform_real_distribution unifDistributionRand { 0, 1 }; + Scalar distrib = unifDistributionRand( m_randomEngine ); Scalar roughness = getRoughness(); // diffuse part - if(distrib < dIntensity) { - std::pair smpl = sampleHemisphereCosineWeighted(u); - Vector3 wi(smpl.first.dot(tangent), smpl.first.dot(bitangent), smpl.first.dot(normal)); - std::pair result {wi, smpl.second}; + if ( distrib < dIntensity ) { + std::pair smpl = sampleHemisphereCosineWeighted( u ); + Vector3 wi( + smpl.first.dot( tangent ), smpl.first.dot( bitangent ), smpl.first.dot( normal ) ); + std::pair result { wi, smpl.second }; return result; - } else if(distrib < dIntensity + sIntensity) { // specular part - std::pair smpl = sampleSpecular(u, roughness); - Vector3 wi(smpl.first.dot(tangent), smpl.first.dot(bitangent), smpl.first.dot(normal)); - std::pair result {wi, smpl.second}; + } + else if ( distrib < dIntensity + sIntensity ) { // specular part + std::pair smpl = sampleSpecular( u, roughness ); + Vector3 wi( + smpl.first.dot( tangent ), smpl.first.dot( bitangent ), smpl.first.dot( normal ) ); + std::pair result { wi, smpl.second }; return result; - } else { // no next dir + } + else { // no next dir return {}; } } Scalar BlinnPhongMaterialModel::PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) { - Vector3 rgbToLuminance { 0.2126_ra , 0.7152_ra, 0.0722_ra }; - Scalar dIntensity = m_kd.rgb().dot( rgbToLuminance ); - Scalar sIntensity = m_ks.rgb().dot( rgbToLuminance ); - Scalar diffSpecNorm = std::max(1_ra, dIntensity + sIntensity); + Vector3 rgbToLuminance { 0.2126_ra, 0.7152_ra, 0.0722_ra }; + Scalar dIntensity = m_kd.rgb().dot( rgbToLuminance ); + Scalar sIntensity = m_ks.rgb().dot( rgbToLuminance ); + Scalar diffSpecNorm = std::max( 1_ra, dIntensity + sIntensity ); dIntensity /= diffSpecNorm; sIntensity /= diffSpecNorm; - return std::clamp(dIntensity * cosineWeightedPDF(outDir, normal) + sIntensity * specularPDF(outDir, normal), 0_ra, 1_ra); + return std::clamp( dIntensity * cosineWeightedPDF( outDir, normal ) + + sIntensity * specularPDF( outDir, normal ), + 0_ra, + 1_ra ); } -std::pair BlinnPhongMaterialModel::sampleSpecular(Vector2 u, Scalar roughness) { +std::pair BlinnPhongMaterialModel::sampleSpecular( Vector2 u, Scalar roughness ) { Vector3 dir; - - Scalar cosTheta = std::pow(u[0], 1_ra / ( roughness + 2 ) ); - Scalar sinTheta = 1-u[0]; - Scalar phi = 2 * Math::Pi * u[1]; - dir[0] = sinTheta * std::cos(phi); - dir[1] = sinTheta * std::sin(phi); + Scalar cosTheta = std::pow( u[0], 1_ra / ( roughness + 2 ) ); + Scalar sinTheta = 1 - u[0]; + Scalar phi = 2 * Math::Pi * u[1]; + + dir[0] = sinTheta * std::cos( phi ); + dir[1] = sinTheta * std::sin( phi ); dir[2] = cosTheta; - - return {dir, (roughness+2) * std::pow(u[0], roughness) / 2 * Math::Pi}; + + return { dir, ( roughness + 2 ) * std::pow( u[0], roughness ) / 2 * Math::Pi }; } Scalar BlinnPhongMaterialModel::specularPDF( Vector3 dir, Vector3 normal, Scalar roughness ) { - Scalar cosTheta = normal.dot(dir); - return (roughness+2) * std::pow(cosTheta, roughness) / 2 * Math::Pi; + Scalar cosTheta = normal.dot( dir ); + return ( roughness + 2 ) * std::pow( cosTheta, roughness ) / 2 * Math::Pi; } Scalar BlinnPhongMaterialModel::getRoughness() { Scalar ns = m_ns; - if (ns > 1) { - ns /= 128_ra; - } - Scalar r = std::clamp(1 - ns, 0.04_ra, 0.96_ra); + if ( ns > 1 ) { ns /= 128_ra; } + Scalar r = std::clamp( 1 - ns, 0.04_ra, 0.96_ra ); return 1 - m_ns; } diff --git a/src/Core/Material/BlinnPhongMaterialModel.hpp b/src/Core/Material/BlinnPhongMaterialModel.hpp index 813f77e05b0..9e9eb913333 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.hpp +++ b/src/Core/Material/BlinnPhongMaterialModel.hpp @@ -31,12 +31,13 @@ class RA_CORE_API BlinnPhongMaterialModel : public MaterialModel bool hasOpacityTexture() const { return m_hasTexOpacity; } - Utils::Color evalBSDF(Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv) override; - std::optional> sample(Vector3 inDir, Vector3 normal, Vector2 u) override; - Scalar PDF(Vector3 inDir, Vector3 outDir, Vector3 normal) override; + Utils::Color evalBSDF( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) override; + std::optional> + sample( Vector3 inDir, Vector3 normal, Vector2 u ) override; + Scalar PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) override; - std::pair sampleSpecular(Vector2 u, Scalar roughness); - Scalar specularPDF(Vector3 dir, Vector3 normal, Scalar roughness); + std::pair sampleSpecular( Vector2 u, Scalar roughness ); + Scalar specularPDF( Vector3 dir, Vector3 normal, Scalar roughness ); Scalar getRoughness(); @@ -61,7 +62,7 @@ class RA_CORE_API BlinnPhongMaterialModel : public MaterialModel static std::mt19937 m_randomEngine; }; -std::mt19937 BlinnPhongMaterialModel::m_randomEngine = std::mt19937 (std::time(nullptr)); +std::mt19937 BlinnPhongMaterialModel::m_randomEngine = std::mt19937( std::time( nullptr ) ); } // namespace Material } // namespace Core diff --git a/src/Core/Material/MaterialModel.cpp b/src/Core/Material/MaterialModel.cpp index 18a0839c516..6ff495e83f6 100644 --- a/src/Core/Material/MaterialModel.cpp +++ b/src/Core/Material/MaterialModel.cpp @@ -1,6 +1,6 @@ +#include "MaterialModel.hpp" #include #include -#include "MaterialModel.hpp" namespace Ra { namespace Core { @@ -14,7 +14,8 @@ Utils::Color MaterialModel::evalBSDF( Vector3 w_i, Vector3 w_o, Vector3 normal, return Utils::Color(); } -std::optional> MaterialModel::sample( Vector3 inDir, Vector3 normal, Vector2 u ) { +std::optional> +MaterialModel::sample( Vector3 inDir, Vector3 normal, Vector2 u ) { return {}; } @@ -23,48 +24,49 @@ Scalar MaterialModel::PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) { } void MaterialModel::coordinateSystem( Vector3 normal, Vector3* tangent, Vector3* bitangent ) { - if (std::abs(normal[0]) > std::abs(normal[1])) { - Scalar invLen = 1 / std::sqrt(normal[0] * normal[0] + normal[2] * normal[2]); - *tangent = Vector3(-normal[2] * invLen, 0, normal[0] * invLen); - } else { - Scalar invLen = 1 / std::sqrt(normal[1] * normal[1] + normal[2] * normal[2]); - *tangent = Vector3(0, normal[2] * invLen, -normal[1] * invLen); + if ( std::abs( normal[0] ) > std::abs( normal[1] ) ) { + Scalar invLen = 1 / std::sqrt( normal[0] * normal[0] + normal[2] * normal[2] ); + *tangent = Vector3( -normal[2] * invLen, 0, normal[0] * invLen ); } - *bitangent = normal.cross(*tangent); + else { + Scalar invLen = 1 / std::sqrt( normal[1] * normal[1] + normal[2] * normal[2] ); + *tangent = Vector3( 0, normal[2] * invLen, -normal[1] * invLen ); + } + *bitangent = normal.cross( *tangent ); } std::pair MaterialModel::sampleHemisphereCosineWeighted( Vector2 u ) { Vector3 dir; - - Scalar cosTheta = std::sqrt(u[0]); - Scalar sinTheta = std::sqrt(1-u[0]); - Scalar phi = 2 * Math::Pi * u[1]; - dir[0] = sinTheta * std::cos(phi); - dir[1] = sinTheta * std::sin(phi); + Scalar cosTheta = std::sqrt( u[0] ); + Scalar sinTheta = std::sqrt( 1 - u[0] ); + Scalar phi = 2 * Math::Pi * u[1]; + + dir[0] = sinTheta * std::cos( phi ); + dir[1] = sinTheta * std::sin( phi ); dir[2] = cosTheta; - - return {dir, cosTheta/Math::Pi}; + + return { dir, cosTheta / Math::Pi }; } std::pair MaterialModel::sampleHemisphere( Vector2 u ) { Vector3 dir; - + Scalar cosTheta = u[0]; - Scalar sinTheta = 1-u[0]; - Scalar phi = 2 * Math::Pi * u[1]; + Scalar sinTheta = 1 - u[0]; + Scalar phi = 2 * Math::Pi * u[1]; - dir[0] = sinTheta * std::cos(phi); - dir[1] = sinTheta * std::sin(phi); + dir[0] = sinTheta * std::cos( phi ); + dir[1] = sinTheta * std::sin( phi ); dir[2] = cosTheta; - - return {dir, 1_ra/(2_ra*Math::Pi)}; + + return { dir, 1_ra / ( 2_ra * Math::Pi ) }; } Scalar MaterialModel::cosineWeightedPDF( Vector3 dir, Vector3 normal ) { dir.normalize(); - Scalar cosTheta = dir.dot(normal); + Scalar cosTheta = dir.dot( normal ); return cosTheta / M_PI; } diff --git a/src/Core/Material/MaterialModel.hpp b/src/Core/Material/MaterialModel.hpp index b11f74ee218..c1619a5ac5e 100644 --- a/src/Core/Material/MaterialModel.hpp +++ b/src/Core/Material/MaterialModel.hpp @@ -1,14 +1,14 @@ #pragma once -#include #include #include +#include #include #include -#include #include +#include namespace Ra { namespace Core { @@ -39,16 +39,17 @@ class RA_CORE_API MaterialModel : public Utils::ObservableVoid * w_i : incident direction, w_o : outgoing direction, normal : geometric normal direction. * w_i, w_o and normal are in world space. */ - virtual Utils::Color evalBSDF(Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv); - virtual std::optional> sample(Vector3 inDir, Vector3 normal, Vector2 u); - virtual Scalar PDF(Vector3 inDir, Vector3 outDir, Vector3 normal); + virtual Utils::Color evalBSDF( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ); + virtual std::optional> + sample( Vector3 inDir, Vector3 normal, Vector2 u ); + virtual Scalar PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ); - void coordinateSystem(Vector3 normal, Vector3* tangent, Vector3* bitangent); + void coordinateSystem( Vector3 normal, Vector3* tangent, Vector3* bitangent ); - std::pair sampleHemisphereCosineWeighted(Vector2 u); - std::pair sampleHemisphere(Vector2 u); + std::pair sampleHemisphereCosineWeighted( Vector2 u ); + std::pair sampleHemisphere( Vector2 u ); - Scalar cosineWeightedPDF(Vector3 dir, Vector3 normal); + Scalar cosineWeightedPDF( Vector3 dir, Vector3 normal ); private: std::string m_materialType; diff --git a/src/Core/Material/SimpleMaterialModel.cpp b/src/Core/Material/SimpleMaterialModel.cpp index e87846a2fa4..6b80c4b8ab5 100644 --- a/src/Core/Material/SimpleMaterialModel.cpp +++ b/src/Core/Material/SimpleMaterialModel.cpp @@ -1,7 +1,7 @@ #include -#include #include "SimpleMaterialModel.hpp" +#include namespace Ra { namespace Core { @@ -42,30 +42,29 @@ Utils::Color Material::LambertianMaterialModel::evalBSDF( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) { - if(w_i.dot(normal) <= 0 || w_o.dot(normal) <= 0) { - return Utils::Color::Black(); - } + if ( w_i.dot( normal ) <= 0 || w_o.dot( normal ) <= 0 ) { return Utils::Color::Black(); } return m_kd / M_PI; } -std::optional> LambertianMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector2 u ) { +std::optional> +LambertianMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector2 u ) { // create local to normal coordinate system Vector3 tangent, bitangent; - coordinateSystem(normal, &tangent, &bitangent); + coordinateSystem( normal, &tangent, &bitangent ); // sample point on hemisphere with cosine-weighted distribution - std::pair smpl = sampleHemisphereCosineWeighted(u); + std::pair smpl = sampleHemisphereCosineWeighted( u ); // transform sampled point from local to world coodinate system - Vector3 wi(smpl.first.dot(tangent), smpl.first.dot(bitangent), smpl.first.dot(normal)); - std::pair result {wi, smpl.second}; + Vector3 wi( smpl.first.dot( tangent ), smpl.first.dot( bitangent ), smpl.first.dot( normal ) ); + std::pair result { wi, smpl.second }; return result; } Scalar LambertianMaterialModel::PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) { - return cosineWeightedPDF(outDir, normal); + return cosineWeightedPDF( outDir, normal ); } } // namespace Material diff --git a/src/Core/Material/SimpleMaterialModel.hpp b/src/Core/Material/SimpleMaterialModel.hpp index 07ed53a3356..a9643b5c25a 100644 --- a/src/Core/Material/SimpleMaterialModel.hpp +++ b/src/Core/Material/SimpleMaterialModel.hpp @@ -47,9 +47,10 @@ class RA_CORE_API LambertianMaterialModel : public SimpleMaterialModel /// QUERY bool hasNormalTexture() const { return m_hasTexNormal; } - Utils::Color evalBSDF(Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv) override; - std::optional> sample(Vector3 inDir, Vector3 normal, Vector2 u) override; - Scalar PDF(Vector3 inDir, Vector3 outDir, Vector3 normal) override; + Utils::Color evalBSDF( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) override; + std::optional> + sample( Vector3 inDir, Vector3 normal, Vector2 u ) override; + Scalar PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) override; /// DATA MEMBERS std::string m_texNormal; From 862a60ba4bef6243b9ecdfa49badc986695a9eab Mon Sep 17 00:00:00 2001 From: grandch Date: Wed, 21 Jun 2023 11:20:14 +0200 Subject: [PATCH 09/56] [core] return reference to random generator --- src/Core/Material/BlinnPhongMaterialModel.cpp | 4 ++-- src/Core/Material/BlinnPhongMaterialModel.hpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Core/Material/BlinnPhongMaterialModel.cpp b/src/Core/Material/BlinnPhongMaterialModel.cpp index fa30c7d4d5e..3a69b21a7a5 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.cpp +++ b/src/Core/Material/BlinnPhongMaterialModel.cpp @@ -124,9 +124,9 @@ Scalar BlinnPhongMaterialModel::getRoughness() { return 1 - m_ns; } -std::mt19937 BlinnPhongMaterialModel::getRandomEngine() { +std::mt19937* BlinnPhongMaterialModel::getRandomEngine() { - return m_randomEngine; + return &m_randomEngine; } } // namespace Material diff --git a/src/Core/Material/BlinnPhongMaterialModel.hpp b/src/Core/Material/BlinnPhongMaterialModel.hpp index 9e9eb913333..6733a4aa908 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.hpp +++ b/src/Core/Material/BlinnPhongMaterialModel.hpp @@ -41,7 +41,7 @@ class RA_CORE_API BlinnPhongMaterialModel : public MaterialModel Scalar getRoughness(); - static std::mt19937 getRandomEngine(); + static std::mt19937* getRandomEngine(); /// DATA MEMBERS Core::Utils::Color m_kd { 0.7_ra, 0.7_ra, 0.7_ra }; From 151309fb2650d80cb84fc2d8237f7d3d1d128bb6 Mon Sep 17 00:00:00 2001 From: grandch Date: Wed, 21 Jun 2023 11:34:29 +0200 Subject: [PATCH 10/56] [core] move math methods to LinearAlgebra --- src/Core/Material/BlinnPhongMaterialModel.cpp | 31 ++------- src/Core/Material/BlinnPhongMaterialModel.hpp | 3 - src/Core/Material/MaterialModel.cpp | 50 +------------- src/Core/Material/MaterialModel.hpp | 7 -- src/Core/Material/SimpleMaterialModel.cpp | 8 +-- src/Core/Math/LinearAlgebra.hpp | 67 +++++++++++++++++++ 6 files changed, 78 insertions(+), 88 deletions(-) diff --git a/src/Core/Material/BlinnPhongMaterialModel.cpp b/src/Core/Material/BlinnPhongMaterialModel.cpp index 3a69b21a7a5..2c6cc322d41 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.cpp +++ b/src/Core/Material/BlinnPhongMaterialModel.cpp @@ -1,7 +1,7 @@ #include +#include #include -#include "BlinnPhongMaterialModel.hpp" #include namespace Ra { @@ -48,7 +48,7 @@ std::optional> BlinnPhongMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector2 u ) { Vector3 halfway, tangent, bitangent; - coordinateSystem( normal, &tangent, &bitangent ); + Math::coordinateSystem( normal, &tangent, &bitangent ); Vector3 rgbToLuminance { 0.2126_ra, 0.7152_ra, 0.0722_ra }; Scalar dIntensity = m_kd.rgb().dot( rgbToLuminance ); @@ -65,14 +65,14 @@ BlinnPhongMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector2 u ) { // diffuse part if ( distrib < dIntensity ) { - std::pair smpl = sampleHemisphereCosineWeighted( u ); + std::pair smpl = Math::sampleHemisphereCosineWeighted( u ); Vector3 wi( smpl.first.dot( tangent ), smpl.first.dot( bitangent ), smpl.first.dot( normal ) ); std::pair result { wi, smpl.second }; return result; } else if ( distrib < dIntensity + sIntensity ) { // specular part - std::pair smpl = sampleSpecular( u, roughness ); + std::pair smpl = Math::sampleSpecular( u, roughness ); Vector3 wi( smpl.first.dot( tangent ), smpl.first.dot( bitangent ), smpl.first.dot( normal ) ); std::pair result { wi, smpl.second }; @@ -92,31 +92,12 @@ Scalar BlinnPhongMaterialModel::PDF( Vector3 inDir, Vector3 outDir, Vector3 norm dIntensity /= diffSpecNorm; sIntensity /= diffSpecNorm; - return std::clamp( dIntensity * cosineWeightedPDF( outDir, normal ) + - sIntensity * specularPDF( outDir, normal ), + return std::clamp( dIntensity * Math::cosineWeightedPDF( outDir, normal ) + + sIntensity * Math::specularPDF( outDir, normal, getRoughness() ), 0_ra, 1_ra ); } -std::pair BlinnPhongMaterialModel::sampleSpecular( Vector2 u, Scalar roughness ) { - Vector3 dir; - - Scalar cosTheta = std::pow( u[0], 1_ra / ( roughness + 2 ) ); - Scalar sinTheta = 1 - u[0]; - Scalar phi = 2 * Math::Pi * u[1]; - - dir[0] = sinTheta * std::cos( phi ); - dir[1] = sinTheta * std::sin( phi ); - dir[2] = cosTheta; - - return { dir, ( roughness + 2 ) * std::pow( u[0], roughness ) / 2 * Math::Pi }; -} - -Scalar BlinnPhongMaterialModel::specularPDF( Vector3 dir, Vector3 normal, Scalar roughness ) { - Scalar cosTheta = normal.dot( dir ); - return ( roughness + 2 ) * std::pow( cosTheta, roughness ) / 2 * Math::Pi; -} - Scalar BlinnPhongMaterialModel::getRoughness() { Scalar ns = m_ns; if ( ns > 1 ) { ns /= 128_ra; } diff --git a/src/Core/Material/BlinnPhongMaterialModel.hpp b/src/Core/Material/BlinnPhongMaterialModel.hpp index 6733a4aa908..ab296cf697d 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.hpp +++ b/src/Core/Material/BlinnPhongMaterialModel.hpp @@ -36,9 +36,6 @@ class RA_CORE_API BlinnPhongMaterialModel : public MaterialModel sample( Vector3 inDir, Vector3 normal, Vector2 u ) override; Scalar PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) override; - std::pair sampleSpecular( Vector2 u, Scalar roughness ); - Scalar specularPDF( Vector3 dir, Vector3 normal, Scalar roughness ); - Scalar getRoughness(); static std::mt19937* getRandomEngine(); diff --git a/src/Core/Material/MaterialModel.cpp b/src/Core/Material/MaterialModel.cpp index 6ff495e83f6..e1b5f6b86d0 100644 --- a/src/Core/Material/MaterialModel.cpp +++ b/src/Core/Material/MaterialModel.cpp @@ -20,55 +20,7 @@ MaterialModel::sample( Vector3 inDir, Vector3 normal, Vector2 u ) { } Scalar MaterialModel::PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) { - return 0.0f; -} - -void MaterialModel::coordinateSystem( Vector3 normal, Vector3* tangent, Vector3* bitangent ) { - if ( std::abs( normal[0] ) > std::abs( normal[1] ) ) { - Scalar invLen = 1 / std::sqrt( normal[0] * normal[0] + normal[2] * normal[2] ); - *tangent = Vector3( -normal[2] * invLen, 0, normal[0] * invLen ); - } - else { - Scalar invLen = 1 / std::sqrt( normal[1] * normal[1] + normal[2] * normal[2] ); - *tangent = Vector3( 0, normal[2] * invLen, -normal[1] * invLen ); - } - *bitangent = normal.cross( *tangent ); -} - -std::pair MaterialModel::sampleHemisphereCosineWeighted( Vector2 u ) { - Vector3 dir; - - Scalar cosTheta = std::sqrt( u[0] ); - Scalar sinTheta = std::sqrt( 1 - u[0] ); - Scalar phi = 2 * Math::Pi * u[1]; - - dir[0] = sinTheta * std::cos( phi ); - dir[1] = sinTheta * std::sin( phi ); - dir[2] = cosTheta; - - return { dir, cosTheta / Math::Pi }; -} - -std::pair MaterialModel::sampleHemisphere( Vector2 u ) { - Vector3 dir; - - Scalar cosTheta = u[0]; - Scalar sinTheta = 1 - u[0]; - Scalar phi = 2 * Math::Pi * u[1]; - - dir[0] = sinTheta * std::cos( phi ); - dir[1] = sinTheta * std::sin( phi ); - dir[2] = cosTheta; - - return { dir, 1_ra / ( 2_ra * Math::Pi ) }; -} - -Scalar MaterialModel::cosineWeightedPDF( Vector3 dir, Vector3 normal ) { - dir.normalize(); - - Scalar cosTheta = dir.dot( normal ); - - return cosTheta / M_PI; + return 0.0_ra; } } // namespace Material diff --git a/src/Core/Material/MaterialModel.hpp b/src/Core/Material/MaterialModel.hpp index c1619a5ac5e..6a959127417 100644 --- a/src/Core/Material/MaterialModel.hpp +++ b/src/Core/Material/MaterialModel.hpp @@ -44,13 +44,6 @@ class RA_CORE_API MaterialModel : public Utils::ObservableVoid sample( Vector3 inDir, Vector3 normal, Vector2 u ); virtual Scalar PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ); - void coordinateSystem( Vector3 normal, Vector3* tangent, Vector3* bitangent ); - - std::pair sampleHemisphereCosineWeighted( Vector2 u ); - std::pair sampleHemisphere( Vector2 u ); - - Scalar cosineWeightedPDF( Vector3 dir, Vector3 normal ); - private: std::string m_materialType; std::string m_name; diff --git a/src/Core/Material/SimpleMaterialModel.cpp b/src/Core/Material/SimpleMaterialModel.cpp index 6b80c4b8ab5..9630c8cc0f7 100644 --- a/src/Core/Material/SimpleMaterialModel.cpp +++ b/src/Core/Material/SimpleMaterialModel.cpp @@ -1,6 +1,6 @@ #include +#include -#include "SimpleMaterialModel.hpp" #include namespace Ra { @@ -51,10 +51,10 @@ std::optional> LambertianMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector2 u ) { // create local to normal coordinate system Vector3 tangent, bitangent; - coordinateSystem( normal, &tangent, &bitangent ); + Math::coordinateSystem( normal, &tangent, &bitangent ); // sample point on hemisphere with cosine-weighted distribution - std::pair smpl = sampleHemisphereCosineWeighted( u ); + std::pair smpl = Math::sampleHemisphereCosineWeighted( u ); // transform sampled point from local to world coodinate system Vector3 wi( smpl.first.dot( tangent ), smpl.first.dot( bitangent ), smpl.first.dot( normal ) ); @@ -64,7 +64,7 @@ LambertianMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector2 u ) { } Scalar LambertianMaterialModel::PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) { - return cosineWeightedPDF( outDir, normal ); + return Math::cosineWeightedPDF( outDir, normal ); } } // namespace Material diff --git a/src/Core/Math/LinearAlgebra.hpp b/src/Core/Math/LinearAlgebra.hpp index 853212b3004..318c1c70ed0 100644 --- a/src/Core/Math/LinearAlgebra.hpp +++ b/src/Core/Math/LinearAlgebra.hpp @@ -123,6 +123,73 @@ inline Matrix4 perspective( Scalar fovy, Scalar aspect, Scalar near, Scalar zfar inline Matrix4 orthographic( Scalar left, Scalar right, Scalar bottom, Scalar top, Scalar near, Scalar zfar ); +inline void coordinateSystem( Vector3 normal, Vector3* tangent, Vector3* bitangent ) { + if ( std::abs( normal[0] ) > std::abs( normal[1] ) ) { + Scalar invLen = 1 / std::sqrt( normal[0] * normal[0] + normal[2] * normal[2] ); + *tangent = Vector3( -normal[2] * invLen, 0, normal[0] * invLen ); + } + else { + Scalar invLen = 1 / std::sqrt( normal[1] * normal[1] + normal[2] * normal[2] ); + *tangent = Vector3( 0, normal[2] * invLen, -normal[1] * invLen ); + } + *bitangent = normal.cross( *tangent ); +} + +inline std::pair sampleHemisphereCosineWeighted( Vector2 u ) { + Vector3 dir; + + Scalar cosTheta = std::sqrt( u[0] ); + Scalar sinTheta = std::sqrt( 1 - u[0] ); + Scalar phi = 2 * Math::Pi * u[1]; + + dir[0] = sinTheta * std::cos( phi ); + dir[1] = sinTheta * std::sin( phi ); + dir[2] = cosTheta; + + return { dir, cosTheta / Math::Pi }; +} + +inline std::pair sampleHemisphere( Vector2 u ) { + Vector3 dir; + + Scalar cosTheta = u[0]; + Scalar sinTheta = 1 - u[0]; + Scalar phi = 2 * Math::Pi * u[1]; + + dir[0] = sinTheta * std::cos( phi ); + dir[1] = sinTheta * std::sin( phi ); + dir[2] = cosTheta; + + return { dir, 1_ra / ( 2_ra * Math::Pi ) }; +} + +inline std::pair sampleSpecular( Vector2 u, Scalar roughness ) { + Vector3 dir; + + Scalar cosTheta = std::pow( u[0], 1_ra / ( roughness + 2 ) ); + Scalar sinTheta = 1 - u[0]; + Scalar phi = 2 * Math::Pi * u[1]; + + dir[0] = sinTheta * std::cos( phi ); + dir[1] = sinTheta * std::sin( phi ); + dir[2] = cosTheta; + + return { dir, ( roughness + 2 ) * std::pow( u[0], roughness ) / 2 * Math::Pi }; +} + +inline Scalar cosineWeightedPDF( Vector3 dir, Vector3 normal ) { + dir.normalize(); + + Scalar cosTheta = dir.dot( normal ); + + return cosTheta / M_PI; +} + +inline Scalar specularPDF( Vector3 dir, Vector3 normal, Scalar roughness ) { + Scalar cosTheta = normal.dot( dir ); + return ( roughness + 2 ) * std::pow( cosTheta, roughness ) / 2 * Math::Pi; +} + // // Quaternion functions // From 467226880f2afdec665f4c131d58865b8f2e59eb Mon Sep 17 00:00:00 2001 From: grandch Date: Tue, 27 Jun 2023 14:57:57 +0200 Subject: [PATCH 11/56] first uniformgenerator and importancesampler --- .../Random/CosineWeightedSphereSampler.cpp | 21 +++++++++++++++ .../Random/CosineWeightedSphereSampler.hpp | 19 ++++++++++++++ src/Core/Random/ImportanceSampler.hpp | 16 ++++++++++++ src/Core/Random/MersenneTwisterGenerator.cpp | 9 +++++++ src/Core/Random/MersenneTwisterGenerator.hpp | 24 +++++++++++++++++ src/Core/Random/SphereSampler.hpp | 22 ++++++++++++++++ src/Core/Random/UniformGenerator.cpp | 19 ++++++++++++++ src/Core/Random/UniformGenerator.hpp | 26 +++++++++++++++++++ src/Core/Random/UniformSphereSampler.cpp | 21 +++++++++++++++ src/Core/Random/UniformSphereSampler.hpp | 19 ++++++++++++++ 10 files changed, 196 insertions(+) create mode 100644 src/Core/Random/CosineWeightedSphereSampler.cpp create mode 100644 src/Core/Random/CosineWeightedSphereSampler.hpp create mode 100644 src/Core/Random/ImportanceSampler.hpp create mode 100644 src/Core/Random/MersenneTwisterGenerator.cpp create mode 100644 src/Core/Random/MersenneTwisterGenerator.hpp create mode 100644 src/Core/Random/SphereSampler.hpp create mode 100644 src/Core/Random/UniformGenerator.cpp create mode 100644 src/Core/Random/UniformGenerator.hpp create mode 100644 src/Core/Random/UniformSphereSampler.cpp create mode 100644 src/Core/Random/UniformSphereSampler.hpp diff --git a/src/Core/Random/CosineWeightedSphereSampler.cpp b/src/Core/Random/CosineWeightedSphereSampler.cpp new file mode 100644 index 00000000000..ca8d7dcf6e0 --- /dev/null +++ b/src/Core/Random/CosineWeightedSphereSampler.cpp @@ -0,0 +1,21 @@ +#include "CosineWeightedSphereSampler.hpp" + +std::pair Ra::Core::Random::CosineWeightedSphereSampler::getPoint( UniformGenerator* generator ) { + Vector2 u = generator->get2D(); + return {{std::sqrt( u[0] ), 2 * Math::Pi * u[1]}, u[0] / Math::Pi}; +} + +std::pair Ra::Core::Random::CosineWeightedSphereSampler::getDir( UniformGenerator* generator ) { + Vector3 dir; + Vector2 u = generator->get2D(); + + Scalar cosTheta = std::sqrt( u[0] ); + Scalar sinTheta = std::sqrt( 1 - u[0] ); + Scalar phi = 2 * Math::Pi * u[1]; + + dir[0] = sinTheta * std::cos( phi ); + dir[1] = sinTheta * std::sin( phi ); + dir[2] = cosTheta; + + return {dir, u[0] / Math::Pi}; +} \ No newline at end of file diff --git a/src/Core/Random/CosineWeightedSphereSampler.hpp b/src/Core/Random/CosineWeightedSphereSampler.hpp new file mode 100644 index 00000000000..cea0c190d86 --- /dev/null +++ b/src/Core/Random/CosineWeightedSphereSampler.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include + +namespace Ra { +namespace Core { +namespace Random { + +class RA_CORE_API CosineWeightedSphereSampler : public SphereSampler { + CosineWeightedSphereSampler(); + ~CosineWeightedSphereSampler(); + + std::pair getPoint( UniformGenerator* generator ); + std::pair getDir( UniformGenerator* generator ); +}; + +} // namespace Random +} // namespace Core +} // namespace Ra \ No newline at end of file diff --git a/src/Core/Random/ImportanceSampler.hpp b/src/Core/Random/ImportanceSampler.hpp new file mode 100644 index 00000000000..967501ea245 --- /dev/null +++ b/src/Core/Random/ImportanceSampler.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include + +namespace Ra { +namespace Core { +namespace Random { + +class RA_CORE_API ImportanceSampler { + virtual ImportanceSampler() = 0; + virtual ~ImportanceSampler() = 0; +}; + +} // namespace Random +} // namespace Core +} // namespace Ra \ No newline at end of file diff --git a/src/Core/Random/MersenneTwisterGenerator.cpp b/src/Core/Random/MersenneTwisterGenerator.cpp new file mode 100644 index 00000000000..d7bdaf71295 --- /dev/null +++ b/src/Core/Random/MersenneTwisterGenerator.cpp @@ -0,0 +1,9 @@ +#include "MersenneTwisterGenerator.hpp" + +Ra::Core::Random::MersenneTwisterGenerator::UniformGenerator() {} + +Ra::Core::Random::MersenneTwisterGenerator::~MersenneTwisterGenerator() {} + +Scalar Ra::Core::Random::MersenneTwisterGenerator::get1D() { + return m_unifDistributionRand( m_randomEngine ); +} \ No newline at end of file diff --git a/src/Core/Random/MersenneTwisterGenerator.hpp b/src/Core/Random/MersenneTwisterGenerator.hpp new file mode 100644 index 00000000000..9422aea9268 --- /dev/null +++ b/src/Core/Random/MersenneTwisterGenerator.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include + +#include + +namespace Ra { +namespace Core { +namespace Random { + +class RA_CORE_API MersenneTwisterGenerator : public UniformGenerator { + MersenneTwisterGenerator(); + ~MersenneTwisterGenerator(); + + Scalar get1D(); + + static std::mt19937 m_randomEngine = std::mt19937( std::time( nullptr ) ); +}; + +std::mt19937 MersenneTwisterGenerator::m_randomEngine = std::mt19937( std::time( nullptr ) ); + +} // namespace Random +} // namespace Core +} // namespace Ra \ No newline at end of file diff --git a/src/Core/Random/SphereSampler.hpp b/src/Core/Random/SphereSampler.hpp new file mode 100644 index 00000000000..28e81796ae1 --- /dev/null +++ b/src/Core/Random/SphereSampler.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include + +namespace Ra { +namespace Core { +namespace Random { + +class RA_CORE_API SphereSampler : public ImportanceSampler { + virtual SphereSampler() = 0; + virtual ~SphereSampler() = 0; + + virtual Vector2 getPoint( UniformGenerator* generator ) = 0; + virtual Vector3 getDir( UniformGenerator* generator ) = 0; + + virtual Scalar pdf( Vector3 dir ) = 0; + virtual Scalar pdf( Vector2 point ) = 0; +}; + +} // namespace Random +} // namespace Core +} // namespace Ra \ No newline at end of file diff --git a/src/Core/Random/UniformGenerator.cpp b/src/Core/Random/UniformGenerator.cpp new file mode 100644 index 00000000000..c3daa0483c2 --- /dev/null +++ b/src/Core/Random/UniformGenerator.cpp @@ -0,0 +1,19 @@ +#include "UniformGenerator.hpp" + +Vector2 Ra::Core::Random::UniformGenerator::get2D() { + return {get1D(), get1D()}; +} + +Vector3 Ra::Core::Random::UniformGenerator::get3D() { + return {get1D(), get1D(), get1D()}; +} + +VectorN Ra::Core::Random::UniformGenerator::getXD( int dim ) { + Eigen::Matrix; result; + + for(int i = 0; i < dim; i++) { + result[i] = get1D(); + } + + return result; +} diff --git a/src/Core/Random/UniformGenerator.hpp b/src/Core/Random/UniformGenerator.hpp new file mode 100644 index 00000000000..33caa3b5103 --- /dev/null +++ b/src/Core/Random/UniformGenerator.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include + +#include + +namespace Ra { +namespace Core { +namespace Random { + +class RA_CORE_API UniformGenerator { + virtual UniformGenerator() = 0; + virtual ~UniformGenerator() = 0; + + virtual Scalar get1D() = 0; + + virtual Vector2 get2D(); + virtual Vector3 get3D(); + virtual VectorN getXD(int dim); + + std::uniform_real_distribution m_unifDistributionRand { 0, 1 }; +}; + +} // namespace Random +} // namespace Core +} // namespace Ra \ No newline at end of file diff --git a/src/Core/Random/UniformSphereSampler.cpp b/src/Core/Random/UniformSphereSampler.cpp new file mode 100644 index 00000000000..1cd16114491 --- /dev/null +++ b/src/Core/Random/UniformSphereSampler.cpp @@ -0,0 +1,21 @@ +#include "UniformSphereSampler.hpp" + +std::pair Ra::Core::Random::UniformSphereSampler::getPoint( UniformGenerator* generator ) { + Vector2 u = generator->get2D(); + return {{u[0], 2 * Math::Pi * u[1]}, 1 / 2 * Math::Pi}; +} + +std::pair Ra::Core::Random::UniformSphereSampler::getDir( UniformGenerator* generator ) { + Vector3 dir; + Vector2 u = generator->get2D(); + + Scalar cosTheta = u[0]; + Scalar sinTheta = 1 - u[0]; + Scalar phi = 2 * Math::Pi * u[1]; + + dir[0] = sinTheta * std::cos( phi ); + dir[1] = sinTheta * std::sin( phi ); + dir[2] = cosTheta; + + return {dir, 1 / 2 * Math::Pi}; +} \ No newline at end of file diff --git a/src/Core/Random/UniformSphereSampler.hpp b/src/Core/Random/UniformSphereSampler.hpp new file mode 100644 index 00000000000..857b42e2089 --- /dev/null +++ b/src/Core/Random/UniformSphereSampler.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include + +namespace Ra { +namespace Core { +namespace Random { + +class RA_CORE_API UniformSphereSampler : public SphereSampler { + UniformSphereSampler(); + ~UniformSphereSampler(); + + std::pair getPoint( UniformGenerator* generator ); + std::pair getDir( UniformGenerator* generator ); +}; + +} // namespace Random +} // namespace Core +} // namespace Ra \ No newline at end of file From 1df63e3175734cfe5c53e18e89d171439e280be2 Mon Sep 17 00:00:00 2001 From: grandch Date: Tue, 27 Jun 2023 17:26:24 +0200 Subject: [PATCH 12/56] wip --- src/Core/Material/BlinnPhongMaterialModel.cpp | 6 +++--- src/Core/Material/MaterialModel.cpp | 13 ------------- src/Core/Material/MaterialModel.hpp | 6 +++--- src/Core/Material/SimpleMaterialModel.cpp | 17 ++++++++++++++++- src/Core/Material/SimpleMaterialModel.hpp | 5 +++++ src/Core/Random/CosineWeightedSphereSampler.hpp | 4 ++-- src/Core/Random/MersenneTwisterGenerator.hpp | 2 +- src/Core/Random/UniformSphereSampler.hpp | 4 ++-- 8 files changed, 32 insertions(+), 25 deletions(-) diff --git a/src/Core/Material/BlinnPhongMaterialModel.cpp b/src/Core/Material/BlinnPhongMaterialModel.cpp index 2c6cc322d41..5fbed59650d 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.cpp +++ b/src/Core/Material/BlinnPhongMaterialModel.cpp @@ -58,14 +58,14 @@ BlinnPhongMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector2 u ) { dIntensity /= diffSpecNorm; sIntensity /= diffSpecNorm; - std::uniform_real_distribution unifDistributionRand { 0, 1 }; - Scalar distrib = unifDistributionRand( m_randomEngine ); + Random::MersenneTwisterGenerator generator = Random::MersenneTwisterGenerator(); + Scalar distrib = generator.get1D(); Scalar roughness = getRoughness(); // diffuse part if ( distrib < dIntensity ) { - std::pair smpl = Math::sampleHemisphereCosineWeighted( u ); + std::pair smpl = Random::CosineWeightedSphereSampler::getDir(&generator); Vector3 wi( smpl.first.dot( tangent ), smpl.first.dot( bitangent ), smpl.first.dot( normal ) ); std::pair result { wi, smpl.second }; diff --git a/src/Core/Material/MaterialModel.cpp b/src/Core/Material/MaterialModel.cpp index e1b5f6b86d0..f6f0cd5b574 100644 --- a/src/Core/Material/MaterialModel.cpp +++ b/src/Core/Material/MaterialModel.cpp @@ -10,19 +10,6 @@ void MaterialModel::displayInfo() const { LOG( logERROR ) << "MaterialModel : unknown material type : " << m_materialType; } -Utils::Color MaterialModel::evalBSDF( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) { - return Utils::Color(); -} - -std::optional> -MaterialModel::sample( Vector3 inDir, Vector3 normal, Vector2 u ) { - return {}; -} - -Scalar MaterialModel::PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) { - return 0.0_ra; -} - } // namespace Material } // namespace Core } // namespace Ra diff --git a/src/Core/Material/MaterialModel.hpp b/src/Core/Material/MaterialModel.hpp index 6a959127417..0f0a8f79b4c 100644 --- a/src/Core/Material/MaterialModel.hpp +++ b/src/Core/Material/MaterialModel.hpp @@ -39,10 +39,10 @@ class RA_CORE_API MaterialModel : public Utils::ObservableVoid * w_i : incident direction, w_o : outgoing direction, normal : geometric normal direction. * w_i, w_o and normal are in world space. */ - virtual Utils::Color evalBSDF( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ); + virtual Utils::Color evalBSDF( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) = 0; virtual std::optional> - sample( Vector3 inDir, Vector3 normal, Vector2 u ); - virtual Scalar PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ); + sample( Vector3 inDir, Vector3 normal, Vector2 u ) = 0; + virtual Scalar PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) = 0; private: std::string m_materialType; diff --git a/src/Core/Material/SimpleMaterialModel.cpp b/src/Core/Material/SimpleMaterialModel.cpp index 9630c8cc0f7..bf7c55a3c83 100644 --- a/src/Core/Material/SimpleMaterialModel.cpp +++ b/src/Core/Material/SimpleMaterialModel.cpp @@ -1,7 +1,10 @@ #include #include +#include +#include #include +#include "SimpleMaterialModel.hpp" namespace Ra { namespace Core { @@ -22,6 +25,17 @@ void SimpleMaterialModel::displayInfo() const { print( hasOpacityTexture(), " Alpha Texture : ", m_texOpacity ); } +Utils::Color SimpleMaterialModel::evalBSDF( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) { + return m_kd; +} +std::optional> +SimpleMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector2 u ) { + return {}; +} +Scalar SimpleMaterialModel::PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) { + return 0_ra; +} + void LambertianMaterialModel::displayInfo() const { using namespace Core::Utils; // log auto print = []( bool ok, const std::string& name, const auto& value ) { @@ -54,7 +68,8 @@ LambertianMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector2 u ) { Math::coordinateSystem( normal, &tangent, &bitangent ); // sample point on hemisphere with cosine-weighted distribution - std::pair smpl = Math::sampleHemisphereCosineWeighted( u ); + Random::MersenneTwisterGenerator generator = Random::MersenneTwisterGenerator(); + std::pair smpl = Random::CosineWeightedSphereSampler::getDir(&generator); // transform sampled point from local to world coodinate system Vector3 wi( smpl.first.dot( tangent ), smpl.first.dot( bitangent ), smpl.first.dot( normal ) ); diff --git a/src/Core/Material/SimpleMaterialModel.hpp b/src/Core/Material/SimpleMaterialModel.hpp index a9643b5c25a..acb91a49507 100644 --- a/src/Core/Material/SimpleMaterialModel.hpp +++ b/src/Core/Material/SimpleMaterialModel.hpp @@ -25,6 +25,11 @@ class RA_CORE_API SimpleMaterialModel : public MaterialModel bool hasDiffuseTexture() const { return m_hasTexDiffuse; } bool hasOpacityTexture() const { return m_hasTexOpacity; } + Utils::Color evalBSDF( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) override; + std::optional> + sample( Vector3 inDir, Vector3 normal, Vector2 u ) override; + Scalar PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) override; + /// DATA MEMBERS Core::Utils::Color m_kd { 0.9_ra, 0.9_ra, 0.9_ra }; Scalar m_alpha { 1_ra }; diff --git a/src/Core/Random/CosineWeightedSphereSampler.hpp b/src/Core/Random/CosineWeightedSphereSampler.hpp index cea0c190d86..3758c5f5e59 100644 --- a/src/Core/Random/CosineWeightedSphereSampler.hpp +++ b/src/Core/Random/CosineWeightedSphereSampler.hpp @@ -10,8 +10,8 @@ class RA_CORE_API CosineWeightedSphereSampler : public SphereSampler { CosineWeightedSphereSampler(); ~CosineWeightedSphereSampler(); - std::pair getPoint( UniformGenerator* generator ); - std::pair getDir( UniformGenerator* generator ); + static std::pair getPoint( UniformGenerator* generator ) override; + static std::pair getDir( UniformGenerator* generator ) override; }; } // namespace Random diff --git a/src/Core/Random/MersenneTwisterGenerator.hpp b/src/Core/Random/MersenneTwisterGenerator.hpp index 9422aea9268..ea2351c0bfc 100644 --- a/src/Core/Random/MersenneTwisterGenerator.hpp +++ b/src/Core/Random/MersenneTwisterGenerator.hpp @@ -12,7 +12,7 @@ class RA_CORE_API MersenneTwisterGenerator : public UniformGenerator { MersenneTwisterGenerator(); ~MersenneTwisterGenerator(); - Scalar get1D(); + Scalar get1D() override; static std::mt19937 m_randomEngine = std::mt19937( std::time( nullptr ) ); }; diff --git a/src/Core/Random/UniformSphereSampler.hpp b/src/Core/Random/UniformSphereSampler.hpp index 857b42e2089..de07873c117 100644 --- a/src/Core/Random/UniformSphereSampler.hpp +++ b/src/Core/Random/UniformSphereSampler.hpp @@ -10,8 +10,8 @@ class RA_CORE_API UniformSphereSampler : public SphereSampler { UniformSphereSampler(); ~UniformSphereSampler(); - std::pair getPoint( UniformGenerator* generator ); - std::pair getDir( UniformGenerator* generator ); + static std::pair getPoint( UniformGenerator* generator ) override; + static std::pair getDir( UniformGenerator* generator ) override; }; } // namespace Random From 497904605f366a2809b5d858ed3664a2a0178aef Mon Sep 17 00:00:00 2001 From: Charlie Grand Date: Wed, 28 Jun 2023 09:38:23 +0200 Subject: [PATCH 13/56] add blinnphongSphereSampler --- src/Core/Material/BlinnPhongMaterialModel.cpp | 2 +- src/Core/Random/BlinnPhongSphereSampler.cpp | 22 +++++++++++++++++++ src/Core/Random/BlinnPhongSphereSampler.hpp | 19 ++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 src/Core/Random/BlinnPhongSphereSampler.cpp create mode 100644 src/Core/Random/BlinnPhongSphereSampler.hpp diff --git a/src/Core/Material/BlinnPhongMaterialModel.cpp b/src/Core/Material/BlinnPhongMaterialModel.cpp index 5fbed59650d..39127568acc 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.cpp +++ b/src/Core/Material/BlinnPhongMaterialModel.cpp @@ -72,7 +72,7 @@ BlinnPhongMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector2 u ) { return result; } else if ( distrib < dIntensity + sIntensity ) { // specular part - std::pair smpl = Math::sampleSpecular( u, roughness ); + std::pair smpl = Random::BlinnPhongSphereSampler( &generator, roughness ); Vector3 wi( smpl.first.dot( tangent ), smpl.first.dot( bitangent ), smpl.first.dot( normal ) ); std::pair result { wi, smpl.second }; diff --git a/src/Core/Random/BlinnPhongSphereSampler.cpp b/src/Core/Random/BlinnPhongSphereSampler.cpp new file mode 100644 index 00000000000..97d8e256c32 --- /dev/null +++ b/src/Core/Random/BlinnPhongSphereSampler.cpp @@ -0,0 +1,22 @@ +#include "BlinnPhongSphereSampler.hpp" + +std::pair +Ra::Core::Random::BlinnPhongSphereSampler::getPoint( UniformGenerator* generator, Scalar roughness ) { + return {{std::pow( u[0], 1_ra / ( roughness + 2 ) ), 2 * Math::Pi * u[1]}, ( roughness + 2 ) * std::pow( u[0], roughness ) / 2 * Math::Pi}; +} + +std::pair +Ra::Core::Random::BlinnPhongSphereSampler::getDir( UniformGenerator* generator, Scalar roughness ) { + Vector3 dir; + Vector2 u = generator->get2D(); + + Scalar cosTheta = std::pow( u[0], 1_ra / ( roughness + 2 ) ); + Scalar sinTheta = 1 - u[0]; + Scalar phi = 2 * Math::Pi * u[1]; + + dir[0] = sinTheta * std::cos( phi ); + dir[1] = sinTheta * std::sin( phi ); + dir[2] = cosTheta; + + return { dir, ( roughness + 2 ) * std::pow( u[0], roughness ) / 2 * Math::Pi }; +} diff --git a/src/Core/Random/BlinnPhongSphereSampler.hpp b/src/Core/Random/BlinnPhongSphereSampler.hpp new file mode 100644 index 00000000000..9bd7123bf40 --- /dev/null +++ b/src/Core/Random/BlinnPhongSphereSampler.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include + +namespace Ra { +namespace Core { +namespace Random { + +class RA_CORE_API BlinnPhongSphereSampler : public SphereSampler { + BlinnPhongSphereSampler(); + ~BlinnPhongSphereSampler(); + + static std::pair getPoint( UniformGenerator* generator, Scalar roughness ) override; + static std::pair getDir( UniformGenerator* generator, Scalar roughness ) override; +}; + +} // namespace Random +} // namespace Core +} // namespace Ra \ No newline at end of file From e6b2d5f95b1bf729065d92922e15a1ba8598d4aa Mon Sep 17 00:00:00 2001 From: grandch Date: Thu, 29 Jun 2023 12:55:11 +0200 Subject: [PATCH 14/56] wip random module --- src/Core/Material/BlinnPhongMaterialModel.cpp | 12 ++++-------- src/Core/Material/BlinnPhongMaterialModel.hpp | 10 ++++------ src/Core/Material/SimpleMaterialModel.cpp | 8 +++----- src/Core/Material/SimpleMaterialModel.hpp | 5 ++++- src/Core/Random/BlinnPhongSphereSampler.cpp | 8 ++++++++ src/Core/Random/BlinnPhongSphereSampler.hpp | 13 +++++++------ src/Core/Random/CosineWeightedSphereSampler.cpp | 10 +++++++++- src/Core/Random/CosineWeightedSphereSampler.hpp | 9 +++++---- src/Core/Random/ImportanceSampler.hpp | 5 +++-- src/Core/Random/MersenneTwisterGenerator.cpp | 12 +++++++++++- src/Core/Random/MersenneTwisterGenerator.hpp | 5 ++--- src/Core/Random/SphereSampler.hpp | 13 +++++++------ src/Core/Random/UniformGenerator.cpp | 8 ++++++++ src/Core/Random/UniformGenerator.hpp | 5 +++-- src/Core/Random/UniformSphereSampler.cpp | 10 +++++++++- src/Core/Random/UniformSphereSampler.hpp | 9 +++++---- 16 files changed, 92 insertions(+), 50 deletions(-) diff --git a/src/Core/Material/BlinnPhongMaterialModel.cpp b/src/Core/Material/BlinnPhongMaterialModel.cpp index 39127568acc..b14834677ce 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.cpp +++ b/src/Core/Material/BlinnPhongMaterialModel.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include @@ -58,21 +59,21 @@ BlinnPhongMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector2 u ) { dIntensity /= diffSpecNorm; sIntensity /= diffSpecNorm; - Random::MersenneTwisterGenerator generator = Random::MersenneTwisterGenerator(); + Core::Random::MersenneTwisterGenerator generator = Core::Random::MersenneTwisterGenerator(); Scalar distrib = generator.get1D(); Scalar roughness = getRoughness(); // diffuse part if ( distrib < dIntensity ) { - std::pair smpl = Random::CosineWeightedSphereSampler::getDir(&generator); + std::pair smpl = m_sampler.CosineWeightedSphereSampler::getDir(&generator); Vector3 wi( smpl.first.dot( tangent ), smpl.first.dot( bitangent ), smpl.first.dot( normal ) ); std::pair result { wi, smpl.second }; return result; } else if ( distrib < dIntensity + sIntensity ) { // specular part - std::pair smpl = Random::BlinnPhongSphereSampler( &generator, roughness ); + std::pair smpl = m_sampler.getDir( &generator, roughness ); Vector3 wi( smpl.first.dot( tangent ), smpl.first.dot( bitangent ), smpl.first.dot( normal ) ); std::pair result { wi, smpl.second }; @@ -105,11 +106,6 @@ Scalar BlinnPhongMaterialModel::getRoughness() { return 1 - m_ns; } -std::mt19937* BlinnPhongMaterialModel::getRandomEngine() { - - return &m_randomEngine; -} - } // namespace Material } // namespace Core } // namespace Ra diff --git a/src/Core/Material/BlinnPhongMaterialModel.hpp b/src/Core/Material/BlinnPhongMaterialModel.hpp index ab296cf697d..00188572e9f 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.hpp +++ b/src/Core/Material/BlinnPhongMaterialModel.hpp @@ -2,6 +2,8 @@ #include #include +#include + #include namespace Ra { @@ -12,7 +14,7 @@ namespace Material { class RA_CORE_API BlinnPhongMaterialModel : public MaterialModel { public: - explicit BlinnPhongMaterialModel( const std::string& name = "" ) : + explicit BlinnPhongMaterialModel( const std::string& name = "" ) : m_sampler(Core::Random::BlinnPhongSphereSampler()), MaterialModel( name, "BlinnPhong" ) {} ~BlinnPhongMaterialModel() override = default; @@ -38,8 +40,6 @@ class RA_CORE_API BlinnPhongMaterialModel : public MaterialModel Scalar getRoughness(); - static std::mt19937* getRandomEngine(); - /// DATA MEMBERS Core::Utils::Color m_kd { 0.7_ra, 0.7_ra, 0.7_ra }; Core::Utils::Color m_ks { 0.3_ra, 0.3_ra, 0.3_ra }; @@ -56,11 +56,9 @@ class RA_CORE_API BlinnPhongMaterialModel : public MaterialModel bool m_hasTexNormal { false }; bool m_hasTexOpacity { false }; - static std::mt19937 m_randomEngine; + Core::Random::BlinnPhongSphereSampler m_sampler; }; -std::mt19937 BlinnPhongMaterialModel::m_randomEngine = std::mt19937( std::time( nullptr ) ); - } // namespace Material } // namespace Core } // namespace Ra diff --git a/src/Core/Material/SimpleMaterialModel.cpp b/src/Core/Material/SimpleMaterialModel.cpp index bf7c55a3c83..c23088dc9bf 100644 --- a/src/Core/Material/SimpleMaterialModel.cpp +++ b/src/Core/Material/SimpleMaterialModel.cpp @@ -1,10 +1,8 @@ #include +#include #include -#include -#include #include -#include "SimpleMaterialModel.hpp" namespace Ra { namespace Core { @@ -68,8 +66,8 @@ LambertianMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector2 u ) { Math::coordinateSystem( normal, &tangent, &bitangent ); // sample point on hemisphere with cosine-weighted distribution - Random::MersenneTwisterGenerator generator = Random::MersenneTwisterGenerator(); - std::pair smpl = Random::CosineWeightedSphereSampler::getDir(&generator); + Core::Random::MersenneTwisterGenerator generator = Core::Random::MersenneTwisterGenerator(); + std::pair smpl = m_sampler.getDir(&generator); // transform sampled point from local to world coodinate system Vector3 wi( smpl.first.dot( tangent ), smpl.first.dot( bitangent ), smpl.first.dot( normal ) ); diff --git a/src/Core/Material/SimpleMaterialModel.hpp b/src/Core/Material/SimpleMaterialModel.hpp index acb91a49507..0445df4b151 100644 --- a/src/Core/Material/SimpleMaterialModel.hpp +++ b/src/Core/Material/SimpleMaterialModel.hpp @@ -2,6 +2,7 @@ #include #include +#include namespace Ra { namespace Core { @@ -42,7 +43,7 @@ class RA_CORE_API SimpleMaterialModel : public MaterialModel class RA_CORE_API LambertianMaterialModel : public SimpleMaterialModel { public: - explicit LambertianMaterialModel( const std::string& name = "" ) : + explicit LambertianMaterialModel( const std::string& name = "" ) : m_sampler(Core::Random::CosineWeightedSphereSampler()), SimpleMaterialModel( name, "Lambertian" ) {} ~LambertianMaterialModel() override = default; @@ -60,6 +61,8 @@ class RA_CORE_API LambertianMaterialModel : public SimpleMaterialModel /// DATA MEMBERS std::string m_texNormal; bool m_hasTexNormal { false }; + + Core::Random::CosineWeightedSphereSampler m_sampler; }; } // namespace Material diff --git a/src/Core/Random/BlinnPhongSphereSampler.cpp b/src/Core/Random/BlinnPhongSphereSampler.cpp index 97d8e256c32..b0d633de981 100644 --- a/src/Core/Random/BlinnPhongSphereSampler.cpp +++ b/src/Core/Random/BlinnPhongSphereSampler.cpp @@ -1,5 +1,9 @@ #include "BlinnPhongSphereSampler.hpp" +namespace Ra { +namespace Core { +namespace Random { + std::pair Ra::Core::Random::BlinnPhongSphereSampler::getPoint( UniformGenerator* generator, Scalar roughness ) { return {{std::pow( u[0], 1_ra / ( roughness + 2 ) ), 2 * Math::Pi * u[1]}, ( roughness + 2 ) * std::pow( u[0], roughness ) / 2 * Math::Pi}; @@ -20,3 +24,7 @@ Ra::Core::Random::BlinnPhongSphereSampler::getDir( UniformGenerator* generator, return { dir, ( roughness + 2 ) * std::pow( u[0], roughness ) / 2 * Math::Pi }; } + +} // namespace Random +} // namespace Core +} // namespace Ra \ No newline at end of file diff --git a/src/Core/Random/BlinnPhongSphereSampler.hpp b/src/Core/Random/BlinnPhongSphereSampler.hpp index 9bd7123bf40..c994a11b898 100644 --- a/src/Core/Random/BlinnPhongSphereSampler.hpp +++ b/src/Core/Random/BlinnPhongSphereSampler.hpp @@ -1,17 +1,18 @@ #pragma once -#include +#include namespace Ra { namespace Core { namespace Random { -class RA_CORE_API BlinnPhongSphereSampler : public SphereSampler { - BlinnPhongSphereSampler(); - ~BlinnPhongSphereSampler(); +class RA_CORE_API BlinnPhongSphereSampler : public CosineWeightedSphereSampler { + public: + BlinnPhongSphereSampler() {}; + ~BlinnPhongSphereSampler() {}; - static std::pair getPoint( UniformGenerator* generator, Scalar roughness ) override; - static std::pair getDir( UniformGenerator* generator, Scalar roughness ) override; + std::pair getPoint( UniformGenerator* generator, Scalar roughness ); + std::pair getDir( UniformGenerator* generator, Scalar roughness ); }; } // namespace Random diff --git a/src/Core/Random/CosineWeightedSphereSampler.cpp b/src/Core/Random/CosineWeightedSphereSampler.cpp index ca8d7dcf6e0..a15352074a4 100644 --- a/src/Core/Random/CosineWeightedSphereSampler.cpp +++ b/src/Core/Random/CosineWeightedSphereSampler.cpp @@ -1,5 +1,9 @@ #include "CosineWeightedSphereSampler.hpp" +namespace Ra { +namespace Core { +namespace Random { + std::pair Ra::Core::Random::CosineWeightedSphereSampler::getPoint( UniformGenerator* generator ) { Vector2 u = generator->get2D(); return {{std::sqrt( u[0] ), 2 * Math::Pi * u[1]}, u[0] / Math::Pi}; @@ -18,4 +22,8 @@ std::pair Ra::Core::Random::CosineWeightedSphereSampler::getDir dir[2] = cosTheta; return {dir, u[0] / Math::Pi}; -} \ No newline at end of file +} + +} // namespace Random +} // namespace Core +} // namespace Ra \ No newline at end of file diff --git a/src/Core/Random/CosineWeightedSphereSampler.hpp b/src/Core/Random/CosineWeightedSphereSampler.hpp index 3758c5f5e59..d3ae7d79c6c 100644 --- a/src/Core/Random/CosineWeightedSphereSampler.hpp +++ b/src/Core/Random/CosineWeightedSphereSampler.hpp @@ -7,11 +7,12 @@ namespace Core { namespace Random { class RA_CORE_API CosineWeightedSphereSampler : public SphereSampler { - CosineWeightedSphereSampler(); - ~CosineWeightedSphereSampler(); + public: + CosineWeightedSphereSampler() {}; + ~CosineWeightedSphereSampler() {}; - static std::pair getPoint( UniformGenerator* generator ) override; - static std::pair getDir( UniformGenerator* generator ) override; + std::pair getPoint( UniformGenerator* generator ) override; + std::pair getDir( UniformGenerator* generator ) override; }; } // namespace Random diff --git a/src/Core/Random/ImportanceSampler.hpp b/src/Core/Random/ImportanceSampler.hpp index 967501ea245..ce1e9039af2 100644 --- a/src/Core/Random/ImportanceSampler.hpp +++ b/src/Core/Random/ImportanceSampler.hpp @@ -7,8 +7,9 @@ namespace Core { namespace Random { class RA_CORE_API ImportanceSampler { - virtual ImportanceSampler() = 0; - virtual ~ImportanceSampler() = 0; + public: + ImportanceSampler() {}; + ~ImportanceSampler() {}; }; } // namespace Random diff --git a/src/Core/Random/MersenneTwisterGenerator.cpp b/src/Core/Random/MersenneTwisterGenerator.cpp index d7bdaf71295..ca85b4aec7b 100644 --- a/src/Core/Random/MersenneTwisterGenerator.cpp +++ b/src/Core/Random/MersenneTwisterGenerator.cpp @@ -1,9 +1,19 @@ #include "MersenneTwisterGenerator.hpp" +namespace Ra { +namespace Core { +namespace Random { + Ra::Core::Random::MersenneTwisterGenerator::UniformGenerator() {} +MersenneTwisterGenerator::MersenneTwisterGenerator() : m_randomEngine( std::mt19937( std::time( nullptr ) ) ) {} + Ra::Core::Random::MersenneTwisterGenerator::~MersenneTwisterGenerator() {} Scalar Ra::Core::Random::MersenneTwisterGenerator::get1D() { return m_unifDistributionRand( m_randomEngine ); -} \ No newline at end of file +} + +} // namespace Random +} // namespace Core +} // namespace Ra \ No newline at end of file diff --git a/src/Core/Random/MersenneTwisterGenerator.hpp b/src/Core/Random/MersenneTwisterGenerator.hpp index ea2351c0bfc..dd462e9fe75 100644 --- a/src/Core/Random/MersenneTwisterGenerator.hpp +++ b/src/Core/Random/MersenneTwisterGenerator.hpp @@ -9,16 +9,15 @@ namespace Core { namespace Random { class RA_CORE_API MersenneTwisterGenerator : public UniformGenerator { + public: MersenneTwisterGenerator(); ~MersenneTwisterGenerator(); Scalar get1D() override; - static std::mt19937 m_randomEngine = std::mt19937( std::time( nullptr ) ); + std::mt19937 m_randomEngine; }; -std::mt19937 MersenneTwisterGenerator::m_randomEngine = std::mt19937( std::time( nullptr ) ); - } // namespace Random } // namespace Core } // namespace Ra \ No newline at end of file diff --git a/src/Core/Random/SphereSampler.hpp b/src/Core/Random/SphereSampler.hpp index 28e81796ae1..a099b3ea7c7 100644 --- a/src/Core/Random/SphereSampler.hpp +++ b/src/Core/Random/SphereSampler.hpp @@ -7,14 +7,15 @@ namespace Core { namespace Random { class RA_CORE_API SphereSampler : public ImportanceSampler { - virtual SphereSampler() = 0; - virtual ~SphereSampler() = 0; + public: + SphereSampler() {}; + ~SphereSampler() {}; - virtual Vector2 getPoint( UniformGenerator* generator ) = 0; - virtual Vector3 getDir( UniformGenerator* generator ) = 0; + virtual std::pair getPoint( UniformGenerator* generator ) = 0; + virtual std::pair getDir( UniformGenerator* generator ) = 0; - virtual Scalar pdf( Vector3 dir ) = 0; - virtual Scalar pdf( Vector2 point ) = 0; + // virtual Scalar pdf( Vector3 dir ) = 0; + // virtual Scalar pdf( Vector2 point ) = 0; }; } // namespace Random diff --git a/src/Core/Random/UniformGenerator.cpp b/src/Core/Random/UniformGenerator.cpp index c3daa0483c2..c40f4c87804 100644 --- a/src/Core/Random/UniformGenerator.cpp +++ b/src/Core/Random/UniformGenerator.cpp @@ -1,5 +1,9 @@ #include "UniformGenerator.hpp" +namespace Ra { +namespace Core { +namespace Random { + Vector2 Ra::Core::Random::UniformGenerator::get2D() { return {get1D(), get1D()}; } @@ -17,3 +21,7 @@ VectorN Ra::Core::Random::UniformGenerator::getXD( int dim ) { return result; } + +} // namespace Random +} // namespace Core +} // namespace Ra diff --git a/src/Core/Random/UniformGenerator.hpp b/src/Core/Random/UniformGenerator.hpp index 33caa3b5103..c62d26e2637 100644 --- a/src/Core/Random/UniformGenerator.hpp +++ b/src/Core/Random/UniformGenerator.hpp @@ -9,8 +9,9 @@ namespace Core { namespace Random { class RA_CORE_API UniformGenerator { - virtual UniformGenerator() = 0; - virtual ~UniformGenerator() = 0; + public: + UniformGenerator() {}; + ~UniformGenerator() {}; virtual Scalar get1D() = 0; diff --git a/src/Core/Random/UniformSphereSampler.cpp b/src/Core/Random/UniformSphereSampler.cpp index 1cd16114491..8066c79df83 100644 --- a/src/Core/Random/UniformSphereSampler.cpp +++ b/src/Core/Random/UniformSphereSampler.cpp @@ -1,5 +1,9 @@ #include "UniformSphereSampler.hpp" +namespace Ra { +namespace Core { +namespace Random { + std::pair Ra::Core::Random::UniformSphereSampler::getPoint( UniformGenerator* generator ) { Vector2 u = generator->get2D(); return {{u[0], 2 * Math::Pi * u[1]}, 1 / 2 * Math::Pi}; @@ -18,4 +22,8 @@ std::pair Ra::Core::Random::UniformSphereSampler::getDir( Unifo dir[2] = cosTheta; return {dir, 1 / 2 * Math::Pi}; -} \ No newline at end of file +} + +} // namespace Random +} // namespace Core +} // namespace Ra \ No newline at end of file diff --git a/src/Core/Random/UniformSphereSampler.hpp b/src/Core/Random/UniformSphereSampler.hpp index de07873c117..198443cb8fc 100644 --- a/src/Core/Random/UniformSphereSampler.hpp +++ b/src/Core/Random/UniformSphereSampler.hpp @@ -7,11 +7,12 @@ namespace Core { namespace Random { class RA_CORE_API UniformSphereSampler : public SphereSampler { - UniformSphereSampler(); - ~UniformSphereSampler(); + public: + UniformSphereSampler() {}; + ~UniformSphereSampler() {}; - static std::pair getPoint( UniformGenerator* generator ) override; - static std::pair getDir( UniformGenerator* generator ) override; + std::pair getPoint( UniformGenerator* generator ) override; + std::pair getDir( UniformGenerator* generator ) override; }; } // namespace Random From 937a575c55eb6ffd769e78de4784f25803f22e8e Mon Sep 17 00:00:00 2001 From: grandch Date: Thu, 29 Jun 2023 15:35:12 +0200 Subject: [PATCH 15/56] add pdf methods --- src/Core/Material/BlinnPhongMaterialModel.cpp | 4 +- src/Core/Material/SimpleMaterialModel.cpp | 2 +- src/Core/Random/BlinnPhongSphereSampler.cpp | 14 ++- src/Core/Random/BlinnPhongSphereSampler.hpp | 3 + .../Random/CosineWeightedSphereSampler.cpp | 13 ++- .../Random/CosineWeightedSphereSampler.hpp | 3 + src/Core/Random/MersenneTwisterGenerator.cpp | 4 +- src/Core/Random/SphereSampler.hpp | 4 +- src/Core/Random/UniformGenerator.cpp | 6 +- src/Core/Random/UniformSphereSampler.cpp | 12 +- src/Core/Random/UniformSphereSampler.hpp | 3 + src/Core/filelist.cmake | 15 ++- src/Engine/filelist.cmake | 3 +- src/Gui/filelist.cmake | 16 ++- src/Headless/filelist.cmake | 10 +- src/IO/filelist.cmake | 108 ++++++++++-------- src/PluginBase/filelist.cmake | 18 ++- 17 files changed, 165 insertions(+), 73 deletions(-) diff --git a/src/Core/Material/BlinnPhongMaterialModel.cpp b/src/Core/Material/BlinnPhongMaterialModel.cpp index b14834677ce..20f385a76ee 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.cpp +++ b/src/Core/Material/BlinnPhongMaterialModel.cpp @@ -93,8 +93,8 @@ Scalar BlinnPhongMaterialModel::PDF( Vector3 inDir, Vector3 outDir, Vector3 norm dIntensity /= diffSpecNorm; sIntensity /= diffSpecNorm; - return std::clamp( dIntensity * Math::cosineWeightedPDF( outDir, normal ) + - sIntensity * Math::specularPDF( outDir, normal, getRoughness() ), + return std::clamp( dIntensity * m_sampler.CosineWeightedSphereSampler::pdf( outDir, normal ) + + sIntensity * m_sampler.pdf( outDir, normal, getRoughness() ), 0_ra, 1_ra ); } diff --git a/src/Core/Material/SimpleMaterialModel.cpp b/src/Core/Material/SimpleMaterialModel.cpp index c23088dc9bf..fe9200e1d58 100644 --- a/src/Core/Material/SimpleMaterialModel.cpp +++ b/src/Core/Material/SimpleMaterialModel.cpp @@ -77,7 +77,7 @@ LambertianMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector2 u ) { } Scalar LambertianMaterialModel::PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) { - return Math::cosineWeightedPDF( outDir, normal ); + return m_sampler.pdf(outDir, normal); } } // namespace Material diff --git a/src/Core/Random/BlinnPhongSphereSampler.cpp b/src/Core/Random/BlinnPhongSphereSampler.cpp index b0d633de981..5cea1478107 100644 --- a/src/Core/Random/BlinnPhongSphereSampler.cpp +++ b/src/Core/Random/BlinnPhongSphereSampler.cpp @@ -1,4 +1,6 @@ -#include "BlinnPhongSphereSampler.hpp" +#include + +#include namespace Ra { namespace Core { @@ -6,6 +8,7 @@ namespace Random { std::pair Ra::Core::Random::BlinnPhongSphereSampler::getPoint( UniformGenerator* generator, Scalar roughness ) { + Vector2 u = generator->get2D(); return {{std::pow( u[0], 1_ra / ( roughness + 2 ) ), 2 * Math::Pi * u[1]}, ( roughness + 2 ) * std::pow( u[0], roughness ) / 2 * Math::Pi}; } @@ -25,6 +28,15 @@ Ra::Core::Random::BlinnPhongSphereSampler::getDir( UniformGenerator* generator, return { dir, ( roughness + 2 ) * std::pow( u[0], roughness ) / 2 * Math::Pi }; } +Scalar BlinnPhongSphereSampler::pdf( Vector3 dir, Vector3 normal, Scalar roughness ) { + dir.normalize(); + return ( roughness + 2 ) * std::pow( dir.dot(normal), roughness ) / 2 * Math::Pi; +} + +Scalar BlinnPhongSphereSampler::pdf( Vector2 point, Scalar roughness ) { + return ( roughness + 2 ) * std::pow( point[0], roughness ) / 2 * Math::Pi; +} + } // namespace Random } // namespace Core } // namespace Ra \ No newline at end of file diff --git a/src/Core/Random/BlinnPhongSphereSampler.hpp b/src/Core/Random/BlinnPhongSphereSampler.hpp index c994a11b898..be6aa93269a 100644 --- a/src/Core/Random/BlinnPhongSphereSampler.hpp +++ b/src/Core/Random/BlinnPhongSphereSampler.hpp @@ -13,6 +13,9 @@ class RA_CORE_API BlinnPhongSphereSampler : public CosineWeightedSphereSampler { std::pair getPoint( UniformGenerator* generator, Scalar roughness ); std::pair getDir( UniformGenerator* generator, Scalar roughness ); + + Scalar pdf( Vector3 dir, Vector3 normal, Scalar roughness ); + Scalar pdf( Vector2 point, Scalar roughness ); }; } // namespace Random diff --git a/src/Core/Random/CosineWeightedSphereSampler.cpp b/src/Core/Random/CosineWeightedSphereSampler.cpp index a15352074a4..2456e7aa75a 100644 --- a/src/Core/Random/CosineWeightedSphereSampler.cpp +++ b/src/Core/Random/CosineWeightedSphereSampler.cpp @@ -1,4 +1,6 @@ -#include "CosineWeightedSphereSampler.hpp" +#include + +#include namespace Ra { namespace Core { @@ -24,6 +26,15 @@ std::pair Ra::Core::Random::CosineWeightedSphereSampler::getDir return {dir, u[0] / Math::Pi}; } +Scalar CosineWeightedSphereSampler::pdf( Vector3 dir, Vector3 normal ) { + dir.normalize(); + return dir.dot( normal ) / Math::Pi; +} + +Scalar CosineWeightedSphereSampler::pdf( Vector2 point ) { + return point[0] / Math::Pi; +} + } // namespace Random } // namespace Core } // namespace Ra \ No newline at end of file diff --git a/src/Core/Random/CosineWeightedSphereSampler.hpp b/src/Core/Random/CosineWeightedSphereSampler.hpp index d3ae7d79c6c..302c1c617da 100644 --- a/src/Core/Random/CosineWeightedSphereSampler.hpp +++ b/src/Core/Random/CosineWeightedSphereSampler.hpp @@ -13,6 +13,9 @@ class RA_CORE_API CosineWeightedSphereSampler : public SphereSampler { std::pair getPoint( UniformGenerator* generator ) override; std::pair getDir( UniformGenerator* generator ) override; + + Scalar pdf( Vector3 dir, Vector3 normal ) override; + Scalar pdf( Vector2 point ) override; }; } // namespace Random diff --git a/src/Core/Random/MersenneTwisterGenerator.cpp b/src/Core/Random/MersenneTwisterGenerator.cpp index ca85b4aec7b..59daa02b3a9 100644 --- a/src/Core/Random/MersenneTwisterGenerator.cpp +++ b/src/Core/Random/MersenneTwisterGenerator.cpp @@ -1,11 +1,9 @@ -#include "MersenneTwisterGenerator.hpp" +#include namespace Ra { namespace Core { namespace Random { -Ra::Core::Random::MersenneTwisterGenerator::UniformGenerator() {} - MersenneTwisterGenerator::MersenneTwisterGenerator() : m_randomEngine( std::mt19937( std::time( nullptr ) ) ) {} Ra::Core::Random::MersenneTwisterGenerator::~MersenneTwisterGenerator() {} diff --git a/src/Core/Random/SphereSampler.hpp b/src/Core/Random/SphereSampler.hpp index a099b3ea7c7..cc04a320bcc 100644 --- a/src/Core/Random/SphereSampler.hpp +++ b/src/Core/Random/SphereSampler.hpp @@ -14,8 +14,8 @@ class RA_CORE_API SphereSampler : public ImportanceSampler { virtual std::pair getPoint( UniformGenerator* generator ) = 0; virtual std::pair getDir( UniformGenerator* generator ) = 0; - // virtual Scalar pdf( Vector3 dir ) = 0; - // virtual Scalar pdf( Vector2 point ) = 0; + virtual Scalar pdf( Vector3 dir, Vector3 normal ) = 0; + virtual Scalar pdf( Vector2 point ) = 0; }; } // namespace Random diff --git a/src/Core/Random/UniformGenerator.cpp b/src/Core/Random/UniformGenerator.cpp index c40f4c87804..23f2a20ec6a 100644 --- a/src/Core/Random/UniformGenerator.cpp +++ b/src/Core/Random/UniformGenerator.cpp @@ -1,4 +1,4 @@ -#include "UniformGenerator.hpp" +#include namespace Ra { namespace Core { @@ -13,7 +13,9 @@ Vector3 Ra::Core::Random::UniformGenerator::get3D() { } VectorN Ra::Core::Random::UniformGenerator::getXD( int dim ) { - Eigen::Matrix; result; + VectorN result; + + result.resize(dim, 1); for(int i = 0; i < dim; i++) { result[i] = get1D(); diff --git a/src/Core/Random/UniformSphereSampler.cpp b/src/Core/Random/UniformSphereSampler.cpp index 8066c79df83..2ee41296c9d 100644 --- a/src/Core/Random/UniformSphereSampler.cpp +++ b/src/Core/Random/UniformSphereSampler.cpp @@ -1,4 +1,6 @@ -#include "UniformSphereSampler.hpp" +#include + +#include namespace Ra { namespace Core { @@ -24,6 +26,14 @@ std::pair Ra::Core::Random::UniformSphereSampler::getDir( Unifo return {dir, 1 / 2 * Math::Pi}; } +Scalar UniformSphereSampler::pdf( Vector3 dir, Vector3 normal ) { + return 1 / 2 * Math::Pi; +} + +Scalar UniformSphereSampler::pdf( Vector2 point ) { + return 1 / 2 * Math::Pi; +} + } // namespace Random } // namespace Core } // namespace Ra \ No newline at end of file diff --git a/src/Core/Random/UniformSphereSampler.hpp b/src/Core/Random/UniformSphereSampler.hpp index 198443cb8fc..e10a87df916 100644 --- a/src/Core/Random/UniformSphereSampler.hpp +++ b/src/Core/Random/UniformSphereSampler.hpp @@ -13,6 +13,9 @@ class RA_CORE_API UniformSphereSampler : public SphereSampler { std::pair getPoint( UniformGenerator* generator ) override; std::pair getDir( UniformGenerator* generator ) override; + + Scalar pdf( Vector3 dir, Vector3 normal ) override; + Scalar pdf( Vector2 point ) override; }; } // namespace Random diff --git a/src/Core/filelist.cmake b/src/Core/filelist.cmake index 101f98962d4..afb5b9d9af9 100644 --- a/src/Core/filelist.cmake +++ b/src/Core/filelist.cmake @@ -1,6 +1,6 @@ # ---------------------------------------------------- # This file can be generated from a script: -# To do so, run "./generateFilelistForModule.sh Core" +# To do so, run "./generateFilelistForModule.sh Core" # from ./scripts directory # ---------------------------------------------------- @@ -36,6 +36,11 @@ set(core_sources Material/BlinnPhongMaterialModel.cpp Material/MaterialModel.cpp Material/SimpleMaterialModel.cpp + Random/BlinnPhongSphereSampler.cpp + Random/CosineWeightedSphereSampler.cpp + Random/MersenneTwisterGenerator.cpp + Random/UniformGenerator.cpp + Random/UniformSphereSampler.cpp Resources/Resources.cpp Tasks/TaskQueue.cpp Utils/Attribs.cpp @@ -110,6 +115,13 @@ set(core_headers Math/Math.hpp Math/Quadric.hpp RaCore.hpp + Random/BlinnPhongSphereSampler.hpp + Random/CosineWeightedSphereSampler.hpp + Random/ImportanceSampler.hpp + Random/MersenneTwisterGenerator.hpp + Random/SphereSampler.hpp + Random/UniformGenerator.hpp + Random/UniformSphereSampler.hpp Resources/Resources.hpp Tasks/Task.hpp Tasks/TaskQueue.hpp @@ -139,3 +151,4 @@ set(core_headers Utils/TypesUtils.hpp Utils/Version.hpp ) + diff --git a/src/Engine/filelist.cmake b/src/Engine/filelist.cmake index 274f82178ba..5e11269aafc 100644 --- a/src/Engine/filelist.cmake +++ b/src/Engine/filelist.cmake @@ -1,6 +1,6 @@ # ---------------------------------------------------- # This file can be generated from a script: -# To do so, run "./generateFilelistForModule.sh Engine" +# To do so, run "./generateFilelistForModule.sh Engine" # from ./scripts directory # ---------------------------------------------------- @@ -116,6 +116,7 @@ set(engine_headers Scene/SystemDisplay.hpp ) + set(engine_shaders 2DShaders/Basic2D.vert.glsl 2DShaders/CircleBrush.frag.glsl diff --git a/src/Gui/filelist.cmake b/src/Gui/filelist.cmake index c312cf504fd..92f257238d0 100644 --- a/src/Gui/filelist.cmake +++ b/src/Gui/filelist.cmake @@ -1,6 +1,6 @@ # ---------------------------------------------------- # This file can be generated from a script: -# To do so, run "./generateFilelistForModule.sh Gui" +# To do so, run "./generateFilelistForModule.sh Gui" # from ./scripts directory # ---------------------------------------------------- @@ -87,10 +87,16 @@ set(gui_headers ) set(gui_uis - AboutDialog/AboutDialog.ui AboutDialog/RadiumHelpDialog.ui - SkeletonBasedAnimation/SkeletonBasedAnimationUI.ui Timeline/HelpDialog.ui Timeline/Timeline.ui + AboutDialog/AboutDialog.ui + AboutDialog/RadiumHelpDialog.ui + SkeletonBasedAnimation/SkeletonBasedAnimationUI.ui + Timeline/HelpDialog.ui + Timeline/Timeline.ui ) -set(gui_resources QtResources/RadiumQtResources.qrc - SkeletonBasedAnimation/SkeletonBasedAnimation.qrc Timeline/timeline.qrc +set(gui_resources + QtResources/RadiumQtResources.qrc + SkeletonBasedAnimation/SkeletonBasedAnimation.qrc + Timeline/timeline.qrc ) + diff --git a/src/Headless/filelist.cmake b/src/Headless/filelist.cmake index cc4128b6bd9..9d9276f8aa4 100644 --- a/src/Headless/filelist.cmake +++ b/src/Headless/filelist.cmake @@ -1,11 +1,14 @@ # ---------------------------------------------------- # This file can be generated from a script: -# To do so, run "./generateFilelistForModule.sh Headless" +# To do so, run "./generateFilelistForModule.sh Headless" # from ./scripts directory # ---------------------------------------------------- -set(headless_sources CLIBaseApplication.cpp CLIViewer.cpp OpenGLContext/EglOpenGLContext.cpp - OpenGLContext/GlfwOpenGLContext.cpp +set(headless_sources + CLIBaseApplication.cpp + CLIViewer.cpp + OpenGLContext/EglOpenGLContext.cpp + OpenGLContext/GlfwOpenGLContext.cpp ) set(headless_headers @@ -31,3 +34,4 @@ set(headless_headers OpenGLContext/OpenGLContext.hpp RaHeadless.hpp ) + diff --git a/src/IO/filelist.cmake b/src/IO/filelist.cmake index 5ab4a4083d2..cb254c06e27 100644 --- a/src/IO/filelist.cmake +++ b/src/IO/filelist.cmake @@ -1,58 +1,74 @@ # ---------------------------------------------------- # This file can be generated from a script: -# To do so, run "./generateFilelistForModule.sh IO" +# To do so, run "./generateFilelistForModule.sh IO" # from ./scripts directory # ---------------------------------------------------- -set(io_sources CameraLoader/CameraLoader.cpp) +set(io_sources + CameraLoader/CameraLoader.cpp +) -set(io_headers CameraLoader/CameraLoader.hpp RaIO.hpp) +set(io_headers + CameraLoader/CameraLoader.hpp + RaIO.hpp +) if(RADIUM_IO_DEPRECATED) - list(APPEND io_sources deprecated/OBJFileManager.cpp deprecated/OFFFileManager.cpp) +list(APPEND io_sources + deprecated/OBJFileManager.cpp + deprecated/OFFFileManager.cpp +) - list(APPEND io_headers deprecated/FileManager.hpp deprecated/OBJFileManager.hpp - deprecated/OFFFileManager.hpp - ) +list(APPEND io_headers + deprecated/FileManager.hpp + deprecated/OBJFileManager.hpp + deprecated/OFFFileManager.hpp +) endif(RADIUM_IO_DEPRECATED) -if(RADIUM_IO_ASSIMP) - list( - APPEND - io_sources - AssimpLoader/AssimpAnimationDataLoader.cpp - AssimpLoader/AssimpCameraDataLoader.cpp - AssimpLoader/AssimpFileLoader.cpp - AssimpLoader/AssimpGeometryDataLoader.cpp - AssimpLoader/AssimpHandleDataLoader.cpp - AssimpLoader/AssimpLightDataLoader.cpp - ) - - list( - APPEND - io_headers - AssimpLoader/AssimpAnimationDataLoader.hpp - AssimpLoader/AssimpCameraDataLoader.hpp - AssimpLoader/AssimpFileLoader.hpp - AssimpLoader/AssimpGeometryDataLoader.hpp - AssimpLoader/AssimpHandleDataLoader.hpp - AssimpLoader/AssimpLightDataLoader.hpp - AssimpLoader/AssimpWrapper.hpp - ) - -endif(RADIUM_IO_ASSIMP) - -if(RADIUM_IO_TINYPLY) - list(APPEND io_sources TinyPlyLoader/TinyPlyFileLoader.cpp) - - list(APPEND io_headers TinyPlyLoader/TinyPlyFileLoader.hpp) - -endif(RADIUM_IO_TINYPLY) - -if(RADIUM_IO_VOLUMES) - list(APPEND io_sources VolumesLoader/VolumeLoader.cpp VolumesLoader/pvmutils.cpp) - - list(APPEND io_headers VolumesLoader/VolumeLoader.hpp VolumesLoader/pvmutils.hpp) - -endif(RADIUM_IO_VOLUMES) +if( RADIUM_IO_ASSIMP ) +list(APPEND io_sources + AssimpLoader/AssimpAnimationDataLoader.cpp + AssimpLoader/AssimpCameraDataLoader.cpp + AssimpLoader/AssimpFileLoader.cpp + AssimpLoader/AssimpGeometryDataLoader.cpp + AssimpLoader/AssimpHandleDataLoader.cpp + AssimpLoader/AssimpLightDataLoader.cpp +) + +list(APPEND io_headers + AssimpLoader/AssimpAnimationDataLoader.hpp + AssimpLoader/AssimpCameraDataLoader.hpp + AssimpLoader/AssimpFileLoader.hpp + AssimpLoader/AssimpGeometryDataLoader.hpp + AssimpLoader/AssimpHandleDataLoader.hpp + AssimpLoader/AssimpLightDataLoader.hpp + AssimpLoader/AssimpWrapper.hpp +) + +endif( RADIUM_IO_ASSIMP ) + +if( RADIUM_IO_TINYPLY ) +list(APPEND io_sources + TinyPlyLoader/TinyPlyFileLoader.cpp +) + +list(APPEND io_headers + TinyPlyLoader/TinyPlyFileLoader.hpp +) + +endif( RADIUM_IO_TINYPLY ) + +if( RADIUM_IO_VOLUMES ) +list(APPEND io_sources + VolumesLoader/VolumeLoader.cpp + VolumesLoader/pvmutils.cpp +) + +list(APPEND io_headers + VolumesLoader/VolumeLoader.hpp + VolumesLoader/pvmutils.hpp +) + +endif( RADIUM_IO_VOLUMES ) diff --git a/src/PluginBase/filelist.cmake b/src/PluginBase/filelist.cmake index e569f6b70f1..7e38da14a88 100644 --- a/src/PluginBase/filelist.cmake +++ b/src/PluginBase/filelist.cmake @@ -1,11 +1,21 @@ # ---------------------------------------------------- # This file can be generated from a script: -# To do so, run "./generateFilelistForModule.sh PluginBase" +# To do so, run "./generateFilelistForModule.sh PluginBase" # from ./scripts directory # ---------------------------------------------------- -set(pluginbase_sources RadiumPluginInterface.cpp) +set(pluginbase_sources + RadiumPluginInterface.cpp +) -set(pluginbase_headers PluginContext.hpp RaPluginBase.hpp RadiumPluginInterface.hpp) +set(pluginbase_headers + PluginContext.hpp + RaPluginBase.hpp + RadiumPluginInterface.hpp +) + +set(pluginbase_json + pluginMetaDataDebug.json + pluginMetaDataRelease.json +) -set(pluginbase_json pluginMetaDataDebug.json pluginMetaDataRelease.json) From f3773113f33a0c1af4b733f0f2e4f4b73c31bec8 Mon Sep 17 00:00:00 2001 From: grandch Date: Thu, 29 Jun 2023 15:49:18 +0200 Subject: [PATCH 16/56] add local frame to sample parameters --- src/Core/Material/BlinnPhongMaterialModel.cpp | 6 ++---- src/Core/Material/BlinnPhongMaterialModel.hpp | 2 +- src/Core/Material/MaterialModel.hpp | 2 +- src/Core/Material/SimpleMaterialModel.cpp | 8 ++------ src/Core/Material/SimpleMaterialModel.hpp | 4 ++-- 5 files changed, 8 insertions(+), 14 deletions(-) diff --git a/src/Core/Material/BlinnPhongMaterialModel.cpp b/src/Core/Material/BlinnPhongMaterialModel.cpp index 20f385a76ee..6f00ca35ece 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.cpp +++ b/src/Core/Material/BlinnPhongMaterialModel.cpp @@ -46,10 +46,8 @@ Utils::Color Material::BlinnPhongMaterialModel::evalBSDF( Vector3 w_i, } std::optional> -BlinnPhongMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector2 u ) { - Vector3 halfway, tangent, bitangent; - - Math::coordinateSystem( normal, &tangent, &bitangent ); +BlinnPhongMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent, Vector2 u ) { + Vector3 halfway; Vector3 rgbToLuminance { 0.2126_ra, 0.7152_ra, 0.0722_ra }; Scalar dIntensity = m_kd.rgb().dot( rgbToLuminance ); diff --git a/src/Core/Material/BlinnPhongMaterialModel.hpp b/src/Core/Material/BlinnPhongMaterialModel.hpp index 00188572e9f..d9b3fc7f4fb 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.hpp +++ b/src/Core/Material/BlinnPhongMaterialModel.hpp @@ -35,7 +35,7 @@ class RA_CORE_API BlinnPhongMaterialModel : public MaterialModel Utils::Color evalBSDF( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) override; std::optional> - sample( Vector3 inDir, Vector3 normal, Vector2 u ) override; + sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent, Vector2 u ) override; Scalar PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) override; Scalar getRoughness(); diff --git a/src/Core/Material/MaterialModel.hpp b/src/Core/Material/MaterialModel.hpp index 0f0a8f79b4c..62b1548f095 100644 --- a/src/Core/Material/MaterialModel.hpp +++ b/src/Core/Material/MaterialModel.hpp @@ -41,7 +41,7 @@ class RA_CORE_API MaterialModel : public Utils::ObservableVoid */ virtual Utils::Color evalBSDF( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) = 0; virtual std::optional> - sample( Vector3 inDir, Vector3 normal, Vector2 u ) = 0; + sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent, Vector2 u ) = 0; virtual Scalar PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) = 0; private: diff --git a/src/Core/Material/SimpleMaterialModel.cpp b/src/Core/Material/SimpleMaterialModel.cpp index fe9200e1d58..50619c1a623 100644 --- a/src/Core/Material/SimpleMaterialModel.cpp +++ b/src/Core/Material/SimpleMaterialModel.cpp @@ -27,7 +27,7 @@ Utils::Color SimpleMaterialModel::evalBSDF( Vector3 w_i, Vector3 w_o, Vector3 no return m_kd; } std::optional> -SimpleMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector2 u ) { +SimpleMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent, Vector2 u ) { return {}; } Scalar SimpleMaterialModel::PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) { @@ -60,11 +60,7 @@ Utils::Color Material::LambertianMaterialModel::evalBSDF( Vector3 w_i, } std::optional> -LambertianMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector2 u ) { - // create local to normal coordinate system - Vector3 tangent, bitangent; - Math::coordinateSystem( normal, &tangent, &bitangent ); - +LambertianMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent, Vector2 u ) { // sample point on hemisphere with cosine-weighted distribution Core::Random::MersenneTwisterGenerator generator = Core::Random::MersenneTwisterGenerator(); std::pair smpl = m_sampler.getDir(&generator); diff --git a/src/Core/Material/SimpleMaterialModel.hpp b/src/Core/Material/SimpleMaterialModel.hpp index 0445df4b151..8a5e2a988dd 100644 --- a/src/Core/Material/SimpleMaterialModel.hpp +++ b/src/Core/Material/SimpleMaterialModel.hpp @@ -28,7 +28,7 @@ class RA_CORE_API SimpleMaterialModel : public MaterialModel Utils::Color evalBSDF( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) override; std::optional> - sample( Vector3 inDir, Vector3 normal, Vector2 u ) override; + sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent, Vector2 u ) override; Scalar PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) override; /// DATA MEMBERS @@ -55,7 +55,7 @@ class RA_CORE_API LambertianMaterialModel : public SimpleMaterialModel Utils::Color evalBSDF( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) override; std::optional> - sample( Vector3 inDir, Vector3 normal, Vector2 u ) override; + sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent, Vector2 u ) override; Scalar PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) override; /// DATA MEMBERS From 4af867073708c18da62b6597a2f333687e35eb59 Mon Sep 17 00:00:00 2001 From: grandch Date: Thu, 29 Jun 2023 15:51:36 +0200 Subject: [PATCH 17/56] remove sampling, pdf methods in linearalgebra --- src/Core/Math/LinearAlgebra.hpp | 67 --------------------------------- 1 file changed, 67 deletions(-) diff --git a/src/Core/Math/LinearAlgebra.hpp b/src/Core/Math/LinearAlgebra.hpp index 318c1c70ed0..853212b3004 100644 --- a/src/Core/Math/LinearAlgebra.hpp +++ b/src/Core/Math/LinearAlgebra.hpp @@ -123,73 +123,6 @@ inline Matrix4 perspective( Scalar fovy, Scalar aspect, Scalar near, Scalar zfar inline Matrix4 orthographic( Scalar left, Scalar right, Scalar bottom, Scalar top, Scalar near, Scalar zfar ); -inline void coordinateSystem( Vector3 normal, Vector3* tangent, Vector3* bitangent ) { - if ( std::abs( normal[0] ) > std::abs( normal[1] ) ) { - Scalar invLen = 1 / std::sqrt( normal[0] * normal[0] + normal[2] * normal[2] ); - *tangent = Vector3( -normal[2] * invLen, 0, normal[0] * invLen ); - } - else { - Scalar invLen = 1 / std::sqrt( normal[1] * normal[1] + normal[2] * normal[2] ); - *tangent = Vector3( 0, normal[2] * invLen, -normal[1] * invLen ); - } - *bitangent = normal.cross( *tangent ); -} - -inline std::pair sampleHemisphereCosineWeighted( Vector2 u ) { - Vector3 dir; - - Scalar cosTheta = std::sqrt( u[0] ); - Scalar sinTheta = std::sqrt( 1 - u[0] ); - Scalar phi = 2 * Math::Pi * u[1]; - - dir[0] = sinTheta * std::cos( phi ); - dir[1] = sinTheta * std::sin( phi ); - dir[2] = cosTheta; - - return { dir, cosTheta / Math::Pi }; -} - -inline std::pair sampleHemisphere( Vector2 u ) { - Vector3 dir; - - Scalar cosTheta = u[0]; - Scalar sinTheta = 1 - u[0]; - Scalar phi = 2 * Math::Pi * u[1]; - - dir[0] = sinTheta * std::cos( phi ); - dir[1] = sinTheta * std::sin( phi ); - dir[2] = cosTheta; - - return { dir, 1_ra / ( 2_ra * Math::Pi ) }; -} - -inline std::pair sampleSpecular( Vector2 u, Scalar roughness ) { - Vector3 dir; - - Scalar cosTheta = std::pow( u[0], 1_ra / ( roughness + 2 ) ); - Scalar sinTheta = 1 - u[0]; - Scalar phi = 2 * Math::Pi * u[1]; - - dir[0] = sinTheta * std::cos( phi ); - dir[1] = sinTheta * std::sin( phi ); - dir[2] = cosTheta; - - return { dir, ( roughness + 2 ) * std::pow( u[0], roughness ) / 2 * Math::Pi }; -} - -inline Scalar cosineWeightedPDF( Vector3 dir, Vector3 normal ) { - dir.normalize(); - - Scalar cosTheta = dir.dot( normal ); - - return cosTheta / M_PI; -} - -inline Scalar specularPDF( Vector3 dir, Vector3 normal, Scalar roughness ) { - Scalar cosTheta = normal.dot( dir ); - return ( roughness + 2 ) * std::pow( cosTheta, roughness ) / 2 * Math::Pi; -} - // // Quaternion functions // From f0d5661ad1a4d0b602cb7e3243c8157821c6410e Mon Sep 17 00:00:00 2001 From: grandch Date: Mon, 3 Jul 2023 15:13:36 +0200 Subject: [PATCH 18/56] remove ImportanceSampler class --- src/Core/Random/ImportanceSampler.hpp | 17 ----------------- src/Core/filelist.cmake | 1 - 2 files changed, 18 deletions(-) delete mode 100644 src/Core/Random/ImportanceSampler.hpp diff --git a/src/Core/Random/ImportanceSampler.hpp b/src/Core/Random/ImportanceSampler.hpp deleted file mode 100644 index ce1e9039af2..00000000000 --- a/src/Core/Random/ImportanceSampler.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include - -namespace Ra { -namespace Core { -namespace Random { - -class RA_CORE_API ImportanceSampler { - public: - ImportanceSampler() {}; - ~ImportanceSampler() {}; -}; - -} // namespace Random -} // namespace Core -} // namespace Ra \ No newline at end of file diff --git a/src/Core/filelist.cmake b/src/Core/filelist.cmake index afb5b9d9af9..ac15bdadfe3 100644 --- a/src/Core/filelist.cmake +++ b/src/Core/filelist.cmake @@ -117,7 +117,6 @@ set(core_headers RaCore.hpp Random/BlinnPhongSphereSampler.hpp Random/CosineWeightedSphereSampler.hpp - Random/ImportanceSampler.hpp Random/MersenneTwisterGenerator.hpp Random/SphereSampler.hpp Random/UniformGenerator.hpp From a3f48e858e370706691eedc8ee48d22f8ec038c6 Mon Sep 17 00:00:00 2001 From: grandch Date: Mon, 3 Jul 2023 15:16:05 +0200 Subject: [PATCH 19/56] add UniformGenerator as optionnal parameter of material --- src/Core/Material/BlinnPhongMaterialModel.cpp | 16 ++++++----- src/Core/Material/BlinnPhongMaterialModel.hpp | 27 +++++++++---------- src/Core/Material/SimpleMaterialModel.cpp | 20 ++++++++------ src/Core/Material/SimpleMaterialModel.hpp | 24 ++++++++++++++--- src/Core/Random/SphereSampler.hpp | 12 +++++---- src/Core/filelist.cmake | 3 +-- 6 files changed, 63 insertions(+), 39 deletions(-) diff --git a/src/Core/Material/BlinnPhongMaterialModel.cpp b/src/Core/Material/BlinnPhongMaterialModel.cpp index 6f00ca35ece..73edcda9d50 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.cpp +++ b/src/Core/Material/BlinnPhongMaterialModel.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include @@ -45,8 +44,11 @@ Utils::Color Material::BlinnPhongMaterialModel::evalBSDF( Vector3 w_i, Utils::Color bsdf = diffuse + specular; } -std::optional> -BlinnPhongMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent, Vector2 u ) { +std::optional> BlinnPhongMaterialModel::sample( Vector3 inDir, + Vector3 normal, + Vector3 tangent, + Vector3 bitangent, + Vector2 u ) { Vector3 halfway; Vector3 rgbToLuminance { 0.2126_ra, 0.7152_ra, 0.0722_ra }; @@ -57,21 +59,21 @@ BlinnPhongMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector3 tangent, dIntensity /= diffSpecNorm; sIntensity /= diffSpecNorm; - Core::Random::MersenneTwisterGenerator generator = Core::Random::MersenneTwisterGenerator(); - Scalar distrib = generator.get1D(); + Scalar distrib = m_generator->get1D(); Scalar roughness = getRoughness(); // diffuse part if ( distrib < dIntensity ) { - std::pair smpl = m_sampler.CosineWeightedSphereSampler::getDir(&generator); + std::pair smpl = + m_sampler.CosineWeightedSphereSampler::getDir( m_generator ); Vector3 wi( smpl.first.dot( tangent ), smpl.first.dot( bitangent ), smpl.first.dot( normal ) ); std::pair result { wi, smpl.second }; return result; } else if ( distrib < dIntensity + sIntensity ) { // specular part - std::pair smpl = m_sampler.getDir( &generator, roughness ); + std::pair smpl = m_sampler.getDir( m_generator, roughness ); Vector3 wi( smpl.first.dot( tangent ), smpl.first.dot( bitangent ), smpl.first.dot( normal ) ); std::pair result { wi, smpl.second }; diff --git a/src/Core/Material/BlinnPhongMaterialModel.hpp b/src/Core/Material/BlinnPhongMaterialModel.hpp index d9b3fc7f4fb..b4e40a83c44 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.hpp +++ b/src/Core/Material/BlinnPhongMaterialModel.hpp @@ -1,8 +1,9 @@ #pragma once -#include -#include +#include #include +#include +#include #include @@ -11,11 +12,18 @@ namespace Core { namespace Material { // RADIUM SUPPORTED MATERIALS -class RA_CORE_API BlinnPhongMaterialModel : public MaterialModel +class RA_CORE_API BlinnPhongMaterialModel : public SimpleMaterialModel { public: - explicit BlinnPhongMaterialModel( const std::string& name = "" ) : m_sampler(Core::Random::BlinnPhongSphereSampler()), - MaterialModel( name, "BlinnPhong" ) {} + explicit BlinnPhongMaterialModel( const std::string& name = "" ) : + m_sampler( Core::Random::BlinnPhongSphereSampler() ), + SimpleMaterialModel( name, "BlinnPhong" ) {} + + explicit BlinnPhongMaterialModel( Core::Random::UniformGenerator* generator, + const std::string& name = "" ) : + m_sampler( Core::Random::BlinnPhongSphereSampler() ), + SimpleMaterialModel( name, "BlinnPhong", generator ) {} + ~BlinnPhongMaterialModel() override = default; /// DEBUG @@ -23,16 +31,12 @@ class RA_CORE_API BlinnPhongMaterialModel : public MaterialModel /// QUERY - bool hasDiffuseTexture() const { return m_hasTexDiffuse; } - bool hasSpecularTexture() const { return m_hasTexSpecular; } bool hasShininessTexture() const { return m_hasTexShininess; } bool hasNormalTexture() const { return m_hasTexNormal; } - bool hasOpacityTexture() const { return m_hasTexOpacity; } - Utils::Color evalBSDF( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) override; std::optional> sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent, Vector2 u ) override; @@ -44,17 +48,12 @@ class RA_CORE_API BlinnPhongMaterialModel : public MaterialModel Core::Utils::Color m_kd { 0.7_ra, 0.7_ra, 0.7_ra }; Core::Utils::Color m_ks { 0.3_ra, 0.3_ra, 0.3_ra }; Scalar m_ns { 64_ra }; - Scalar m_alpha { 1_ra }; - std::string m_texDiffuse; std::string m_texSpecular; std::string m_texShininess; std::string m_texNormal; - std::string m_texOpacity; - bool m_hasTexDiffuse { false }; bool m_hasTexSpecular { false }; bool m_hasTexShininess { false }; bool m_hasTexNormal { false }; - bool m_hasTexOpacity { false }; Core::Random::BlinnPhongSphereSampler m_sampler; }; diff --git a/src/Core/Material/SimpleMaterialModel.cpp b/src/Core/Material/SimpleMaterialModel.cpp index 50619c1a623..105442aba17 100644 --- a/src/Core/Material/SimpleMaterialModel.cpp +++ b/src/Core/Material/SimpleMaterialModel.cpp @@ -1,5 +1,4 @@ #include -#include #include #include @@ -26,8 +25,11 @@ void SimpleMaterialModel::displayInfo() const { Utils::Color SimpleMaterialModel::evalBSDF( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) { return m_kd; } -std::optional> -SimpleMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent, Vector2 u ) { +std::optional> SimpleMaterialModel::sample( Vector3 inDir, + Vector3 normal, + Vector3 tangent, + Vector3 bitangent, + Vector2 u ) { return {}; } Scalar SimpleMaterialModel::PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) { @@ -59,11 +61,13 @@ Utils::Color Material::LambertianMaterialModel::evalBSDF( Vector3 w_i, return m_kd / M_PI; } -std::optional> -LambertianMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent, Vector2 u ) { +std::optional> LambertianMaterialModel::sample( Vector3 inDir, + Vector3 normal, + Vector3 tangent, + Vector3 bitangent, + Vector2 u ) { // sample point on hemisphere with cosine-weighted distribution - Core::Random::MersenneTwisterGenerator generator = Core::Random::MersenneTwisterGenerator(); - std::pair smpl = m_sampler.getDir(&generator); + std::pair smpl = m_sampler.getDir( m_generator ); // transform sampled point from local to world coodinate system Vector3 wi( smpl.first.dot( tangent ), smpl.first.dot( bitangent ), smpl.first.dot( normal ) ); @@ -73,7 +77,7 @@ LambertianMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector3 tangent, } Scalar LambertianMaterialModel::PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) { - return m_sampler.pdf(outDir, normal); + return m_sampler.pdf( outDir, normal ); } } // namespace Material diff --git a/src/Core/Material/SimpleMaterialModel.hpp b/src/Core/Material/SimpleMaterialModel.hpp index 8a5e2a988dd..790e30d7f56 100644 --- a/src/Core/Material/SimpleMaterialModel.hpp +++ b/src/Core/Material/SimpleMaterialModel.hpp @@ -1,8 +1,10 @@ #pragma once #include -#include #include +#include +#include +#include namespace Ra { namespace Core { @@ -13,7 +15,14 @@ class RA_CORE_API SimpleMaterialModel : public MaterialModel { protected: SimpleMaterialModel( const std::string& name, const std::string type ) : - MaterialModel( name, type ) {} + m_generator( new Core::Random::MersenneTwisterGenerator() ), MaterialModel( name, type ) {} + + SimpleMaterialModel( const std::string& name, + const std::string type, + Core::Random::UniformGenerator* generator ) : + MaterialModel( name, type ) { + *m_generator = *generator; + } public: explicit SimpleMaterialModel( const std::string& name = "" ) : MaterialModel( name, "Plain" ) {} @@ -38,13 +47,22 @@ class RA_CORE_API SimpleMaterialModel : public MaterialModel std::string m_texOpacity; bool m_hasTexDiffuse { false }; bool m_hasTexOpacity { false }; + + Core::Random::UniformGenerator* m_generator; }; class RA_CORE_API LambertianMaterialModel : public SimpleMaterialModel { public: - explicit LambertianMaterialModel( const std::string& name = "" ) : m_sampler(Core::Random::CosineWeightedSphereSampler()), + explicit LambertianMaterialModel( const std::string& name = "" ) : + m_sampler( Core::Random::CosineWeightedSphereSampler() ), SimpleMaterialModel( name, "Lambertian" ) {} + + explicit LambertianMaterialModel( Core::Random::UniformGenerator* generator, + const std::string& name = "" ) : + m_sampler( Core::Random::CosineWeightedSphereSampler() ), + SimpleMaterialModel( name, "Lambertian", generator ) {} + ~LambertianMaterialModel() override = default; /// DEBUG diff --git a/src/Core/Random/SphereSampler.hpp b/src/Core/Random/SphereSampler.hpp index cc04a320bcc..b96dd20c9c3 100644 --- a/src/Core/Random/SphereSampler.hpp +++ b/src/Core/Random/SphereSampler.hpp @@ -1,23 +1,25 @@ #pragma once -#include +#include +#include namespace Ra { namespace Core { namespace Random { -class RA_CORE_API SphereSampler : public ImportanceSampler { +class RA_CORE_API SphereSampler +{ public: SphereSampler() {}; ~SphereSampler() {}; virtual std::pair getPoint( UniformGenerator* generator ) = 0; - virtual std::pair getDir( UniformGenerator* generator ) = 0; + virtual std::pair getDir( UniformGenerator* generator ) = 0; virtual Scalar pdf( Vector3 dir, Vector3 normal ) = 0; - virtual Scalar pdf( Vector2 point ) = 0; + virtual Scalar pdf( Vector2 point ) = 0; }; } // namespace Random } // namespace Core -} // namespace Ra \ No newline at end of file +} // namespace Ra diff --git a/src/Core/filelist.cmake b/src/Core/filelist.cmake index ac15bdadfe3..062dfc8ad7d 100644 --- a/src/Core/filelist.cmake +++ b/src/Core/filelist.cmake @@ -1,6 +1,6 @@ # ---------------------------------------------------- # This file can be generated from a script: -# To do so, run "./generateFilelistForModule.sh Core" +# To do so, run "./generateFilelistForModule.sh Core" # from ./scripts directory # ---------------------------------------------------- @@ -150,4 +150,3 @@ set(core_headers Utils/TypesUtils.hpp Utils/Version.hpp ) - From a5a6bf4166a6085b7fc747019bee8b491d844eff Mon Sep 17 00:00:00 2001 From: grandch Date: Mon, 3 Jul 2023 16:44:06 +0200 Subject: [PATCH 20/56] make samplers CRTP for static methods --- src/Core/Material/BlinnPhongMaterialModel.cpp | 15 +++++++++------ src/Core/Material/BlinnPhongMaterialModel.hpp | 4 ---- src/Core/Material/SimpleMaterialModel.cpp | 5 +++-- src/Core/Material/SimpleMaterialModel.hpp | 4 ---- src/Core/Random/BlinnPhongSphereSampler.hpp | 13 +++++++------ src/Core/Random/CosineWeightedSphereSampler.cpp | 16 +++++++++------- src/Core/Random/CosineWeightedSphereSampler.hpp | 13 +++++++------ src/Core/Random/SphereSampler.hpp | 13 +++++++++---- src/Core/Random/UniformSphereSampler.cpp | 16 +++++++++------- src/Core/Random/UniformSphereSampler.hpp | 13 +++++++------ 10 files changed, 60 insertions(+), 52 deletions(-) diff --git a/src/Core/Material/BlinnPhongMaterialModel.cpp b/src/Core/Material/BlinnPhongMaterialModel.cpp index 73edcda9d50..b66f845bf5f 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.cpp +++ b/src/Core/Material/BlinnPhongMaterialModel.cpp @@ -66,14 +66,15 @@ std::optional> BlinnPhongMaterialModel::sample( Vecto // diffuse part if ( distrib < dIntensity ) { std::pair smpl = - m_sampler.CosineWeightedSphereSampler::getDir( m_generator ); + Core::Random::CosineWeightedSphereSampler::getDir( m_generator ); Vector3 wi( smpl.first.dot( tangent ), smpl.first.dot( bitangent ), smpl.first.dot( normal ) ); std::pair result { wi, smpl.second }; return result; } else if ( distrib < dIntensity + sIntensity ) { // specular part - std::pair smpl = m_sampler.getDir( m_generator, roughness ); + std::pair smpl = + Core::Random::BlinnPhongSphereSampler::getDir( m_generator, roughness ); Vector3 wi( smpl.first.dot( tangent ), smpl.first.dot( bitangent ), smpl.first.dot( normal ) ); std::pair result { wi, smpl.second }; @@ -93,10 +94,12 @@ Scalar BlinnPhongMaterialModel::PDF( Vector3 inDir, Vector3 outDir, Vector3 norm dIntensity /= diffSpecNorm; sIntensity /= diffSpecNorm; - return std::clamp( dIntensity * m_sampler.CosineWeightedSphereSampler::pdf( outDir, normal ) + - sIntensity * m_sampler.pdf( outDir, normal, getRoughness() ), - 0_ra, - 1_ra ); + return std::clamp( + dIntensity * Core::Random::CosineWeightedSphereSampler::pdf( outDir, normal ) + + sIntensity * + Core::Random::BlinnPhongSphereSampler::pdf( outDir, normal, getRoughness() ), + 0_ra, + 1_ra ); } Scalar BlinnPhongMaterialModel::getRoughness() { diff --git a/src/Core/Material/BlinnPhongMaterialModel.hpp b/src/Core/Material/BlinnPhongMaterialModel.hpp index b4e40a83c44..b26468ee5f3 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.hpp +++ b/src/Core/Material/BlinnPhongMaterialModel.hpp @@ -16,12 +16,10 @@ class RA_CORE_API BlinnPhongMaterialModel : public SimpleMaterialModel { public: explicit BlinnPhongMaterialModel( const std::string& name = "" ) : - m_sampler( Core::Random::BlinnPhongSphereSampler() ), SimpleMaterialModel( name, "BlinnPhong" ) {} explicit BlinnPhongMaterialModel( Core::Random::UniformGenerator* generator, const std::string& name = "" ) : - m_sampler( Core::Random::BlinnPhongSphereSampler() ), SimpleMaterialModel( name, "BlinnPhong", generator ) {} ~BlinnPhongMaterialModel() override = default; @@ -54,8 +52,6 @@ class RA_CORE_API BlinnPhongMaterialModel : public SimpleMaterialModel bool m_hasTexSpecular { false }; bool m_hasTexShininess { false }; bool m_hasTexNormal { false }; - - Core::Random::BlinnPhongSphereSampler m_sampler; }; } // namespace Material diff --git a/src/Core/Material/SimpleMaterialModel.cpp b/src/Core/Material/SimpleMaterialModel.cpp index 105442aba17..f8e0d4b6a0b 100644 --- a/src/Core/Material/SimpleMaterialModel.cpp +++ b/src/Core/Material/SimpleMaterialModel.cpp @@ -67,7 +67,8 @@ std::optional> LambertianMaterialModel::sample( Vecto Vector3 bitangent, Vector2 u ) { // sample point on hemisphere with cosine-weighted distribution - std::pair smpl = m_sampler.getDir( m_generator ); + std::pair smpl = + Core::Random::CosineWeightedSphereSampler::getDir( m_generator ); // transform sampled point from local to world coodinate system Vector3 wi( smpl.first.dot( tangent ), smpl.first.dot( bitangent ), smpl.first.dot( normal ) ); @@ -77,7 +78,7 @@ std::optional> LambertianMaterialModel::sample( Vecto } Scalar LambertianMaterialModel::PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) { - return m_sampler.pdf( outDir, normal ); + return Core::Random::CosineWeightedSphereSampler::pdf( outDir, normal ); } } // namespace Material diff --git a/src/Core/Material/SimpleMaterialModel.hpp b/src/Core/Material/SimpleMaterialModel.hpp index 790e30d7f56..ee3da5a69a7 100644 --- a/src/Core/Material/SimpleMaterialModel.hpp +++ b/src/Core/Material/SimpleMaterialModel.hpp @@ -55,12 +55,10 @@ class RA_CORE_API LambertianMaterialModel : public SimpleMaterialModel { public: explicit LambertianMaterialModel( const std::string& name = "" ) : - m_sampler( Core::Random::CosineWeightedSphereSampler() ), SimpleMaterialModel( name, "Lambertian" ) {} explicit LambertianMaterialModel( Core::Random::UniformGenerator* generator, const std::string& name = "" ) : - m_sampler( Core::Random::CosineWeightedSphereSampler() ), SimpleMaterialModel( name, "Lambertian", generator ) {} ~LambertianMaterialModel() override = default; @@ -79,8 +77,6 @@ class RA_CORE_API LambertianMaterialModel : public SimpleMaterialModel /// DATA MEMBERS std::string m_texNormal; bool m_hasTexNormal { false }; - - Core::Random::CosineWeightedSphereSampler m_sampler; }; } // namespace Material diff --git a/src/Core/Random/BlinnPhongSphereSampler.hpp b/src/Core/Random/BlinnPhongSphereSampler.hpp index be6aa93269a..34bdf52b1d7 100644 --- a/src/Core/Random/BlinnPhongSphereSampler.hpp +++ b/src/Core/Random/BlinnPhongSphereSampler.hpp @@ -6,18 +6,19 @@ namespace Ra { namespace Core { namespace Random { -class RA_CORE_API BlinnPhongSphereSampler : public CosineWeightedSphereSampler { +class RA_CORE_API BlinnPhongSphereSampler : public CosineWeightedSphereSampler +{ public: BlinnPhongSphereSampler() {}; ~BlinnPhongSphereSampler() {}; - std::pair getPoint( UniformGenerator* generator, Scalar roughness ); - std::pair getDir( UniformGenerator* generator, Scalar roughness ); + static std::pair getPoint( UniformGenerator* generator, Scalar roughness ); + static std::pair getDir( UniformGenerator* generator, Scalar roughness ); - Scalar pdf( Vector3 dir, Vector3 normal, Scalar roughness ); - Scalar pdf( Vector2 point, Scalar roughness ); + static Scalar pdf( Vector3 dir, Vector3 normal, Scalar roughness ); + static Scalar pdf( Vector2 point, Scalar roughness ); }; } // namespace Random } // namespace Core -} // namespace Ra \ No newline at end of file +} // namespace Ra diff --git a/src/Core/Random/CosineWeightedSphereSampler.cpp b/src/Core/Random/CosineWeightedSphereSampler.cpp index 2456e7aa75a..6fdbe597f74 100644 --- a/src/Core/Random/CosineWeightedSphereSampler.cpp +++ b/src/Core/Random/CosineWeightedSphereSampler.cpp @@ -6,12 +6,14 @@ namespace Ra { namespace Core { namespace Random { -std::pair Ra::Core::Random::CosineWeightedSphereSampler::getPoint( UniformGenerator* generator ) { +std::pair +Ra::Core::Random::CosineWeightedSphereSampler::getPointImplem( UniformGenerator* generator ) { Vector2 u = generator->get2D(); - return {{std::sqrt( u[0] ), 2 * Math::Pi * u[1]}, u[0] / Math::Pi}; + return { { std::sqrt( u[0] ), 2 * Math::Pi * u[1] }, u[0] / Math::Pi }; } -std::pair Ra::Core::Random::CosineWeightedSphereSampler::getDir( UniformGenerator* generator ) { +std::pair +Ra::Core::Random::CosineWeightedSphereSampler::getDirImplem( UniformGenerator* generator ) { Vector3 dir; Vector2 u = generator->get2D(); @@ -23,18 +25,18 @@ std::pair Ra::Core::Random::CosineWeightedSphereSampler::getDir dir[1] = sinTheta * std::sin( phi ); dir[2] = cosTheta; - return {dir, u[0] / Math::Pi}; + return { dir, u[0] / Math::Pi }; } -Scalar CosineWeightedSphereSampler::pdf( Vector3 dir, Vector3 normal ) { +Scalar CosineWeightedSphereSampler::pdfImplem( Vector3 dir, Vector3 normal ) { dir.normalize(); return dir.dot( normal ) / Math::Pi; } -Scalar CosineWeightedSphereSampler::pdf( Vector2 point ) { +Scalar CosineWeightedSphereSampler::pdfImplem( Vector2 point ) { return point[0] / Math::Pi; } } // namespace Random } // namespace Core -} // namespace Ra \ No newline at end of file +} // namespace Ra diff --git a/src/Core/Random/CosineWeightedSphereSampler.hpp b/src/Core/Random/CosineWeightedSphereSampler.hpp index 302c1c617da..f9ac6d4582c 100644 --- a/src/Core/Random/CosineWeightedSphereSampler.hpp +++ b/src/Core/Random/CosineWeightedSphereSampler.hpp @@ -6,18 +6,19 @@ namespace Ra { namespace Core { namespace Random { -class RA_CORE_API CosineWeightedSphereSampler : public SphereSampler { +class RA_CORE_API CosineWeightedSphereSampler : public SphereSampler +{ public: CosineWeightedSphereSampler() {}; ~CosineWeightedSphereSampler() {}; - std::pair getPoint( UniformGenerator* generator ) override; - std::pair getDir( UniformGenerator* generator ) override; + static std::pair getPointImplem( UniformGenerator* generator ); + static std::pair getDirImplem( UniformGenerator* generator ); - Scalar pdf( Vector3 dir, Vector3 normal ) override; - Scalar pdf( Vector2 point ) override; + static Scalar pdfImplem( Vector3 dir, Vector3 normal ); + static Scalar pdfImplem( Vector2 point ); }; } // namespace Random } // namespace Core -} // namespace Ra \ No newline at end of file +} // namespace Ra diff --git a/src/Core/Random/SphereSampler.hpp b/src/Core/Random/SphereSampler.hpp index b96dd20c9c3..fc609122952 100644 --- a/src/Core/Random/SphereSampler.hpp +++ b/src/Core/Random/SphereSampler.hpp @@ -7,17 +7,22 @@ namespace Ra { namespace Core { namespace Random { +template class RA_CORE_API SphereSampler { public: SphereSampler() {}; ~SphereSampler() {}; - virtual std::pair getPoint( UniformGenerator* generator ) = 0; - virtual std::pair getDir( UniformGenerator* generator ) = 0; + static std::pair getPoint( UniformGenerator* generator ) { + T::getPointImplem( generator ); + } + static std::pair getDir( UniformGenerator* generator ) { + T::getDirImplem( generator ); + } - virtual Scalar pdf( Vector3 dir, Vector3 normal ) = 0; - virtual Scalar pdf( Vector2 point ) = 0; + static Scalar pdf( Vector3 dir, Vector3 normal ) { T::pdfImplem( dir, normal ); } + static Scalar pdf( Vector2 point ) { T::pdfImplem( point ); } }; } // namespace Random diff --git a/src/Core/Random/UniformSphereSampler.cpp b/src/Core/Random/UniformSphereSampler.cpp index 2ee41296c9d..fb530331fe5 100644 --- a/src/Core/Random/UniformSphereSampler.cpp +++ b/src/Core/Random/UniformSphereSampler.cpp @@ -6,12 +6,14 @@ namespace Ra { namespace Core { namespace Random { -std::pair Ra::Core::Random::UniformSphereSampler::getPoint( UniformGenerator* generator ) { +std::pair +Ra::Core::Random::UniformSphereSampler::getPointImplem( UniformGenerator* generator ) { Vector2 u = generator->get2D(); - return {{u[0], 2 * Math::Pi * u[1]}, 1 / 2 * Math::Pi}; + return { { u[0], 2 * Math::Pi * u[1] }, 1 / 2 * Math::Pi }; } -std::pair Ra::Core::Random::UniformSphereSampler::getDir( UniformGenerator* generator ) { +std::pair +Ra::Core::Random::UniformSphereSampler::getDirImplem( UniformGenerator* generator ) { Vector3 dir; Vector2 u = generator->get2D(); @@ -23,17 +25,17 @@ std::pair Ra::Core::Random::UniformSphereSampler::getDir( Unifo dir[1] = sinTheta * std::sin( phi ); dir[2] = cosTheta; - return {dir, 1 / 2 * Math::Pi}; + return { dir, 1 / 2 * Math::Pi }; } -Scalar UniformSphereSampler::pdf( Vector3 dir, Vector3 normal ) { +Scalar UniformSphereSampler::pdfImplem( Vector3 dir, Vector3 normal ) { return 1 / 2 * Math::Pi; } -Scalar UniformSphereSampler::pdf( Vector2 point ) { +Scalar UniformSphereSampler::pdfImplem( Vector2 point ) { return 1 / 2 * Math::Pi; } } // namespace Random } // namespace Core -} // namespace Ra \ No newline at end of file +} // namespace Ra diff --git a/src/Core/Random/UniformSphereSampler.hpp b/src/Core/Random/UniformSphereSampler.hpp index e10a87df916..a96a7f0e053 100644 --- a/src/Core/Random/UniformSphereSampler.hpp +++ b/src/Core/Random/UniformSphereSampler.hpp @@ -6,18 +6,19 @@ namespace Ra { namespace Core { namespace Random { -class RA_CORE_API UniformSphereSampler : public SphereSampler { +class RA_CORE_API UniformSphereSampler : public SphereSampler +{ public: UniformSphereSampler() {}; ~UniformSphereSampler() {}; - std::pair getPoint( UniformGenerator* generator ) override; - std::pair getDir( UniformGenerator* generator ) override; + static std::pair getPointImplem( UniformGenerator* generator ); + static std::pair getDirImplem( UniformGenerator* generator ); - Scalar pdf( Vector3 dir, Vector3 normal ) override; - Scalar pdf( Vector2 point ) override; + static Scalar pdfImplem( Vector3 dir, Vector3 normal ); + static Scalar pdfImplem( Vector2 point ); }; } // namespace Random } // namespace Core -} // namespace Ra \ No newline at end of file +} // namespace Ra From f206a5da247ab7646f395c009f56e8bcfa9beaab Mon Sep 17 00:00:00 2001 From: grandch Date: Tue, 4 Jul 2023 15:55:51 +0200 Subject: [PATCH 21/56] fix include --- src/Core/Material/BlinnPhongMaterialModel.cpp | 1 - src/Core/Material/SimpleMaterialModel.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/src/Core/Material/BlinnPhongMaterialModel.cpp b/src/Core/Material/BlinnPhongMaterialModel.cpp index b66f845bf5f..aa8dd904ac9 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.cpp +++ b/src/Core/Material/BlinnPhongMaterialModel.cpp @@ -1,5 +1,4 @@ #include -#include #include #include diff --git a/src/Core/Material/SimpleMaterialModel.cpp b/src/Core/Material/SimpleMaterialModel.cpp index f8e0d4b6a0b..db2072e5c99 100644 --- a/src/Core/Material/SimpleMaterialModel.cpp +++ b/src/Core/Material/SimpleMaterialModel.cpp @@ -1,5 +1,4 @@ #include -#include #include From 1c4efe698965140229d0d1e1a67fb629ff6e4073 Mon Sep 17 00:00:00 2001 From: grandch Date: Wed, 5 Jul 2023 18:15:15 +0200 Subject: [PATCH 22/56] fix crtp --- src/Core/Random/SphereSampler.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Core/Random/SphereSampler.hpp b/src/Core/Random/SphereSampler.hpp index fc609122952..8919e594aad 100644 --- a/src/Core/Random/SphereSampler.hpp +++ b/src/Core/Random/SphereSampler.hpp @@ -15,14 +15,14 @@ class RA_CORE_API SphereSampler ~SphereSampler() {}; static std::pair getPoint( UniformGenerator* generator ) { - T::getPointImplem( generator ); + return T::getPointImplem( generator ); } static std::pair getDir( UniformGenerator* generator ) { - T::getDirImplem( generator ); + return T::getDirImplem( generator ); } - static Scalar pdf( Vector3 dir, Vector3 normal ) { T::pdfImplem( dir, normal ); } - static Scalar pdf( Vector2 point ) { T::pdfImplem( point ); } + static Scalar pdf( Vector3 dir, Vector3 normal ) { return T::pdfImplem( dir, normal ); } + static Scalar pdf( Vector2 point ) { return T::pdfImplem( point ); } }; } // namespace Random From 4d77fbbd2ddc5cef307351db49b398c1a14c880b Mon Sep 17 00:00:00 2001 From: grandch Date: Wed, 5 Jul 2023 17:39:59 +0200 Subject: [PATCH 23/56] example --- examples/CMakeLists.txt | 1 + examples/PlotImportanceSampler/CMakeLists.txt | 61 +++++++++++++++++++ examples/PlotImportanceSampler/main.cpp | 51 ++++++++++++++++ 3 files changed, 113 insertions(+) create mode 100644 examples/PlotImportanceSampler/CMakeLists.txt create mode 100644 examples/PlotImportanceSampler/main.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index e9171f7f5a4..3b864d52caa 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -23,6 +23,7 @@ foreach( MaterialEdition ParameterEdition Picking + PlotImportanceSampler RawShaderMaterial SimpleAnimation SimpleSimulation diff --git a/examples/PlotImportanceSampler/CMakeLists.txt b/examples/PlotImportanceSampler/CMakeLists.txt new file mode 100644 index 00000000000..a8a1b3f1e92 --- /dev/null +++ b/examples/PlotImportanceSampler/CMakeLists.txt @@ -0,0 +1,61 @@ +cmake_minimum_required(VERSION 3.16) +cmake_policy(SET CMP0042 NEW) + +project(PlotImportanceSampler) + +# ------------------------------------------------------------------------------ +# set wanted application defaults for cmake settings +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif() +# Set default install location to installed- folder in build dir we do not want to +# install to /usr by default +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX + "${CMAKE_CURRENT_BINARY_DIR}/installed-${CMAKE_CXX_COMPILER_ID}-${CMAKE_BUILD_TYPE}" + CACHE PATH "Install path prefix, prepended onto install directories." FORCE + ) + message("Set install prefix to ${CMAKE_INSTALL_PREFIX}") +endif() +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_DISABLE_SOURCE_CHANGES ON) +set(CMAKE_DISABLE_IN_SOURCE_BUILD ON) + +# ------------------------------------------------------------------------------ + +find_package(Radium REQUIRED Core) + +# ------------------------------------------------------------------------------ + +set(app_sources main.cpp) +set(app_headers) +set(app_resources) + +# to install the app as a redistribuable bundle on macos, add MACOSX_BUNDLE when calling +# add_executable +add_executable(${PROJECT_NAME} ${app_sources} ${app_headers} ${app_uis} ${app_resources}) + +if("${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC") + target_compile_options( + ${PROJECT_NAME} + PRIVATE /MP + /W4 + /wd4251 + /wd4592 + /wd4127 + /Zm200 + $<$: + /Gw + /GS- + /GL + /GF + > + PUBLIC + ) +endif() + +target_link_libraries(${PROJECT_NAME} PUBLIC Radium::Core) + +# configure the application +configure_radium_app(NAME ${PROJECT_NAME}) diff --git a/examples/PlotImportanceSampler/main.cpp b/examples/PlotImportanceSampler/main.cpp new file mode 100644 index 00000000000..b117ac5bb5f --- /dev/null +++ b/examples/PlotImportanceSampler/main.cpp @@ -0,0 +1,51 @@ +#include +#include +#include +#include + +#include +#include +#include +#include + +int main( int /*argc*/, char** /*argv*/ ) { + using namespace Ra::Core; + using json = nlohmann::json; + + Random::MersenneTwisterGenerator generator = Random::MersenneTwisterGenerator(); + + std::vector uSamplesDir, cSamplesDir, bSamplesDir01, bSamplesDir05, bSamplesDir09; + // std::vector uSamplesPoint, cSamplesPoint, bSamplesPoint, lbSamplesPoint, + // bpSamplesPoint; + + for ( int i = 0; i < 500; i++ ) { + uSamplesDir.push_back( Random::UniformSphereSampler::getDir( &generator ).first ); + cSamplesDir.push_back( Random::CosineWeightedSphereSampler::getDir( &generator ).first ); + bSamplesDir01.push_back( Random::BlinnPhongSphereSampler::getDir( &generator, 0.1 ).first ); + bSamplesDir05.push_back( Random::BlinnPhongSphereSampler::getDir( &generator, 0.5 ).first ); + bSamplesDir09.push_back( Random::BlinnPhongSphereSampler::getDir( &generator, 0.9 ).first ); + + // uSamplesPoint.push_back( Random::UniformSphereSampler::getPoint( &generator ).first ); + // cSamplesPoint.push_back( + // Random::CosineWeightedSphereSampler::getPoint( &generator ).first ); + // bSamplesPoint.push_back( Random::BlinnPhongSphereSampler::getPoint( &generator, 0.7 + // ).first ); + } + + json j = { { "UniformSampleDir", uSamplesDir }, + { "CosineWeightedSampleDir", cSamplesDir }, + { "BlinnPhongSampleDir r=0.1", bSamplesDir01 }, + { "BlinnPhongSampleDir r=0.5", bSamplesDir05 }, + { "BlinnPhongSampleDir r=0.9", bSamplesDir09 } }; + // { "UniformSamplePoint", uSamplesPoint }, + // { "CosineWeightedSamplePoint", cSamplesPoint }, + // { "BlinnPhongSamplePoint", bSamplesPoint } + + std::ofstream o( "samples.json" ); + + o << std::setw( 4 ) << j << std::endl; + + o.close(); + + return 0; +} From b03287ccf93d74ef5476fe3baee23aa8f26e0631 Mon Sep 17 00:00:00 2001 From: grandch Date: Fri, 7 Jul 2023 13:40:12 +0200 Subject: [PATCH 24/56] fix samplers --- src/Core/Random/BlinnPhongSphereSampler.cpp | 16 +++++++++------- src/Core/Random/CosineWeightedSphereSampler.cpp | 4 ++-- src/Core/Random/UniformSphereSampler.cpp | 4 ++-- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/Core/Random/BlinnPhongSphereSampler.cpp b/src/Core/Random/BlinnPhongSphereSampler.cpp index 5cea1478107..f2493ea7645 100644 --- a/src/Core/Random/BlinnPhongSphereSampler.cpp +++ b/src/Core/Random/BlinnPhongSphereSampler.cpp @@ -5,11 +5,13 @@ namespace Ra { namespace Core { namespace Random { - + std::pair -Ra::Core::Random::BlinnPhongSphereSampler::getPoint( UniformGenerator* generator, Scalar roughness ) { +Ra::Core::Random::BlinnPhongSphereSampler::getPoint( UniformGenerator* generator, + Scalar roughness ) { Vector2 u = generator->get2D(); - return {{std::pow( u[0], 1_ra / ( roughness + 2 ) ), 2 * Math::Pi * u[1]}, ( roughness + 2 ) * std::pow( u[0], roughness ) / 2 * Math::Pi}; + return { { std::pow( u[0], 1_ra / ( roughness + 2 ) ), 2 * Math::Pi * u[1] }, + ( roughness + 2 ) * std::pow( u[0], roughness ) / 2 * Math::Pi }; } std::pair @@ -17,8 +19,8 @@ Ra::Core::Random::BlinnPhongSphereSampler::getDir( UniformGenerator* generator, Vector3 dir; Vector2 u = generator->get2D(); - Scalar cosTheta = std::pow( u[0], 1_ra / ( roughness + 2 ) ); - Scalar sinTheta = 1 - u[0]; + Scalar cosTheta = std::cos( std::pow( u[0], 1_ra / ( roughness + 2 ) ) ); + Scalar sinTheta = std::cos( Math::Pi / 2_ra - std::pow( u[0], 1_ra / ( roughness + 2 ) ) ); Scalar phi = 2 * Math::Pi * u[1]; dir[0] = sinTheta * std::cos( phi ); @@ -30,7 +32,7 @@ Ra::Core::Random::BlinnPhongSphereSampler::getDir( UniformGenerator* generator, Scalar BlinnPhongSphereSampler::pdf( Vector3 dir, Vector3 normal, Scalar roughness ) { dir.normalize(); - return ( roughness + 2 ) * std::pow( dir.dot(normal), roughness ) / 2 * Math::Pi; + return ( roughness + 2 ) * std::pow( dir.dot( normal ), roughness ) / 2 * Math::Pi; } Scalar BlinnPhongSphereSampler::pdf( Vector2 point, Scalar roughness ) { @@ -39,4 +41,4 @@ Scalar BlinnPhongSphereSampler::pdf( Vector2 point, Scalar roughness ) { } // namespace Random } // namespace Core -} // namespace Ra \ No newline at end of file +} // namespace Ra diff --git a/src/Core/Random/CosineWeightedSphereSampler.cpp b/src/Core/Random/CosineWeightedSphereSampler.cpp index 6fdbe597f74..f182f72059e 100644 --- a/src/Core/Random/CosineWeightedSphereSampler.cpp +++ b/src/Core/Random/CosineWeightedSphereSampler.cpp @@ -17,8 +17,8 @@ Ra::Core::Random::CosineWeightedSphereSampler::getDirImplem( UniformGenerator* g Vector3 dir; Vector2 u = generator->get2D(); - Scalar cosTheta = std::sqrt( u[0] ); - Scalar sinTheta = std::sqrt( 1 - u[0] ); + Scalar cosTheta = std::cos( std::sqrt( u[0] ) ); + Scalar sinTheta = std::cos( Math::Pi / 2_ra - std::sqrt( u[0] ) ); Scalar phi = 2 * Math::Pi * u[1]; dir[0] = sinTheta * std::cos( phi ); diff --git a/src/Core/Random/UniformSphereSampler.cpp b/src/Core/Random/UniformSphereSampler.cpp index fb530331fe5..e0d19ce4a00 100644 --- a/src/Core/Random/UniformSphereSampler.cpp +++ b/src/Core/Random/UniformSphereSampler.cpp @@ -17,8 +17,8 @@ Ra::Core::Random::UniformSphereSampler::getDirImplem( UniformGenerator* generato Vector3 dir; Vector2 u = generator->get2D(); - Scalar cosTheta = u[0]; - Scalar sinTheta = 1 - u[0]; + Scalar cosTheta = std::cos( u[0] ); + Scalar sinTheta = std::cos( Math::Pi / 2_ra - u[0] ); Scalar phi = 2 * Math::Pi * u[1]; dir[0] = sinTheta * std::cos( phi ); From 1c976db65b8702ea2c60dd37d82c52df46e86260 Mon Sep 17 00:00:00 2001 From: grandch Date: Fri, 7 Jul 2023 14:00:39 +0200 Subject: [PATCH 25/56] add plot.py --- .../PlotImportanceSampler/plot-samples.py | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 examples/PlotImportanceSampler/plot-samples.py diff --git a/examples/PlotImportanceSampler/plot-samples.py b/examples/PlotImportanceSampler/plot-samples.py new file mode 100644 index 00000000000..cc381a98f33 --- /dev/null +++ b/examples/PlotImportanceSampler/plot-samples.py @@ -0,0 +1,27 @@ +import json +import matplotlib.pyplot as plt +import matplotlib.gridspec as gridspec +import numpy as np +import math + +def plotDir(array, ax): + for p in array: + ax.scatter(p[0], p[1], p[2], c='#1f77b4', s=1) + +with open('/home/charlie/RadiumInstall/builds/radium-build-r/examples/PlotImportanceSampler/samples.json', 'r') as f: + data = json.load(f) + +size = len(data) + +fig = plt.figure(figsize=plt.figaspect(1/3)) +gs = gridspec.GridSpec(math.ceil(size/3), 3) + +i = 0 +for l in data: + ax = fig.add_subplot(gs[math.floor(i/3), i%3], projection='3d') + ax.set_title(l) + arr = np.array(data[l]) + plotDir(arr, ax) + i += 1 + +plt.show() From 5101d6845bdc94a7a63b7f1186e0c9374bae7343 Mon Sep 17 00:00:00 2001 From: Charlie Grand Date: Tue, 11 Jul 2023 13:55:15 +0200 Subject: [PATCH 26/56] use blinn-phong exponent instead of roughness --- examples/PlotImportanceSampler/main.cpp | 18 +++++++++++------- src/Core/Material/BlinnPhongMaterialModel.cpp | 7 ++----- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/examples/PlotImportanceSampler/main.cpp b/examples/PlotImportanceSampler/main.cpp index b117ac5bb5f..b58875555ac 100644 --- a/examples/PlotImportanceSampler/main.cpp +++ b/examples/PlotImportanceSampler/main.cpp @@ -14,16 +14,19 @@ int main( int /*argc*/, char** /*argv*/ ) { Random::MersenneTwisterGenerator generator = Random::MersenneTwisterGenerator(); - std::vector uSamplesDir, cSamplesDir, bSamplesDir01, bSamplesDir05, bSamplesDir09; + std::vector uSamplesDir, cSamplesDir, bSamplesDir4, bSamplesDir16, bSamplesDir64, + bSamplesDir128; // std::vector uSamplesPoint, cSamplesPoint, bSamplesPoint, lbSamplesPoint, // bpSamplesPoint; for ( int i = 0; i < 500; i++ ) { uSamplesDir.push_back( Random::UniformSphereSampler::getDir( &generator ).first ); cSamplesDir.push_back( Random::CosineWeightedSphereSampler::getDir( &generator ).first ); - bSamplesDir01.push_back( Random::BlinnPhongSphereSampler::getDir( &generator, 0.1 ).first ); - bSamplesDir05.push_back( Random::BlinnPhongSphereSampler::getDir( &generator, 0.5 ).first ); - bSamplesDir09.push_back( Random::BlinnPhongSphereSampler::getDir( &generator, 0.9 ).first ); + bSamplesDir4.push_back( Random::BlinnPhongSphereSampler::getDir( &generator, 4 ).first ); + bSamplesDir16.push_back( Random::BlinnPhongSphereSampler::getDir( &generator, 16 ).first ); + bSamplesDir64.push_back( Random::BlinnPhongSphereSampler::getDir( &generator, 64 ).first ); + bSamplesDir128.push_back( + Random::BlinnPhongSphereSampler::getDir( &generator, 128 ).first ); // uSamplesPoint.push_back( Random::UniformSphereSampler::getPoint( &generator ).first ); // cSamplesPoint.push_back( @@ -34,9 +37,10 @@ int main( int /*argc*/, char** /*argv*/ ) { json j = { { "UniformSampleDir", uSamplesDir }, { "CosineWeightedSampleDir", cSamplesDir }, - { "BlinnPhongSampleDir r=0.1", bSamplesDir01 }, - { "BlinnPhongSampleDir r=0.5", bSamplesDir05 }, - { "BlinnPhongSampleDir r=0.9", bSamplesDir09 } }; + { "BlinnPhongSampleDir 4", bSamplesDir4 }, + { "BlinnPhongSampleDir 16", bSamplesDir16 }, + { "BlinnPhongSampleDir 64", bSamplesDir64 }, + { "BlinnPhongSampleDir 128", bSamplesDir128 } }; // { "UniformSamplePoint", uSamplesPoint }, // { "CosineWeightedSamplePoint", cSamplesPoint }, // { "BlinnPhongSamplePoint", bSamplesPoint } diff --git a/src/Core/Material/BlinnPhongMaterialModel.cpp b/src/Core/Material/BlinnPhongMaterialModel.cpp index aa8dd904ac9..64b8afce0b2 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.cpp +++ b/src/Core/Material/BlinnPhongMaterialModel.cpp @@ -60,8 +60,6 @@ std::optional> BlinnPhongMaterialModel::sample( Vecto Scalar distrib = m_generator->get1D(); - Scalar roughness = getRoughness(); - // diffuse part if ( distrib < dIntensity ) { std::pair smpl = @@ -73,7 +71,7 @@ std::optional> BlinnPhongMaterialModel::sample( Vecto } else if ( distrib < dIntensity + sIntensity ) { // specular part std::pair smpl = - Core::Random::BlinnPhongSphereSampler::getDir( m_generator, roughness ); + Core::Random::BlinnPhongSphereSampler::getDir( m_generator, m_ns ); Vector3 wi( smpl.first.dot( tangent ), smpl.first.dot( bitangent ), smpl.first.dot( normal ) ); std::pair result { wi, smpl.second }; @@ -95,8 +93,7 @@ Scalar BlinnPhongMaterialModel::PDF( Vector3 inDir, Vector3 outDir, Vector3 norm return std::clamp( dIntensity * Core::Random::CosineWeightedSphereSampler::pdf( outDir, normal ) + - sIntensity * - Core::Random::BlinnPhongSphereSampler::pdf( outDir, normal, getRoughness() ), + sIntensity * Core::Random::BlinnPhongSphereSampler::pdf( outDir, normal, m_ns ), 0_ra, 1_ra ); } From 2ceef6cd4da3b6e4aaa8e020f62c6d4446ecbdc2 Mon Sep 17 00:00:00 2001 From: Charlie Grand Date: Tue, 11 Jul 2023 13:57:18 +0200 Subject: [PATCH 27/56] fix operators precedence --- src/Core/Random/BlinnPhongSphereSampler.cpp | 8 ++++---- src/Core/Random/UniformSphereSampler.cpp | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Core/Random/BlinnPhongSphereSampler.cpp b/src/Core/Random/BlinnPhongSphereSampler.cpp index f2493ea7645..83271400dfc 100644 --- a/src/Core/Random/BlinnPhongSphereSampler.cpp +++ b/src/Core/Random/BlinnPhongSphereSampler.cpp @@ -11,7 +11,7 @@ Ra::Core::Random::BlinnPhongSphereSampler::getPoint( UniformGenerator* generator Scalar roughness ) { Vector2 u = generator->get2D(); return { { std::pow( u[0], 1_ra / ( roughness + 2 ) ), 2 * Math::Pi * u[1] }, - ( roughness + 2 ) * std::pow( u[0], roughness ) / 2 * Math::Pi }; + ( roughness + 2 ) * std::pow( u[0], roughness ) / ( 2 * Math::Pi ) }; } std::pair @@ -27,16 +27,16 @@ Ra::Core::Random::BlinnPhongSphereSampler::getDir( UniformGenerator* generator, dir[1] = sinTheta * std::sin( phi ); dir[2] = cosTheta; - return { dir, ( roughness + 2 ) * std::pow( u[0], roughness ) / 2 * Math::Pi }; + return { dir, ( roughness + 2 ) * std::pow( u[0], roughness ) / ( 2 * Math::Pi ) }; } Scalar BlinnPhongSphereSampler::pdf( Vector3 dir, Vector3 normal, Scalar roughness ) { dir.normalize(); - return ( roughness + 2 ) * std::pow( dir.dot( normal ), roughness ) / 2 * Math::Pi; + return ( roughness + 2 ) * std::pow( dir.dot( normal ), roughness ) / ( 2 * Math::Pi ); } Scalar BlinnPhongSphereSampler::pdf( Vector2 point, Scalar roughness ) { - return ( roughness + 2 ) * std::pow( point[0], roughness ) / 2 * Math::Pi; + return ( roughness + 2 ) * std::pow( point[0], roughness ) / ( 2 * Math::Pi ); } } // namespace Random diff --git a/src/Core/Random/UniformSphereSampler.cpp b/src/Core/Random/UniformSphereSampler.cpp index e0d19ce4a00..c04095ce17f 100644 --- a/src/Core/Random/UniformSphereSampler.cpp +++ b/src/Core/Random/UniformSphereSampler.cpp @@ -9,7 +9,7 @@ namespace Random { std::pair Ra::Core::Random::UniformSphereSampler::getPointImplem( UniformGenerator* generator ) { Vector2 u = generator->get2D(); - return { { u[0], 2 * Math::Pi * u[1] }, 1 / 2 * Math::Pi }; + return { { u[0], 2 * Math::Pi * u[1] }, 1 / ( 2 * Math::Pi ) }; } std::pair @@ -25,15 +25,15 @@ Ra::Core::Random::UniformSphereSampler::getDirImplem( UniformGenerator* generato dir[1] = sinTheta * std::sin( phi ); dir[2] = cosTheta; - return { dir, 1 / 2 * Math::Pi }; + return { dir, 1 / ( 2 * Math::Pi ) }; } Scalar UniformSphereSampler::pdfImplem( Vector3 dir, Vector3 normal ) { - return 1 / 2 * Math::Pi; + return 1 / ( 2 * Math::Pi ); } Scalar UniformSphereSampler::pdfImplem( Vector2 point ) { - return 1 / 2 * Math::Pi; + return 1 / ( 2 * Math::Pi ); } } // namespace Random From 0c0195b05225756fdeb937541bff0c174d4c278e Mon Sep 17 00:00:00 2001 From: Charlie Grand Date: Tue, 11 Jul 2023 14:01:38 +0200 Subject: [PATCH 28/56] fix plot samples path --- examples/PlotImportanceSampler/plot-samples.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/PlotImportanceSampler/plot-samples.py b/examples/PlotImportanceSampler/plot-samples.py index cc381a98f33..3e2c4620a3f 100644 --- a/examples/PlotImportanceSampler/plot-samples.py +++ b/examples/PlotImportanceSampler/plot-samples.py @@ -3,12 +3,13 @@ import matplotlib.gridspec as gridspec import numpy as np import math +import sys def plotDir(array, ax): for p in array: ax.scatter(p[0], p[1], p[2], c='#1f77b4', s=1) -with open('/home/charlie/RadiumInstall/builds/radium-build-r/examples/PlotImportanceSampler/samples.json', 'r') as f: +with open(sys.argv[1], 'r') as f: data = json.load(f) size = len(data) @@ -20,6 +21,7 @@ def plotDir(array, ax): for l in data: ax = fig.add_subplot(gs[math.floor(i/3), i%3], projection='3d') ax.set_title(l) + ax.set_zlim(0, 1) arr = np.array(data[l]) plotDir(arr, ax) i += 1 From 9af56433f8171c8d139e28375c0d56928f199fa3 Mon Sep 17 00:00:00 2001 From: Charlie Grand Date: Wed, 19 Jul 2023 11:56:18 +0200 Subject: [PATCH 29/56] fix evalbsdf --- src/Core/Material/BlinnPhongMaterialModel.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Core/Material/BlinnPhongMaterialModel.cpp b/src/Core/Material/BlinnPhongMaterialModel.cpp index 64b8afce0b2..06d2dc0b4c1 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.cpp +++ b/src/Core/Material/BlinnPhongMaterialModel.cpp @@ -41,6 +41,8 @@ Utils::Color Material::BlinnPhongMaterialModel::evalBSDF( Vector3 w_i, // Combine the diffuse and specular components Utils::Color bsdf = diffuse + specular; + + return bsdf; } std::optional> BlinnPhongMaterialModel::sample( Vector3 inDir, From f2e323c69af121dc820a056fd4a4c257d815da7e Mon Sep 17 00:00:00 2001 From: grandch Date: Mon, 24 Jul 2023 18:17:49 +0200 Subject: [PATCH 30/56] fix blinnphong sampling --- src/Core/Random/BlinnPhongSphereSampler.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Core/Random/BlinnPhongSphereSampler.cpp b/src/Core/Random/BlinnPhongSphereSampler.cpp index 83271400dfc..47e394bd562 100644 --- a/src/Core/Random/BlinnPhongSphereSampler.cpp +++ b/src/Core/Random/BlinnPhongSphereSampler.cpp @@ -19,15 +19,15 @@ Ra::Core::Random::BlinnPhongSphereSampler::getDir( UniformGenerator* generator, Vector3 dir; Vector2 u = generator->get2D(); - Scalar cosTheta = std::cos( std::pow( u[0], 1_ra / ( roughness + 2 ) ) ); - Scalar sinTheta = std::cos( Math::Pi / 2_ra - std::pow( u[0], 1_ra / ( roughness + 2 ) ) ); + Scalar cosTheta = std::pow( 1_ra - u[0], 1_ra / ( roughness + 2 ) ); + Scalar sinTheta = std::sqrt( 1_ra - cosTheta * cosTheta ); Scalar phi = 2 * Math::Pi * u[1]; dir[0] = sinTheta * std::cos( phi ); dir[1] = sinTheta * std::sin( phi ); dir[2] = cosTheta; - return { dir, ( roughness + 2 ) * std::pow( u[0], roughness ) / ( 2 * Math::Pi ) }; + return { dir, ( roughness + 2 ) * std::pow( 1_ra - u[0], roughness ) / ( 2 * Math::Pi ) }; } Scalar BlinnPhongSphereSampler::pdf( Vector3 dir, Vector3 normal, Scalar roughness ) { From f73e500cd324a5627935958f34111613e36bc886 Mon Sep 17 00:00:00 2001 From: grandch Date: Mon, 24 Jul 2023 18:18:13 +0200 Subject: [PATCH 31/56] plot sample --- examples/PlotImportanceSampler/main.cpp | 49 ++++++++++++++++--------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/examples/PlotImportanceSampler/main.cpp b/examples/PlotImportanceSampler/main.cpp index b58875555ac..1efd587afd5 100644 --- a/examples/PlotImportanceSampler/main.cpp +++ b/examples/PlotImportanceSampler/main.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -15,32 +16,44 @@ int main( int /*argc*/, char** /*argv*/ ) { Random::MersenneTwisterGenerator generator = Random::MersenneTwisterGenerator(); std::vector uSamplesDir, cSamplesDir, bSamplesDir4, bSamplesDir16, bSamplesDir64, - bSamplesDir128; - // std::vector uSamplesPoint, cSamplesPoint, bSamplesPoint, lbSamplesPoint, - // bpSamplesPoint; + bSamplesDir128, bpmat, lambmat; + + Material::BlinnPhongMaterialModel bpmaterial = Material::BlinnPhongMaterialModel(); for ( int i = 0; i < 500; i++ ) { - uSamplesDir.push_back( Random::UniformSphereSampler::getDir( &generator ).first ); - cSamplesDir.push_back( Random::CosineWeightedSphereSampler::getDir( &generator ).first ); - bSamplesDir4.push_back( Random::BlinnPhongSphereSampler::getDir( &generator, 4 ).first ); - bSamplesDir16.push_back( Random::BlinnPhongSphereSampler::getDir( &generator, 16 ).first ); - bSamplesDir64.push_back( Random::BlinnPhongSphereSampler::getDir( &generator, 64 ).first ); - bSamplesDir128.push_back( - Random::BlinnPhongSphereSampler::getDir( &generator, 128 ).first ); - - // uSamplesPoint.push_back( Random::UniformSphereSampler::getPoint( &generator ).first ); - // cSamplesPoint.push_back( - // Random::CosineWeightedSphereSampler::getPoint( &generator ).first ); - // bSamplesPoint.push_back( Random::BlinnPhongSphereSampler::getPoint( &generator, 0.7 - // ).first ); + // uSamplesDir.push_back( Random::UniformSphereSampler::getDir( &generator ).first ); + // cSamplesDir.push_back( Random::CosineWeightedSphereSampler::getDir( &generator ).first ); + // bSamplesDir4.push_back( Random::BlinnPhongSphereSampler::getDir( &generator, 4 ).first ); + // bSamplesDir16.push_back( Random::BlinnPhongSphereSampler::getDir( &generator, 16 ).first + // ); bSamplesDir64.push_back( Random::BlinnPhongSphereSampler::getDir( &generator, 64 + // ).first ); bSamplesDir128.push_back( + // Random::BlinnPhongSphereSampler::getDir( &generator, 128 ).first ); + + bpmaterial.m_ns = 4; + auto sample = + bpmaterial.sample( { -1, 0, 1 }, { 0, 0, 1 }, { 0, 1, 0 }, { 1, 0, 0 }, { 0, 0 } ); + if ( sample.has_value() ) bSamplesDir4.push_back( sample.value().first ); + + bpmaterial.m_ns = 16; + sample = bpmaterial.sample( { -1, 0, 1 }, { 0, 0, 1 }, { 0, 1, 0 }, { 1, 0, 0 }, { 0, 0 } ); + if ( sample.has_value() ) bSamplesDir16.push_back( sample.value().first ); + + bpmaterial.m_ns = 64; + sample = bpmaterial.sample( { -1, 0, 1 }, { 0, 0, 1 }, { 0, 1, 0 }, { 1, 0, 0 }, { 0, 0 } ); + if ( sample.has_value() ) bSamplesDir64.push_back( sample.value().first ); + + bpmaterial.m_ns = 128; + sample = bpmaterial.sample( { -1, 0, 1 }, { 0, 0, 1 }, { 0, 1, 0 }, { 1, 0, 0 }, { 0, 0 } ); + if ( sample.has_value() ) bSamplesDir128.push_back( sample.value().first ); } - json j = { { "UniformSampleDir", uSamplesDir }, - { "CosineWeightedSampleDir", cSamplesDir }, + json j = { //{ "UniformSampleDir", uSamplesDir }, + //{ "CosineWeightedSampleDir", cSamplesDir }, { "BlinnPhongSampleDir 4", bSamplesDir4 }, { "BlinnPhongSampleDir 16", bSamplesDir16 }, { "BlinnPhongSampleDir 64", bSamplesDir64 }, { "BlinnPhongSampleDir 128", bSamplesDir128 } }; + // {"BlinnPhongMaterial", bpmat}}; // { "UniformSamplePoint", uSamplesPoint }, // { "CosineWeightedSamplePoint", cSamplesPoint }, // { "BlinnPhongSamplePoint", bSamplesPoint } From 1f6aca9085d90cc56e00d4bd18d50fdcbd7f8f75 Mon Sep 17 00:00:00 2001 From: grandch Date: Tue, 25 Jul 2023 16:09:03 +0200 Subject: [PATCH 32/56] remove getRoughness method --- src/Core/Material/BlinnPhongMaterialModel.cpp | 7 ------- src/Core/Material/BlinnPhongMaterialModel.hpp | 2 -- 2 files changed, 9 deletions(-) diff --git a/src/Core/Material/BlinnPhongMaterialModel.cpp b/src/Core/Material/BlinnPhongMaterialModel.cpp index 06d2dc0b4c1..19c687dd944 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.cpp +++ b/src/Core/Material/BlinnPhongMaterialModel.cpp @@ -100,13 +100,6 @@ Scalar BlinnPhongMaterialModel::PDF( Vector3 inDir, Vector3 outDir, Vector3 norm 1_ra ); } -Scalar BlinnPhongMaterialModel::getRoughness() { - Scalar ns = m_ns; - if ( ns > 1 ) { ns /= 128_ra; } - Scalar r = std::clamp( 1 - ns, 0.04_ra, 0.96_ra ); - return 1 - m_ns; -} - } // namespace Material } // namespace Core } // namespace Ra diff --git a/src/Core/Material/BlinnPhongMaterialModel.hpp b/src/Core/Material/BlinnPhongMaterialModel.hpp index b26468ee5f3..669f1e11d2d 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.hpp +++ b/src/Core/Material/BlinnPhongMaterialModel.hpp @@ -40,8 +40,6 @@ class RA_CORE_API BlinnPhongMaterialModel : public SimpleMaterialModel sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent, Vector2 u ) override; Scalar PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) override; - Scalar getRoughness(); - /// DATA MEMBERS Core::Utils::Color m_kd { 0.7_ra, 0.7_ra, 0.7_ra }; Core::Utils::Color m_ks { 0.3_ra, 0.3_ra, 0.3_ra }; From 714e748657197abdfff57974867590a0adcd37dc Mon Sep 17 00:00:00 2001 From: grandch Date: Tue, 25 Jul 2023 16:22:50 +0200 Subject: [PATCH 33/56] remove redundant field from blinnphongmaterialmodel --- src/Core/Material/BlinnPhongMaterialModel.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Core/Material/BlinnPhongMaterialModel.hpp b/src/Core/Material/BlinnPhongMaterialModel.hpp index 669f1e11d2d..a96a5949cb8 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.hpp +++ b/src/Core/Material/BlinnPhongMaterialModel.hpp @@ -41,7 +41,6 @@ class RA_CORE_API BlinnPhongMaterialModel : public SimpleMaterialModel Scalar PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) override; /// DATA MEMBERS - Core::Utils::Color m_kd { 0.7_ra, 0.7_ra, 0.7_ra }; Core::Utils::Color m_ks { 0.3_ra, 0.3_ra, 0.3_ra }; Scalar m_ns { 64_ra }; std::string m_texSpecular; From 670adaae9ae761463ce75229d9845e3e9ee91e9e Mon Sep 17 00:00:00 2001 From: grandch Date: Tue, 25 Jul 2023 17:49:25 +0200 Subject: [PATCH 34/56] precomputed luminance --- src/Core/Material/BlinnPhongMaterialModel.cpp | 31 +++--------- src/Core/Material/BlinnPhongMaterialModel.hpp | 49 ++++++++++++++++++- 2 files changed, 56 insertions(+), 24 deletions(-) diff --git a/src/Core/Material/BlinnPhongMaterialModel.cpp b/src/Core/Material/BlinnPhongMaterialModel.cpp index 19c687dd944..0a507ee34c1 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.cpp +++ b/src/Core/Material/BlinnPhongMaterialModel.cpp @@ -52,18 +52,10 @@ std::optional> BlinnPhongMaterialModel::sample( Vecto Vector2 u ) { Vector3 halfway; - Vector3 rgbToLuminance { 0.2126_ra, 0.7152_ra, 0.0722_ra }; - Scalar dIntensity = m_kd.rgb().dot( rgbToLuminance ); - Scalar sIntensity = m_ks.rgb().dot( rgbToLuminance ); - Scalar diffSpecNorm = std::max( 1_ra, dIntensity + sIntensity ); - - dIntensity /= diffSpecNorm; - sIntensity /= diffSpecNorm; - Scalar distrib = m_generator->get1D(); // diffuse part - if ( distrib < dIntensity ) { + if ( distrib < m_diffuseLuminance ) { std::pair smpl = Core::Random::CosineWeightedSphereSampler::getDir( m_generator ); Vector3 wi( @@ -71,7 +63,7 @@ std::optional> BlinnPhongMaterialModel::sample( Vecto std::pair result { wi, smpl.second }; return result; } - else if ( distrib < dIntensity + sIntensity ) { // specular part + else if ( distrib < m_diffuseLuminance + m_specularLuminance ) { // specular part std::pair smpl = Core::Random::BlinnPhongSphereSampler::getDir( m_generator, m_ns ); Vector3 wi( @@ -85,19 +77,12 @@ std::optional> BlinnPhongMaterialModel::sample( Vecto } Scalar BlinnPhongMaterialModel::PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) { - Vector3 rgbToLuminance { 0.2126_ra, 0.7152_ra, 0.0722_ra }; - Scalar dIntensity = m_kd.rgb().dot( rgbToLuminance ); - Scalar sIntensity = m_ks.rgb().dot( rgbToLuminance ); - Scalar diffSpecNorm = std::max( 1_ra, dIntensity + sIntensity ); - - dIntensity /= diffSpecNorm; - sIntensity /= diffSpecNorm; - - return std::clamp( - dIntensity * Core::Random::CosineWeightedSphereSampler::pdf( outDir, normal ) + - sIntensity * Core::Random::BlinnPhongSphereSampler::pdf( outDir, normal, m_ns ), - 0_ra, - 1_ra ); + return std::clamp( m_diffuseLuminance * + Core::Random::CosineWeightedSphereSampler::pdf( outDir, normal ) + + m_specularLuminance * + Core::Random::BlinnPhongSphereSampler::pdf( outDir, normal, m_ns ), + 0_ra, + 1_ra ); } } // namespace Material diff --git a/src/Core/Material/BlinnPhongMaterialModel.hpp b/src/Core/Material/BlinnPhongMaterialModel.hpp index a96a5949cb8..b9f7029bb0e 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.hpp +++ b/src/Core/Material/BlinnPhongMaterialModel.hpp @@ -40,9 +40,56 @@ class RA_CORE_API BlinnPhongMaterialModel : public SimpleMaterialModel sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent, Vector2 u ) override; Scalar PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) override; - /// DATA MEMBERS + inline Utils::Color getSpecularColor() const { return m_ks; } + inline Scalar getShininess() const { return m_ns; } + inline Scalar getDiffuseLuminance() const { return m_diffuseLuminance; } + inline Scalar getSpecularLuminance() const { return m_specularLuminance; } + inline std::string getTexSpecular() const { return m_texSpecular; } + inline std::string getTexShininess() const { return m_texShininess; } + inline std::string getTexNormal() const { return m_texNormal; } + + inline void setDiffuseColor( Utils::Color color ) { + m_kd = color; + Vector3 rgbToLuminance { 0.2126_ra, 0.7152_ra, 0.0722_ra }; + Scalar dIntensity = m_kd.rgb().dot( rgbToLuminance ); + Scalar sIntensity = m_ks.rgb().dot( rgbToLuminance ); + Scalar diffSpecNorm = std::max( 1_ra, dIntensity + sIntensity ); + + m_diffuseLuminance /= diffSpecNorm; + m_specularLuminance /= diffSpecNorm; + m_alpha = color.alpha(); + } + + inline void setSpecularColor( Utils::Color color ) { + m_ks = color; + Vector3 rgbToLuminance { 0.2126_ra, 0.7152_ra, 0.0722_ra }; + Scalar dIntensity = m_kd.rgb().dot( rgbToLuminance ); + Scalar sIntensity = m_ks.rgb().dot( rgbToLuminance ); + Scalar diffSpecNorm = std::max( 1_ra, dIntensity + sIntensity ); + + m_diffuseLuminance /= diffSpecNorm; + m_specularLuminance /= diffSpecNorm; + } + + inline void setShininess( Scalar specular ) { m_ns = specular; } + inline void setTexSpecular( std::string texSpecular ) { + m_texSpecular = texSpecular; + m_hasTexSpecular = true; + } + inline void setTexShininess( std::string texShininess ) { + m_texShininess = texShininess; + m_hasTexShininess = true; + } + inline void setTexNormal( std::string texNormal ) { + m_texNormal = texNormal; + m_hasTexNormal = true; + } + + private: Core::Utils::Color m_ks { 0.3_ra, 0.3_ra, 0.3_ra }; Scalar m_ns { 64_ra }; + Scalar m_diffuseLuminance; + Scalar m_specularLuminance; std::string m_texSpecular; std::string m_texShininess; std::string m_texNormal; From 443bd9b1244d1329394181c70f5e1393d4091111 Mon Sep 17 00:00:00 2001 From: grandch Date: Tue, 25 Jul 2023 17:50:00 +0200 Subject: [PATCH 35/56] private and protected fields --- src/Core/Material/SimpleMaterialModel.hpp | 32 ++++++++++++- src/Engine/Data/BlinnPhongMaterial.cpp | 20 ++++---- src/Engine/Data/LambertianMaterial.cpp | 10 ++-- src/Engine/Data/PlainMaterial.cpp | 8 ++-- .../AssimpLoader/AssimpGeometryDataLoader.cpp | 48 +++++++------------ 5 files changed, 68 insertions(+), 50 deletions(-) diff --git a/src/Core/Material/SimpleMaterialModel.hpp b/src/Core/Material/SimpleMaterialModel.hpp index ee3da5a69a7..06ae546c1ee 100644 --- a/src/Core/Material/SimpleMaterialModel.hpp +++ b/src/Core/Material/SimpleMaterialModel.hpp @@ -40,7 +40,29 @@ class RA_CORE_API SimpleMaterialModel : public MaterialModel sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent, Vector2 u ) override; Scalar PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) override; - /// DATA MEMBERS + inline Utils::Color getDiffuseColor() const { return m_kd; } + inline Scalar getAlpha() const { return m_alpha; } + inline std::string getTexDiffuse() const { return m_texDiffuse; } + inline std::string getTexOpacity() const { return m_texOpacity; } + + inline void setDiffuseColor( Utils::Color color ) { + m_kd = color; + m_alpha = color.alpha(); + } + inline void setAlpha( Scalar alpha ) { + m_alpha = alpha; + m_kd[3] = alpha; + } + inline void setTexDiffuse( std::string texDiffuse ) { + m_texDiffuse = texDiffuse; + m_hasTexDiffuse = true; + } + inline void setTexOpacity( std::string texOpacity ) { + m_texOpacity = texOpacity; + m_hasTexOpacity = true; + } + + protected: Core::Utils::Color m_kd { 0.9_ra, 0.9_ra, 0.9_ra }; Scalar m_alpha { 1_ra }; std::string m_texDiffuse; @@ -74,7 +96,13 @@ class RA_CORE_API LambertianMaterialModel : public SimpleMaterialModel sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent, Vector2 u ) override; Scalar PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) override; - /// DATA MEMBERS + inline std::string getTexNormal() const { return m_texNormal; } + inline void setTexNormal( std::string texNormal ) { + m_texNormal = texNormal; + m_hasTexNormal = true; + } + + private: std::string m_texNormal; bool m_hasTexNormal { false }; }; diff --git a/src/Engine/Data/BlinnPhongMaterial.cpp b/src/Engine/Data/BlinnPhongMaterial.cpp index 126773a09ce..a905ce8483c 100644 --- a/src/Engine/Data/BlinnPhongMaterial.cpp +++ b/src/Engine/Data/BlinnPhongMaterial.cpp @@ -154,23 +154,25 @@ BlinnPhongMaterialConverter::operator()( const Ra::Core::Material::MaterialModel // static cst is safe here auto source = static_cast( toconvert ); - result->m_kd = source->m_kd; - result->m_ks = source->m_ks; - result->m_ns = source->m_ns; - result->m_alpha = source->m_alpha; + result->m_kd = source->getDiffuseColor(); + result->m_ks = source->getSpecularColor(); + result->m_ns = source->getShininess(); + result->m_alpha = source->getAlpha(); if ( source->hasDiffuseTexture() ) result->addTexture( BlinnPhongMaterial::TextureSemantic::TEX_DIFFUSE, - source->m_texDiffuse ); + source->getTexDiffuse() ); if ( source->hasSpecularTexture() ) result->addTexture( BlinnPhongMaterial::TextureSemantic::TEX_SPECULAR, - source->m_texSpecular ); + source->getTexSpecular() ); if ( source->hasShininessTexture() ) result->addTexture( BlinnPhongMaterial::TextureSemantic::TEX_SHININESS, - source->m_texShininess ); + source->getTexShininess() ); if ( source->hasOpacityTexture() ) - result->addTexture( BlinnPhongMaterial::TextureSemantic::TEX_ALPHA, source->m_texOpacity ); + result->addTexture( BlinnPhongMaterial::TextureSemantic::TEX_ALPHA, + source->getTexOpacity() ); if ( source->hasNormalTexture() ) - result->addTexture( BlinnPhongMaterial::TextureSemantic::TEX_NORMAL, source->m_texNormal ); + result->addTexture( BlinnPhongMaterial::TextureSemantic::TEX_NORMAL, + source->getTexNormal() ); return result; } diff --git a/src/Engine/Data/LambertianMaterial.cpp b/src/Engine/Data/LambertianMaterial.cpp index 3cd8a0e4d5f..6737e29344b 100644 --- a/src/Engine/Data/LambertianMaterial.cpp +++ b/src/Engine/Data/LambertianMaterial.cpp @@ -82,15 +82,15 @@ LambertianMaterialConverter::operator()( const Ra::Core::Material::MaterialModel // static cst is safe here auto source = static_cast( toconvert ); - result->m_color = source->m_kd; - result->m_alpha = source->m_alpha; + result->m_color = source->getDiffuseColor(); + result->m_alpha = source->getAlpha(); if ( source->hasDiffuseTexture() ) - result->addTexture( SimpleMaterial::TextureSemantic::TEX_COLOR, source->m_texDiffuse ); + result->addTexture( SimpleMaterial::TextureSemantic::TEX_COLOR, source->getTexDiffuse() ); if ( source->hasOpacityTexture() ) - result->addTexture( SimpleMaterial::TextureSemantic::TEX_MASK, source->m_texOpacity ); + result->addTexture( SimpleMaterial::TextureSemantic::TEX_MASK, source->getTexOpacity() ); if ( source->hasNormalTexture() ) - result->addTexture( SimpleMaterial::TextureSemantic::TEX_NORMAL, source->m_texNormal ); + result->addTexture( SimpleMaterial::TextureSemantic::TEX_NORMAL, source->getTexNormal() ); return result; } diff --git a/src/Engine/Data/PlainMaterial.cpp b/src/Engine/Data/PlainMaterial.cpp index c7c7b26d58e..a691a0cd2a3 100644 --- a/src/Engine/Data/PlainMaterial.cpp +++ b/src/Engine/Data/PlainMaterial.cpp @@ -81,13 +81,13 @@ Material* PlainMaterialConverter::operator()( const Ra::Core::Material::Material // static cst is safe here auto source = static_cast( toconvert ); - result->m_color = source->m_kd; - result->m_alpha = source->m_alpha; + result->m_color = source->getDiffuseColor(); + result->m_alpha = source->getAlpha(); if ( source->hasDiffuseTexture() ) - result->addTexture( SimpleMaterial::TextureSemantic::TEX_COLOR, source->m_texDiffuse ); + result->addTexture( SimpleMaterial::TextureSemantic::TEX_COLOR, source->getTexDiffuse() ); if ( source->hasOpacityTexture() ) - result->addTexture( SimpleMaterial::TextureSemantic::TEX_MASK, source->m_texOpacity ); + result->addTexture( SimpleMaterial::TextureSemantic::TEX_MASK, source->getTexOpacity() ); return result; } diff --git a/src/IO/AssimpLoader/AssimpGeometryDataLoader.cpp b/src/IO/AssimpLoader/AssimpGeometryDataLoader.cpp index 74e3b7dced7..375fe651c82 100644 --- a/src/IO/AssimpLoader/AssimpGeometryDataLoader.cpp +++ b/src/IO/AssimpLoader/AssimpGeometryDataLoader.cpp @@ -237,17 +237,15 @@ void AssimpGeometryDataLoader::loadMaterial( const aiMaterial& material, aiColor4D color; aiString name; if ( AI_SUCCESS == material.Get( AI_MATKEY_COLOR_DIFFUSE, color ) ) { - plainMaterial->m_kd = assimpToCore( color ); + plainMaterial->setDiffuseColor( assimpToCore( color ) ); } if ( AI_SUCCESS == material.Get( AI_MATKEY_TEXTURE( aiTextureType_DIFFUSE, 0 ), name ) ) { - plainMaterial->m_texDiffuse = m_filepath + "/" + assimpToCore( name ); - plainMaterial->m_hasTexDiffuse = true; + plainMaterial->setTexDiffuse( m_filepath + "/" + assimpToCore( name ) ); } if ( AI_SUCCESS == material.Get( AI_MATKEY_TEXTURE( aiTextureType_OPACITY, 0 ), name ) ) { - plainMaterial->m_texOpacity = m_filepath + "/" + assimpToCore( name ); - plainMaterial->m_hasTexOpacity = true; + plainMaterial->setTexOpacity( m_filepath + "/" + assimpToCore( name ) ); } } break; @@ -259,28 +257,24 @@ void AssimpGeometryDataLoader::loadMaterial( const aiMaterial& material, aiColor4D color; aiString name; if ( AI_SUCCESS == material.Get( AI_MATKEY_COLOR_DIFFUSE, color ) ) { - lambertianMaterial->m_kd = assimpToCore( color ); + lambertianMaterial->setDiffuseColor( assimpToCore( color ) ); } if ( AI_SUCCESS == material.Get( AI_MATKEY_TEXTURE( aiTextureType_DIFFUSE, 0 ), name ) ) { - lambertianMaterial->m_texDiffuse = m_filepath + "/" + assimpToCore( name ); - lambertianMaterial->m_hasTexDiffuse = true; + lambertianMaterial->setTexDiffuse( m_filepath + "/" + assimpToCore( name ) ); } if ( AI_SUCCESS == material.Get( AI_MATKEY_TEXTURE( aiTextureType_OPACITY, 0 ), name ) ) { - lambertianMaterial->m_texOpacity = m_filepath + "/" + assimpToCore( name ); - lambertianMaterial->m_hasTexOpacity = true; + lambertianMaterial->setTexOpacity( m_filepath + "/" + assimpToCore( name ) ); } if ( AI_SUCCESS == material.Get( AI_MATKEY_TEXTURE( aiTextureType_NORMALS, 0 ), name ) ) { - lambertianMaterial->m_texNormal = m_filepath + "/" + assimpToCore( name ); - lambertianMaterial->m_hasTexNormal = true; + lambertianMaterial->setTexNormal( m_filepath + "/" + assimpToCore( name ) ); } // Assimp loads objs bump maps as height maps, gj bro if ( AI_SUCCESS == material.Get( AI_MATKEY_TEXTURE( aiTextureType_HEIGHT, 0 ), name ) ) { - lambertianMaterial->m_texNormal = m_filepath + "/" + assimpToCore( name ); - lambertianMaterial->m_hasTexNormal = true; + lambertianMaterial->setTexNormal( m_filepath + "/" + assimpToCore( name ) ); } } break; @@ -296,60 +290,54 @@ void AssimpGeometryDataLoader::loadMaterial( const aiMaterial& material, aiString name; if ( AI_SUCCESS == material.Get( AI_MATKEY_COLOR_DIFFUSE, color ) ) { - blinnPhongMaterial->m_kd = assimpToCore( color ); + blinnPhongMaterial->setDiffuseColor( assimpToCore( color ) ); } if ( AI_SUCCESS == material.Get( AI_MATKEY_COLOR_SPECULAR, color ) ) { - blinnPhongMaterial->m_ks = assimpToCore( color ); + blinnPhongMaterial->setSpecularColor( assimpToCore( color ) ); } if ( AI_SUCCESS == material.Get( AI_MATKEY_SHININESS, shininess ) ) { // Assimp gives the Phong exponent, we use the Blinn-Phong exponent - blinnPhongMaterial->m_ns = shininess * 4; + blinnPhongMaterial->setShininess( shininess * 4 ); } if ( AI_SUCCESS == material.Get( AI_MATKEY_OPACITY, opacity ) ) { // NOTE(charly): Due to collada way of handling objects that have an alpha map, we // must ensure // we do not have zeros in here. - blinnPhongMaterial->m_alpha = opacity < 1e-5 ? 1 : opacity; + blinnPhongMaterial->setAlpha( opacity < 1e-5 ? 1 : opacity ); } if ( AI_SUCCESS == material.Get( AI_MATKEY_TEXTURE( aiTextureType_DIFFUSE, 0 ), name ) ) { - blinnPhongMaterial->m_texDiffuse = m_filepath + "/" + assimpToCore( name ); - blinnPhongMaterial->m_hasTexDiffuse = true; + blinnPhongMaterial->setTexDiffuse( m_filepath + "/" + assimpToCore( name ) ); } if ( AI_SUCCESS == material.Get( AI_MATKEY_TEXTURE( aiTextureType_SPECULAR, 0 ), name ) ) { - blinnPhongMaterial->m_texSpecular = m_filepath + "/" + assimpToCore( name ); - blinnPhongMaterial->m_hasTexSpecular = true; + blinnPhongMaterial->setTexSpecular( m_filepath + "/" + assimpToCore( name ) ); } if ( AI_SUCCESS == material.Get( AI_MATKEY_TEXTURE( aiTextureType_SHININESS, 0 ), name ) ) { - blinnPhongMaterial->m_texShininess = m_filepath + "/" + assimpToCore( name ); - blinnPhongMaterial->m_hasTexShininess = true; + blinnPhongMaterial->setTexShininess( m_filepath + "/" + assimpToCore( name ) ); } if ( AI_SUCCESS == material.Get( AI_MATKEY_TEXTURE( aiTextureType_NORMALS, 0 ), name ) ) { - blinnPhongMaterial->m_texNormal = m_filepath + "/" + assimpToCore( name ); - blinnPhongMaterial->m_hasTexNormal = true; + blinnPhongMaterial->setTexNormal( m_filepath + "/" + assimpToCore( name ) ); } // Assimp loads objs bump maps as height maps, gj bro if ( AI_SUCCESS == material.Get( AI_MATKEY_TEXTURE( aiTextureType_HEIGHT, 0 ), name ) ) { - blinnPhongMaterial->m_texNormal = m_filepath + "/" + assimpToCore( name ); - blinnPhongMaterial->m_hasTexNormal = true; + blinnPhongMaterial->setTexNormal( m_filepath + "/" + assimpToCore( name ) ); } if ( AI_SUCCESS == material.Get( AI_MATKEY_TEXTURE( aiTextureType_OPACITY, 0 ), name ) ) { - blinnPhongMaterial->m_texOpacity = m_filepath + "/" + assimpToCore( name ); - blinnPhongMaterial->m_hasTexOpacity = true; + blinnPhongMaterial->setTexOpacity( m_filepath + "/" + assimpToCore( name ) ); } } } From 7f90533a2d442308f42c1395906922c3e90b7bcf Mon Sep 17 00:00:00 2001 From: grandch Date: Tue, 25 Jul 2023 18:02:51 +0200 Subject: [PATCH 36/56] modify constructors* --- src/Core/Material/BlinnPhongMaterialModel.hpp | 4 ++-- src/Core/Material/SimpleMaterialModel.hpp | 16 ++++++---------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/Core/Material/BlinnPhongMaterialModel.hpp b/src/Core/Material/BlinnPhongMaterialModel.hpp index b9f7029bb0e..4644f912ffd 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.hpp +++ b/src/Core/Material/BlinnPhongMaterialModel.hpp @@ -18,8 +18,8 @@ class RA_CORE_API BlinnPhongMaterialModel : public SimpleMaterialModel explicit BlinnPhongMaterialModel( const std::string& name = "" ) : SimpleMaterialModel( name, "BlinnPhong" ) {} - explicit BlinnPhongMaterialModel( Core::Random::UniformGenerator* generator, - const std::string& name = "" ) : + explicit BlinnPhongMaterialModel( const std::string& name = "", + std::shared_ptr generator ) : SimpleMaterialModel( name, "BlinnPhong", generator ) {} ~BlinnPhongMaterialModel() override = default; diff --git a/src/Core/Material/SimpleMaterialModel.hpp b/src/Core/Material/SimpleMaterialModel.hpp index 06ae546c1ee..625be61a170 100644 --- a/src/Core/Material/SimpleMaterialModel.hpp +++ b/src/Core/Material/SimpleMaterialModel.hpp @@ -14,15 +14,11 @@ namespace Material { class RA_CORE_API SimpleMaterialModel : public MaterialModel { protected: - SimpleMaterialModel( const std::string& name, const std::string type ) : - m_generator( new Core::Random::MersenneTwisterGenerator() ), MaterialModel( name, type ) {} - SimpleMaterialModel( const std::string& name, const std::string type, - Core::Random::UniformGenerator* generator ) : - MaterialModel( name, type ) { - *m_generator = *generator; - } + std::shared_ptr generator = + std::make_shared() ) : + MaterialModel( name, type ), m_generator = std::move( generator ) {} public: explicit SimpleMaterialModel( const std::string& name = "" ) : MaterialModel( name, "Plain" ) {} @@ -70,7 +66,7 @@ class RA_CORE_API SimpleMaterialModel : public MaterialModel bool m_hasTexDiffuse { false }; bool m_hasTexOpacity { false }; - Core::Random::UniformGenerator* m_generator; + std::shared_ptr m_generator; }; class RA_CORE_API LambertianMaterialModel : public SimpleMaterialModel @@ -79,8 +75,8 @@ class RA_CORE_API LambertianMaterialModel : public SimpleMaterialModel explicit LambertianMaterialModel( const std::string& name = "" ) : SimpleMaterialModel( name, "Lambertian" ) {} - explicit LambertianMaterialModel( Core::Random::UniformGenerator* generator, - const std::string& name = "" ) : + explicit LambertianMaterialModel( const std::string& name = "", + std::shared_ptr generator ) : SimpleMaterialModel( name, "Lambertian", generator ) {} ~LambertianMaterialModel() override = default; From 5cec94ae1c9dbde15c7ca36fc9794c46c87bba0d Mon Sep 17 00:00:00 2001 From: grandch Date: Tue, 25 Jul 2023 18:22:34 +0200 Subject: [PATCH 37/56] store random generator with shared_ptr --- src/Core/Material/BlinnPhongMaterialModel.cpp | 6 +++--- src/Core/Material/BlinnPhongMaterialModel.hpp | 9 ++++----- src/Core/Material/SimpleMaterialModel.cpp | 2 +- src/Core/Material/SimpleMaterialModel.hpp | 13 ++++++------- 4 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/Core/Material/BlinnPhongMaterialModel.cpp b/src/Core/Material/BlinnPhongMaterialModel.cpp index 0a507ee34c1..766a1595633 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.cpp +++ b/src/Core/Material/BlinnPhongMaterialModel.cpp @@ -52,12 +52,12 @@ std::optional> BlinnPhongMaterialModel::sample( Vecto Vector2 u ) { Vector3 halfway; - Scalar distrib = m_generator->get1D(); + Scalar distrib = m_generator.get()->get1D(); // diffuse part if ( distrib < m_diffuseLuminance ) { std::pair smpl = - Core::Random::CosineWeightedSphereSampler::getDir( m_generator ); + Core::Random::CosineWeightedSphereSampler::getDir( m_generator.get() ); Vector3 wi( smpl.first.dot( tangent ), smpl.first.dot( bitangent ), smpl.first.dot( normal ) ); std::pair result { wi, smpl.second }; @@ -65,7 +65,7 @@ std::optional> BlinnPhongMaterialModel::sample( Vecto } else if ( distrib < m_diffuseLuminance + m_specularLuminance ) { // specular part std::pair smpl = - Core::Random::BlinnPhongSphereSampler::getDir( m_generator, m_ns ); + Core::Random::BlinnPhongSphereSampler::getDir( m_generator.get(), m_ns ); Vector3 wi( smpl.first.dot( tangent ), smpl.first.dot( bitangent ), smpl.first.dot( normal ) ); std::pair result { wi, smpl.second }; diff --git a/src/Core/Material/BlinnPhongMaterialModel.hpp b/src/Core/Material/BlinnPhongMaterialModel.hpp index 4644f912ffd..63157c50a01 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.hpp +++ b/src/Core/Material/BlinnPhongMaterialModel.hpp @@ -15,11 +15,10 @@ namespace Material { class RA_CORE_API BlinnPhongMaterialModel : public SimpleMaterialModel { public: - explicit BlinnPhongMaterialModel( const std::string& name = "" ) : - SimpleMaterialModel( name, "BlinnPhong" ) {} - - explicit BlinnPhongMaterialModel( const std::string& name = "", - std::shared_ptr generator ) : + explicit BlinnPhongMaterialModel( + const std::string& name = "", + std::shared_ptr generator = + std::make_shared() ) : SimpleMaterialModel( name, "BlinnPhong", generator ) {} ~BlinnPhongMaterialModel() override = default; diff --git a/src/Core/Material/SimpleMaterialModel.cpp b/src/Core/Material/SimpleMaterialModel.cpp index db2072e5c99..65d28d7f3cd 100644 --- a/src/Core/Material/SimpleMaterialModel.cpp +++ b/src/Core/Material/SimpleMaterialModel.cpp @@ -67,7 +67,7 @@ std::optional> LambertianMaterialModel::sample( Vecto Vector2 u ) { // sample point on hemisphere with cosine-weighted distribution std::pair smpl = - Core::Random::CosineWeightedSphereSampler::getDir( m_generator ); + Core::Random::CosineWeightedSphereSampler::getDir( m_generator.get() ); // transform sampled point from local to world coodinate system Vector3 wi( smpl.first.dot( tangent ), smpl.first.dot( bitangent ), smpl.first.dot( normal ) ); diff --git a/src/Core/Material/SimpleMaterialModel.hpp b/src/Core/Material/SimpleMaterialModel.hpp index 625be61a170..f3740f127ad 100644 --- a/src/Core/Material/SimpleMaterialModel.hpp +++ b/src/Core/Material/SimpleMaterialModel.hpp @@ -17,8 +17,8 @@ class RA_CORE_API SimpleMaterialModel : public MaterialModel SimpleMaterialModel( const std::string& name, const std::string type, std::shared_ptr generator = - std::make_shared() ) : - MaterialModel( name, type ), m_generator = std::move( generator ) {} + std::make_shared() ) : + MaterialModel( name, type ), m_generator( std::move( generator ) ) {} public: explicit SimpleMaterialModel( const std::string& name = "" ) : MaterialModel( name, "Plain" ) {} @@ -72,11 +72,10 @@ class RA_CORE_API SimpleMaterialModel : public MaterialModel class RA_CORE_API LambertianMaterialModel : public SimpleMaterialModel { public: - explicit LambertianMaterialModel( const std::string& name = "" ) : - SimpleMaterialModel( name, "Lambertian" ) {} - - explicit LambertianMaterialModel( const std::string& name = "", - std::shared_ptr generator ) : + explicit LambertianMaterialModel( + const std::string& name = "", + std::shared_ptr generator = + std::make_shared() ) : SimpleMaterialModel( name, "Lambertian", generator ) {} ~LambertianMaterialModel() override = default; From d20b9f2a4fe9d7c87004fbea405e17e4f36eb177 Mon Sep 17 00:00:00 2001 From: grandch Date: Wed, 26 Jul 2023 11:25:03 +0200 Subject: [PATCH 38/56] remove spherical coordinate based methods --- src/Core/Random/BlinnPhongSphereSampler.cpp | 12 ------------ src/Core/Random/BlinnPhongSphereSampler.hpp | 2 -- src/Core/Random/CosineWeightedSphereSampler.cpp | 10 ---------- src/Core/Random/CosineWeightedSphereSampler.hpp | 2 -- src/Core/Random/SphereSampler.hpp | 4 ---- src/Core/Random/UniformSphereSampler.cpp | 10 ---------- src/Core/Random/UniformSphereSampler.hpp | 2 -- 7 files changed, 42 deletions(-) diff --git a/src/Core/Random/BlinnPhongSphereSampler.cpp b/src/Core/Random/BlinnPhongSphereSampler.cpp index 47e394bd562..82a12f7ae32 100644 --- a/src/Core/Random/BlinnPhongSphereSampler.cpp +++ b/src/Core/Random/BlinnPhongSphereSampler.cpp @@ -6,14 +6,6 @@ namespace Ra { namespace Core { namespace Random { -std::pair -Ra::Core::Random::BlinnPhongSphereSampler::getPoint( UniformGenerator* generator, - Scalar roughness ) { - Vector2 u = generator->get2D(); - return { { std::pow( u[0], 1_ra / ( roughness + 2 ) ), 2 * Math::Pi * u[1] }, - ( roughness + 2 ) * std::pow( u[0], roughness ) / ( 2 * Math::Pi ) }; -} - std::pair Ra::Core::Random::BlinnPhongSphereSampler::getDir( UniformGenerator* generator, Scalar roughness ) { Vector3 dir; @@ -35,10 +27,6 @@ Scalar BlinnPhongSphereSampler::pdf( Vector3 dir, Vector3 normal, Scalar roughne return ( roughness + 2 ) * std::pow( dir.dot( normal ), roughness ) / ( 2 * Math::Pi ); } -Scalar BlinnPhongSphereSampler::pdf( Vector2 point, Scalar roughness ) { - return ( roughness + 2 ) * std::pow( point[0], roughness ) / ( 2 * Math::Pi ); -} - } // namespace Random } // namespace Core } // namespace Ra diff --git a/src/Core/Random/BlinnPhongSphereSampler.hpp b/src/Core/Random/BlinnPhongSphereSampler.hpp index 34bdf52b1d7..685e25c1b66 100644 --- a/src/Core/Random/BlinnPhongSphereSampler.hpp +++ b/src/Core/Random/BlinnPhongSphereSampler.hpp @@ -12,11 +12,9 @@ class RA_CORE_API BlinnPhongSphereSampler : public CosineWeightedSphereSampler BlinnPhongSphereSampler() {}; ~BlinnPhongSphereSampler() {}; - static std::pair getPoint( UniformGenerator* generator, Scalar roughness ); static std::pair getDir( UniformGenerator* generator, Scalar roughness ); static Scalar pdf( Vector3 dir, Vector3 normal, Scalar roughness ); - static Scalar pdf( Vector2 point, Scalar roughness ); }; } // namespace Random diff --git a/src/Core/Random/CosineWeightedSphereSampler.cpp b/src/Core/Random/CosineWeightedSphereSampler.cpp index f182f72059e..2bcb8a13ba2 100644 --- a/src/Core/Random/CosineWeightedSphereSampler.cpp +++ b/src/Core/Random/CosineWeightedSphereSampler.cpp @@ -6,12 +6,6 @@ namespace Ra { namespace Core { namespace Random { -std::pair -Ra::Core::Random::CosineWeightedSphereSampler::getPointImplem( UniformGenerator* generator ) { - Vector2 u = generator->get2D(); - return { { std::sqrt( u[0] ), 2 * Math::Pi * u[1] }, u[0] / Math::Pi }; -} - std::pair Ra::Core::Random::CosineWeightedSphereSampler::getDirImplem( UniformGenerator* generator ) { Vector3 dir; @@ -33,10 +27,6 @@ Scalar CosineWeightedSphereSampler::pdfImplem( Vector3 dir, Vector3 normal ) { return dir.dot( normal ) / Math::Pi; } -Scalar CosineWeightedSphereSampler::pdfImplem( Vector2 point ) { - return point[0] / Math::Pi; -} - } // namespace Random } // namespace Core } // namespace Ra diff --git a/src/Core/Random/CosineWeightedSphereSampler.hpp b/src/Core/Random/CosineWeightedSphereSampler.hpp index f9ac6d4582c..af475fc2629 100644 --- a/src/Core/Random/CosineWeightedSphereSampler.hpp +++ b/src/Core/Random/CosineWeightedSphereSampler.hpp @@ -12,11 +12,9 @@ class RA_CORE_API CosineWeightedSphereSampler : public SphereSampler getPointImplem( UniformGenerator* generator ); static std::pair getDirImplem( UniformGenerator* generator ); static Scalar pdfImplem( Vector3 dir, Vector3 normal ); - static Scalar pdfImplem( Vector2 point ); }; } // namespace Random diff --git a/src/Core/Random/SphereSampler.hpp b/src/Core/Random/SphereSampler.hpp index 8919e594aad..11930f2683f 100644 --- a/src/Core/Random/SphereSampler.hpp +++ b/src/Core/Random/SphereSampler.hpp @@ -14,15 +14,11 @@ class RA_CORE_API SphereSampler SphereSampler() {}; ~SphereSampler() {}; - static std::pair getPoint( UniformGenerator* generator ) { - return T::getPointImplem( generator ); - } static std::pair getDir( UniformGenerator* generator ) { return T::getDirImplem( generator ); } static Scalar pdf( Vector3 dir, Vector3 normal ) { return T::pdfImplem( dir, normal ); } - static Scalar pdf( Vector2 point ) { return T::pdfImplem( point ); } }; } // namespace Random diff --git a/src/Core/Random/UniformSphereSampler.cpp b/src/Core/Random/UniformSphereSampler.cpp index c04095ce17f..7823f900bad 100644 --- a/src/Core/Random/UniformSphereSampler.cpp +++ b/src/Core/Random/UniformSphereSampler.cpp @@ -6,12 +6,6 @@ namespace Ra { namespace Core { namespace Random { -std::pair -Ra::Core::Random::UniformSphereSampler::getPointImplem( UniformGenerator* generator ) { - Vector2 u = generator->get2D(); - return { { u[0], 2 * Math::Pi * u[1] }, 1 / ( 2 * Math::Pi ) }; -} - std::pair Ra::Core::Random::UniformSphereSampler::getDirImplem( UniformGenerator* generator ) { Vector3 dir; @@ -32,10 +26,6 @@ Scalar UniformSphereSampler::pdfImplem( Vector3 dir, Vector3 normal ) { return 1 / ( 2 * Math::Pi ); } -Scalar UniformSphereSampler::pdfImplem( Vector2 point ) { - return 1 / ( 2 * Math::Pi ); -} - } // namespace Random } // namespace Core } // namespace Ra diff --git a/src/Core/Random/UniformSphereSampler.hpp b/src/Core/Random/UniformSphereSampler.hpp index a96a7f0e053..0d767c9b7ad 100644 --- a/src/Core/Random/UniformSphereSampler.hpp +++ b/src/Core/Random/UniformSphereSampler.hpp @@ -12,11 +12,9 @@ class RA_CORE_API UniformSphereSampler : public SphereSampler getPointImplem( UniformGenerator* generator ); static std::pair getDirImplem( UniformGenerator* generator ); static Scalar pdfImplem( Vector3 dir, Vector3 normal ); - static Scalar pdfImplem( Vector2 point ); }; } // namespace Random From 6b79b652d3c42e42d72ce2b7283549baa006f966 Mon Sep 17 00:00:00 2001 From: grandch Date: Wed, 26 Jul 2023 11:46:11 +0200 Subject: [PATCH 39/56] modify names of methods --- src/Core/Material/BlinnPhongMaterialModel.cpp | 11 ++++++----- src/Core/Material/BlinnPhongMaterialModel.hpp | 4 ++-- src/Core/Material/MaterialModel.hpp | 4 ++-- src/Core/Material/SimpleMaterialModel.cpp | 15 ++++++++------- src/Core/Material/SimpleMaterialModel.hpp | 8 ++++---- 5 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/Core/Material/BlinnPhongMaterialModel.cpp b/src/Core/Material/BlinnPhongMaterialModel.cpp index 766a1595633..abc23b42353 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.cpp +++ b/src/Core/Material/BlinnPhongMaterialModel.cpp @@ -25,10 +25,11 @@ void BlinnPhongMaterialModel::displayInfo() const { print( hasNormalTexture(), " Normal Texture : ", m_texNormal ); print( hasOpacityTexture(), " Alpha Texture : ", m_texOpacity ); } -Utils::Color Material::BlinnPhongMaterialModel::evalBSDF( Vector3 w_i, - Vector3 w_o, - Vector3 normal, - Vector2 uv ) { + +Utils::Color Material::BlinnPhongMaterialModel::operator()( Vector3 w_i, + Vector3 w_o, + Vector3 normal, + Vector2 uv ) { // diffuse lambertien component Utils::Color diffuse = m_kd / M_PI; @@ -76,7 +77,7 @@ std::optional> BlinnPhongMaterialModel::sample( Vecto } } -Scalar BlinnPhongMaterialModel::PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) { +Scalar BlinnPhongMaterialModel::pdf( Vector3 inDir, Vector3 outDir, Vector3 normal ) { return std::clamp( m_diffuseLuminance * Core::Random::CosineWeightedSphereSampler::pdf( outDir, normal ) + m_specularLuminance * diff --git a/src/Core/Material/BlinnPhongMaterialModel.hpp b/src/Core/Material/BlinnPhongMaterialModel.hpp index 63157c50a01..1e098c8e895 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.hpp +++ b/src/Core/Material/BlinnPhongMaterialModel.hpp @@ -34,10 +34,10 @@ class RA_CORE_API BlinnPhongMaterialModel : public SimpleMaterialModel bool hasNormalTexture() const { return m_hasTexNormal; } - Utils::Color evalBSDF( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) override; + Utils::Color operator()( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) override; std::optional> sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent, Vector2 u ) override; - Scalar PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) override; + Scalar pdf( Vector3 inDir, Vector3 outDir, Vector3 normal ) override; inline Utils::Color getSpecularColor() const { return m_ks; } inline Scalar getShininess() const { return m_ns; } diff --git a/src/Core/Material/MaterialModel.hpp b/src/Core/Material/MaterialModel.hpp index 62b1548f095..5278d4df1f3 100644 --- a/src/Core/Material/MaterialModel.hpp +++ b/src/Core/Material/MaterialModel.hpp @@ -39,10 +39,10 @@ class RA_CORE_API MaterialModel : public Utils::ObservableVoid * w_i : incident direction, w_o : outgoing direction, normal : geometric normal direction. * w_i, w_o and normal are in world space. */ - virtual Utils::Color evalBSDF( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) = 0; + virtual Utils::Color operator()( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) = 0; virtual std::optional> sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent, Vector2 u ) = 0; - virtual Scalar PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) = 0; + virtual Scalar pdf( Vector3 inDir, Vector3 outDir, Vector3 normal ) = 0; private: std::string m_materialType; diff --git a/src/Core/Material/SimpleMaterialModel.cpp b/src/Core/Material/SimpleMaterialModel.cpp index 65d28d7f3cd..1facd59d3bf 100644 --- a/src/Core/Material/SimpleMaterialModel.cpp +++ b/src/Core/Material/SimpleMaterialModel.cpp @@ -21,7 +21,8 @@ void SimpleMaterialModel::displayInfo() const { print( hasOpacityTexture(), " Alpha Texture : ", m_texOpacity ); } -Utils::Color SimpleMaterialModel::evalBSDF( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) { +Utils::Color +SimpleMaterialModel::operator()( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) { return m_kd; } std::optional> SimpleMaterialModel::sample( Vector3 inDir, @@ -31,7 +32,7 @@ std::optional> SimpleMaterialModel::sample( Vector3 i Vector2 u ) { return {}; } -Scalar SimpleMaterialModel::PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) { +Scalar SimpleMaterialModel::pdf( Vector3 inDir, Vector3 outDir, Vector3 normal ) { return 0_ra; } @@ -51,10 +52,10 @@ void LambertianMaterialModel::displayInfo() const { print( hasOpacityTexture(), " Alpha Texture : ", m_texOpacity ); } -Utils::Color Material::LambertianMaterialModel::evalBSDF( Vector3 w_i, - Vector3 w_o, - Vector3 normal, - Vector2 uv ) { +Utils::Color Material::LambertianMaterialModel::operator()( Vector3 w_i, + Vector3 w_o, + Vector3 normal, + Vector2 uv ) { if ( w_i.dot( normal ) <= 0 || w_o.dot( normal ) <= 0 ) { return Utils::Color::Black(); } return m_kd / M_PI; @@ -76,7 +77,7 @@ std::optional> LambertianMaterialModel::sample( Vecto return result; } -Scalar LambertianMaterialModel::PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) { +Scalar LambertianMaterialModel::pdf( Vector3 inDir, Vector3 outDir, Vector3 normal ) { return Core::Random::CosineWeightedSphereSampler::pdf( outDir, normal ); } diff --git a/src/Core/Material/SimpleMaterialModel.hpp b/src/Core/Material/SimpleMaterialModel.hpp index f3740f127ad..5c3ecbdc7bd 100644 --- a/src/Core/Material/SimpleMaterialModel.hpp +++ b/src/Core/Material/SimpleMaterialModel.hpp @@ -31,10 +31,10 @@ class RA_CORE_API SimpleMaterialModel : public MaterialModel bool hasDiffuseTexture() const { return m_hasTexDiffuse; } bool hasOpacityTexture() const { return m_hasTexOpacity; } - Utils::Color evalBSDF( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) override; + Utils::Color operator()( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) override; std::optional> sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent, Vector2 u ) override; - Scalar PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) override; + Scalar pdf( Vector3 inDir, Vector3 outDir, Vector3 normal ) override; inline Utils::Color getDiffuseColor() const { return m_kd; } inline Scalar getAlpha() const { return m_alpha; } @@ -86,10 +86,10 @@ class RA_CORE_API LambertianMaterialModel : public SimpleMaterialModel /// QUERY bool hasNormalTexture() const { return m_hasTexNormal; } - Utils::Color evalBSDF( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) override; + Utils::Color operator()( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) override; std::optional> sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent, Vector2 u ) override; - Scalar PDF( Vector3 inDir, Vector3 outDir, Vector3 normal ) override; + Scalar pdf( Vector3 inDir, Vector3 outDir, Vector3 normal ) override; inline std::string getTexNormal() const { return m_texNormal; } inline void setTexNormal( std::string texNormal ) { From 6798fd3c94265acba8657a0a0f30c0971a13a46f Mon Sep 17 00:00:00 2001 From: grandch Date: Wed, 26 Jul 2023 12:13:36 +0200 Subject: [PATCH 40/56] add computeLuminance method --- src/Core/Material/BlinnPhongMaterialModel.cpp | 10 ++++++++++ src/Core/Material/BlinnPhongMaterialModel.hpp | 20 +++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Core/Material/BlinnPhongMaterialModel.cpp b/src/Core/Material/BlinnPhongMaterialModel.cpp index abc23b42353..bf9094b448a 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.cpp +++ b/src/Core/Material/BlinnPhongMaterialModel.cpp @@ -86,6 +86,16 @@ Scalar BlinnPhongMaterialModel::pdf( Vector3 inDir, Vector3 outDir, Vector3 norm 1_ra ); } +void BlinnPhongMaterialModel::computeLuminance() { + Vector3 rgbToLuminance { 0.2126_ra, 0.7152_ra, 0.0722_ra }; + Scalar dIntensity = m_kd.rgb().dot( rgbToLuminance ); + Scalar sIntensity = m_ks.rgb().dot( rgbToLuminance ); + Scalar diffSpecNorm = std::max( 1_ra, dIntensity + sIntensity ); + + m_diffuseLuminance = dIntensity / diffSpecNorm; + m_specularLuminance = sIntensity / diffSpecNorm; +} + } // namespace Material } // namespace Core } // namespace Ra diff --git a/src/Core/Material/BlinnPhongMaterialModel.hpp b/src/Core/Material/BlinnPhongMaterialModel.hpp index 1e098c8e895..b8957ca25dd 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.hpp +++ b/src/Core/Material/BlinnPhongMaterialModel.hpp @@ -48,26 +48,14 @@ class RA_CORE_API BlinnPhongMaterialModel : public SimpleMaterialModel inline std::string getTexNormal() const { return m_texNormal; } inline void setDiffuseColor( Utils::Color color ) { - m_kd = color; - Vector3 rgbToLuminance { 0.2126_ra, 0.7152_ra, 0.0722_ra }; - Scalar dIntensity = m_kd.rgb().dot( rgbToLuminance ); - Scalar sIntensity = m_ks.rgb().dot( rgbToLuminance ); - Scalar diffSpecNorm = std::max( 1_ra, dIntensity + sIntensity ); - - m_diffuseLuminance /= diffSpecNorm; - m_specularLuminance /= diffSpecNorm; + m_kd = color; m_alpha = color.alpha(); + computeLuminance(); } inline void setSpecularColor( Utils::Color color ) { m_ks = color; - Vector3 rgbToLuminance { 0.2126_ra, 0.7152_ra, 0.0722_ra }; - Scalar dIntensity = m_kd.rgb().dot( rgbToLuminance ); - Scalar sIntensity = m_ks.rgb().dot( rgbToLuminance ); - Scalar diffSpecNorm = std::max( 1_ra, dIntensity + sIntensity ); - - m_diffuseLuminance /= diffSpecNorm; - m_specularLuminance /= diffSpecNorm; + computeLuminance(); } inline void setShininess( Scalar specular ) { m_ns = specular; } @@ -85,6 +73,8 @@ class RA_CORE_API BlinnPhongMaterialModel : public SimpleMaterialModel } private: + void computeLuminance(); + Core::Utils::Color m_ks { 0.3_ra, 0.3_ra, 0.3_ra }; Scalar m_ns { 64_ra }; Scalar m_diffuseLuminance; From 84fe1c8de3dc787469d98c37aced333d7db646ca Mon Sep 17 00:00:00 2001 From: grandch Date: Wed, 26 Jul 2023 14:22:29 +0200 Subject: [PATCH 41/56] fix frame usage in blinnphong specular sampling --- src/Core/Material/BlinnPhongMaterialModel.cpp | 24 ++++++++++++++----- src/Core/Random/BlinnPhongSphereSampler.cpp | 4 ++++ src/Core/Random/BlinnPhongSphereSampler.hpp | 2 ++ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/Core/Material/BlinnPhongMaterialModel.cpp b/src/Core/Material/BlinnPhongMaterialModel.cpp index bf9094b448a..9d00294362e 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.cpp +++ b/src/Core/Material/BlinnPhongMaterialModel.cpp @@ -59,17 +59,29 @@ std::optional> BlinnPhongMaterialModel::sample( Vecto if ( distrib < m_diffuseLuminance ) { std::pair smpl = Core::Random::CosineWeightedSphereSampler::getDir( m_generator.get() ); - Vector3 wi( + Vector3 wo( smpl.first.dot( tangent ), smpl.first.dot( bitangent ), smpl.first.dot( normal ) ); - std::pair result { wi, smpl.second }; + std::pair result { wo, smpl.second }; + return result; } - else if ( distrib < m_diffuseLuminance + m_specularLuminance ) { // specular part + // specular part + else if ( distrib < m_diffuseLuminance + m_specularLuminance ) { + // compute incoming direction in canonical frame + Vector3 inDirLocal = inDir.dot( normal ) * normal + inDir.dot( tangent ) * tangent + + inDir.dot( bitangent ) * bitangent; std::pair smpl = Core::Random::BlinnPhongSphereSampler::getDir( m_generator.get(), m_ns ); - Vector3 wi( - smpl.first.dot( tangent ), smpl.first.dot( bitangent ), smpl.first.dot( normal ) ); - std::pair result { wi, smpl.second }; + + // compute reflection in canonical frame using sample as microfacet normal + Vector3 localReflection = + Core::Random::BlinnPhongSphereSampler::reflect( inDirLocal, smpl.first ); + // compute outgoing direction in world frame using normal, tangent and bitangent vectors + Vector3 wo( localReflection.dot( tangent ), + localReflection.dot( bitangent ), + localReflection.dot( normal ) ); + std::pair result { wo, smpl.second }; + return result; } else { // no next dir diff --git a/src/Core/Random/BlinnPhongSphereSampler.cpp b/src/Core/Random/BlinnPhongSphereSampler.cpp index 82a12f7ae32..a640757a85b 100644 --- a/src/Core/Random/BlinnPhongSphereSampler.cpp +++ b/src/Core/Random/BlinnPhongSphereSampler.cpp @@ -27,6 +27,10 @@ Scalar BlinnPhongSphereSampler::pdf( Vector3 dir, Vector3 normal, Scalar roughne return ( roughness + 2 ) * std::pow( dir.dot( normal ), roughness ) / ( 2 * Math::Pi ); } +Vector3 BlinnPhongSphereSampler::reflect( Vector3 inDir, Vector3 normal ) { + return -inDir + 2 * inDir.dot( normal ) * normal; +} + } // namespace Random } // namespace Core } // namespace Ra diff --git a/src/Core/Random/BlinnPhongSphereSampler.hpp b/src/Core/Random/BlinnPhongSphereSampler.hpp index 685e25c1b66..a494867e003 100644 --- a/src/Core/Random/BlinnPhongSphereSampler.hpp +++ b/src/Core/Random/BlinnPhongSphereSampler.hpp @@ -15,6 +15,8 @@ class RA_CORE_API BlinnPhongSphereSampler : public CosineWeightedSphereSampler static std::pair getDir( UniformGenerator* generator, Scalar roughness ); static Scalar pdf( Vector3 dir, Vector3 normal, Scalar roughness ); + + static Vector3 reflect( Vector3 inDir, Vector3 normal ); }; } // namespace Random From bfb19b703f6025b0fd6250c99b03b0c6f3757269 Mon Sep 17 00:00:00 2001 From: grandch Date: Wed, 26 Jul 2023 14:31:42 +0200 Subject: [PATCH 42/56] remove unused u parameter for sampling --- src/Core/Material/BlinnPhongMaterialModel.cpp | 3 +-- src/Core/Material/BlinnPhongMaterialModel.hpp | 2 +- src/Core/Material/MaterialModel.hpp | 4 ++-- src/Core/Material/SimpleMaterialModel.cpp | 10 +++------- src/Core/Material/SimpleMaterialModel.hpp | 4 ++-- 5 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/Core/Material/BlinnPhongMaterialModel.cpp b/src/Core/Material/BlinnPhongMaterialModel.cpp index 9d00294362e..9263682193b 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.cpp +++ b/src/Core/Material/BlinnPhongMaterialModel.cpp @@ -49,8 +49,7 @@ Utils::Color Material::BlinnPhongMaterialModel::operator()( Vector3 w_i, std::optional> BlinnPhongMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector3 tangent, - Vector3 bitangent, - Vector2 u ) { + Vector3 bitangent ) { Vector3 halfway; Scalar distrib = m_generator.get()->get1D(); diff --git a/src/Core/Material/BlinnPhongMaterialModel.hpp b/src/Core/Material/BlinnPhongMaterialModel.hpp index b8957ca25dd..5f999ed6679 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.hpp +++ b/src/Core/Material/BlinnPhongMaterialModel.hpp @@ -36,7 +36,7 @@ class RA_CORE_API BlinnPhongMaterialModel : public SimpleMaterialModel Utils::Color operator()( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) override; std::optional> - sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent, Vector2 u ) override; + sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent ) override; Scalar pdf( Vector3 inDir, Vector3 outDir, Vector3 normal ) override; inline Utils::Color getSpecularColor() const { return m_ks; } diff --git a/src/Core/Material/MaterialModel.hpp b/src/Core/Material/MaterialModel.hpp index 5278d4df1f3..235897cf454 100644 --- a/src/Core/Material/MaterialModel.hpp +++ b/src/Core/Material/MaterialModel.hpp @@ -41,8 +41,8 @@ class RA_CORE_API MaterialModel : public Utils::ObservableVoid */ virtual Utils::Color operator()( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) = 0; virtual std::optional> - sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent, Vector2 u ) = 0; - virtual Scalar pdf( Vector3 inDir, Vector3 outDir, Vector3 normal ) = 0; + sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent ) = 0; + virtual Scalar pdf( Vector3 inDir, Vector3 outDir, Vector3 normal ) = 0; private: std::string m_materialType; diff --git a/src/Core/Material/SimpleMaterialModel.cpp b/src/Core/Material/SimpleMaterialModel.cpp index 1facd59d3bf..86cba99baba 100644 --- a/src/Core/Material/SimpleMaterialModel.cpp +++ b/src/Core/Material/SimpleMaterialModel.cpp @@ -25,11 +25,8 @@ Utils::Color SimpleMaterialModel::operator()( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) { return m_kd; } -std::optional> SimpleMaterialModel::sample( Vector3 inDir, - Vector3 normal, - Vector3 tangent, - Vector3 bitangent, - Vector2 u ) { +std::optional> +SimpleMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent ) { return {}; } Scalar SimpleMaterialModel::pdf( Vector3 inDir, Vector3 outDir, Vector3 normal ) { @@ -64,8 +61,7 @@ Utils::Color Material::LambertianMaterialModel::operator()( Vector3 w_i, std::optional> LambertianMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector3 tangent, - Vector3 bitangent, - Vector2 u ) { + Vector3 bitangent ) { // sample point on hemisphere with cosine-weighted distribution std::pair smpl = Core::Random::CosineWeightedSphereSampler::getDir( m_generator.get() ); diff --git a/src/Core/Material/SimpleMaterialModel.hpp b/src/Core/Material/SimpleMaterialModel.hpp index 5c3ecbdc7bd..b1e00911803 100644 --- a/src/Core/Material/SimpleMaterialModel.hpp +++ b/src/Core/Material/SimpleMaterialModel.hpp @@ -33,7 +33,7 @@ class RA_CORE_API SimpleMaterialModel : public MaterialModel Utils::Color operator()( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) override; std::optional> - sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent, Vector2 u ) override; + sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent ) override; Scalar pdf( Vector3 inDir, Vector3 outDir, Vector3 normal ) override; inline Utils::Color getDiffuseColor() const { return m_kd; } @@ -88,7 +88,7 @@ class RA_CORE_API LambertianMaterialModel : public SimpleMaterialModel Utils::Color operator()( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) override; std::optional> - sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent, Vector2 u ) override; + sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent ) override; Scalar pdf( Vector3 inDir, Vector3 outDir, Vector3 normal ) override; inline std::string getTexNormal() const { return m_texNormal; } From 5919435aaa04f15ffa8174257f845e5a54cabc4c Mon Sep 17 00:00:00 2001 From: grandch Date: Wed, 26 Jul 2023 15:56:40 +0200 Subject: [PATCH 43/56] first doc --- src/Core/Material/BlinnPhongMaterialModel.cpp | 33 ++++++++--------- src/Core/Material/BlinnPhongMaterialModel.hpp | 7 ++-- src/Core/Material/MaterialModel.hpp | 35 ++++++++++++++----- src/Core/Material/SimpleMaterialModel.cpp | 18 +++++----- src/Core/Material/SimpleMaterialModel.hpp | 10 ++++-- src/Core/Random/BlinnPhongSphereSampler.cpp | 10 +++--- src/Core/Random/BlinnPhongSphereSampler.hpp | 23 ++++++++++-- .../Random/CosineWeightedSphereSampler.hpp | 5 +++ src/Core/Random/MersenneTwisterGenerator.hpp | 8 +++-- src/Core/Random/SphereSampler.hpp | 13 +++++++ src/Core/Random/UniformGenerator.hpp | 23 +++++++++--- src/Core/Random/UniformSphereSampler.hpp | 5 +++ 12 files changed, 135 insertions(+), 55 deletions(-) diff --git a/src/Core/Material/BlinnPhongMaterialModel.cpp b/src/Core/Material/BlinnPhongMaterialModel.cpp index 9263682193b..0f92b4b3e2b 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.cpp +++ b/src/Core/Material/BlinnPhongMaterialModel.cpp @@ -46,10 +46,8 @@ Utils::Color Material::BlinnPhongMaterialModel::operator()( Vector3 w_i, return bsdf; } -std::optional> BlinnPhongMaterialModel::sample( Vector3 inDir, - Vector3 normal, - Vector3 tangent, - Vector3 bitangent ) { +std::optional> +BlinnPhongMaterialModel::sample( Vector3 w_i, Vector3 normal, Vector3 tangent, Vector3 bitangent ) { Vector3 halfway; Scalar distrib = m_generator.get()->get1D(); @@ -67,19 +65,19 @@ std::optional> BlinnPhongMaterialModel::sample( Vecto // specular part else if ( distrib < m_diffuseLuminance + m_specularLuminance ) { // compute incoming direction in canonical frame - Vector3 inDirLocal = inDir.dot( normal ) * normal + inDir.dot( tangent ) * tangent + - inDir.dot( bitangent ) * bitangent; + Vector3 w_iLocal = w_i.dot( normal ) * normal + w_i.dot( tangent ) * tangent + + w_i.dot( bitangent ) * bitangent; std::pair smpl = Core::Random::BlinnPhongSphereSampler::getDir( m_generator.get(), m_ns ); // compute reflection in canonical frame using sample as microfacet normal Vector3 localReflection = - Core::Random::BlinnPhongSphereSampler::reflect( inDirLocal, smpl.first ); + Core::Random::BlinnPhongSphereSampler::reflect( w_iLocal, smpl.first ); // compute outgoing direction in world frame using normal, tangent and bitangent vectors - Vector3 wo( localReflection.dot( tangent ), - localReflection.dot( bitangent ), - localReflection.dot( normal ) ); - std::pair result { wo, smpl.second }; + Vector3 w_o( localReflection.dot( tangent ), + localReflection.dot( bitangent ), + localReflection.dot( normal ) ); + std::pair result { w_o, smpl.second }; return result; } @@ -88,13 +86,12 @@ std::optional> BlinnPhongMaterialModel::sample( Vecto } } -Scalar BlinnPhongMaterialModel::pdf( Vector3 inDir, Vector3 outDir, Vector3 normal ) { - return std::clamp( m_diffuseLuminance * - Core::Random::CosineWeightedSphereSampler::pdf( outDir, normal ) + - m_specularLuminance * - Core::Random::BlinnPhongSphereSampler::pdf( outDir, normal, m_ns ), - 0_ra, - 1_ra ); +Scalar BlinnPhongMaterialModel::pdf( Vector3 w_i, Vector3 w_o, Vector3 normal ) { + return std::clamp( + m_diffuseLuminance * Core::Random::CosineWeightedSphereSampler::pdf( w_o, normal ) + + m_specularLuminance * Core::Random::BlinnPhongSphereSampler::pdf( w_o, normal, m_ns ), + 0_ra, + 1_ra ); } void BlinnPhongMaterialModel::computeLuminance() { diff --git a/src/Core/Material/BlinnPhongMaterialModel.hpp b/src/Core/Material/BlinnPhongMaterialModel.hpp index 5f999ed6679..9c48c83898d 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.hpp +++ b/src/Core/Material/BlinnPhongMaterialModel.hpp @@ -12,6 +12,8 @@ namespace Core { namespace Material { // RADIUM SUPPORTED MATERIALS + +/// @brief Implementation of MaterialModel according to Blinn-Phong reflectance model. class RA_CORE_API BlinnPhongMaterialModel : public SimpleMaterialModel { public: @@ -36,8 +38,8 @@ class RA_CORE_API BlinnPhongMaterialModel : public SimpleMaterialModel Utils::Color operator()( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) override; std::optional> - sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent ) override; - Scalar pdf( Vector3 inDir, Vector3 outDir, Vector3 normal ) override; + sample( Vector3 w_i, Vector3 normal, Vector3 tangent, Vector3 bitangent ) override; + Scalar pdf( Vector3 w_i, Vector3 w_o, Vector3 normal ) override; inline Utils::Color getSpecularColor() const { return m_ks; } inline Scalar getShininess() const { return m_ns; } @@ -73,6 +75,7 @@ class RA_CORE_API BlinnPhongMaterialModel : public SimpleMaterialModel } private: + /// @brief Compute luminance values for diffuse color and specular color. void computeLuminance(); Core::Utils::Color m_ks { 0.3_ra, 0.3_ra, 0.3_ra }; diff --git a/src/Core/Material/MaterialModel.hpp b/src/Core/Material/MaterialModel.hpp index 235897cf454..9c4f29d3a5f 100644 --- a/src/Core/Material/MaterialModel.hpp +++ b/src/Core/Material/MaterialModel.hpp @@ -14,9 +14,9 @@ namespace Ra { namespace Core { namespace Material { -/** @brief represent material model, loaded by a file loader. - * - */ +/// Texture management isn't implemented at all. + +/// @brief Interface used for discribing materials, compute bsdf and sample reflectance ray. class RA_CORE_API MaterialModel : public Utils::ObservableVoid { public: @@ -35,14 +35,31 @@ class RA_CORE_API MaterialModel : public Utils::ObservableVoid /// DEBUG virtual void displayInfo() const; - /** Compute BSDF value for a set of directions and texture coordinates. - * w_i : incident direction, w_o : outgoing direction, normal : geometric normal direction. - * w_i, w_o and normal are in world space. - */ + /// @brief Compute BSDF value for a set of directions and texture coordinates. + /// @param w_i incident direction in world space. + /// @param w_o outgoing direction in world space. + /// @param normal geometric normal direction in world space. + /// @param uv UV coordinates for texture mapping. + /// @return The color value of the bsdf. virtual Utils::Color operator()( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) = 0; + + /// @brief Sample reflectance direction for a set of directions. + /// @param w_i incident direction in world space. + /// @param normal normal to the surface in world space. + /// @param tangent tangent to the surface, perpendicular to normal, in world space. + /// @param bitangent bitangent to the surface, perpendicular to the normal and the tangent, in + /// world space. + /// @return optional pair composed of outgoing direction and probability density function value + /// associated with the direction. virtual std::optional> - sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent ) = 0; - virtual Scalar pdf( Vector3 inDir, Vector3 outDir, Vector3 normal ) = 0; + sample( Vector3 w_i, Vector3 normal, Vector3 tangent, Vector3 bitangent ) = 0; + + /// @brief Compute probability density function value associated with a set of directions. + /// @param w_i incident direction in world space. + /// @param w_o outgoing direction in world space. + /// @param normal normal to the surface in world space. + /// @return Scalar probability density function value associated with the directions. + virtual Scalar pdf( Vector3 w_i, Vector3 w_o, Vector3 normal ) = 0; private: std::string m_materialType; diff --git a/src/Core/Material/SimpleMaterialModel.cpp b/src/Core/Material/SimpleMaterialModel.cpp index 86cba99baba..998496f0125 100644 --- a/src/Core/Material/SimpleMaterialModel.cpp +++ b/src/Core/Material/SimpleMaterialModel.cpp @@ -26,10 +26,10 @@ SimpleMaterialModel::operator()( Vector3 w_i, Vector3 w_o, Vector3 normal, Vecto return m_kd; } std::optional> -SimpleMaterialModel::sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent ) { +SimpleMaterialModel::sample( Vector3 w_i, Vector3 normal, Vector3 tangent, Vector3 bitangent ) { return {}; } -Scalar SimpleMaterialModel::pdf( Vector3 inDir, Vector3 outDir, Vector3 normal ) { +Scalar SimpleMaterialModel::pdf( Vector3 w_i, Vector3 w_o, Vector3 normal ) { return 0_ra; } @@ -58,23 +58,21 @@ Utils::Color Material::LambertianMaterialModel::operator()( Vector3 w_i, return m_kd / M_PI; } -std::optional> LambertianMaterialModel::sample( Vector3 inDir, - Vector3 normal, - Vector3 tangent, - Vector3 bitangent ) { +std::optional> +LambertianMaterialModel::sample( Vector3 w_i, Vector3 normal, Vector3 tangent, Vector3 bitangent ) { // sample point on hemisphere with cosine-weighted distribution std::pair smpl = Core::Random::CosineWeightedSphereSampler::getDir( m_generator.get() ); // transform sampled point from local to world coodinate system - Vector3 wi( smpl.first.dot( tangent ), smpl.first.dot( bitangent ), smpl.first.dot( normal ) ); - std::pair result { wi, smpl.second }; + Vector3 w_o( smpl.first.dot( tangent ), smpl.first.dot( bitangent ), smpl.first.dot( normal ) ); + std::pair result { w_o, smpl.second }; return result; } -Scalar LambertianMaterialModel::pdf( Vector3 inDir, Vector3 outDir, Vector3 normal ) { - return Core::Random::CosineWeightedSphereSampler::pdf( outDir, normal ); +Scalar LambertianMaterialModel::pdf( Vector3 w_i, Vector3 w_o, Vector3 normal ) { + return Core::Random::CosineWeightedSphereSampler::pdf( w_o, normal ); } } // namespace Material diff --git a/src/Core/Material/SimpleMaterialModel.hpp b/src/Core/Material/SimpleMaterialModel.hpp index b1e00911803..1463fb6c2d6 100644 --- a/src/Core/Material/SimpleMaterialModel.hpp +++ b/src/Core/Material/SimpleMaterialModel.hpp @@ -11,6 +11,9 @@ namespace Core { namespace Material { // RADIUM SUPPORTED MATERIALS + +/// @brief Implementation of MaterialModel. This material doesn't compute lighting and only display +/// one color. class RA_CORE_API SimpleMaterialModel : public MaterialModel { protected: @@ -33,7 +36,7 @@ class RA_CORE_API SimpleMaterialModel : public MaterialModel Utils::Color operator()( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) override; std::optional> - sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent ) override; + sample( Vector3 w_i, Vector3 normal, Vector3 tangent, Vector3 bitangent ) override; Scalar pdf( Vector3 inDir, Vector3 outDir, Vector3 normal ) override; inline Utils::Color getDiffuseColor() const { return m_kd; } @@ -69,6 +72,7 @@ class RA_CORE_API SimpleMaterialModel : public MaterialModel std::shared_ptr m_generator; }; +/// @brief Implementation of MaterialModel according to Lambertian reflectance model. class RA_CORE_API LambertianMaterialModel : public SimpleMaterialModel { public: @@ -88,8 +92,8 @@ class RA_CORE_API LambertianMaterialModel : public SimpleMaterialModel Utils::Color operator()( Vector3 w_i, Vector3 w_o, Vector3 normal, Vector2 uv ) override; std::optional> - sample( Vector3 inDir, Vector3 normal, Vector3 tangent, Vector3 bitangent ) override; - Scalar pdf( Vector3 inDir, Vector3 outDir, Vector3 normal ) override; + sample( Vector3 w_i, Vector3 normal, Vector3 tangent, Vector3 bitangent ) override; + Scalar pdf( Vector3 w_i, Vector3 w_o, Vector3 normal ) override; inline std::string getTexNormal() const { return m_texNormal; } inline void setTexNormal( std::string texNormal ) { diff --git a/src/Core/Random/BlinnPhongSphereSampler.cpp b/src/Core/Random/BlinnPhongSphereSampler.cpp index a640757a85b..25ca75572eb 100644 --- a/src/Core/Random/BlinnPhongSphereSampler.cpp +++ b/src/Core/Random/BlinnPhongSphereSampler.cpp @@ -7,11 +7,11 @@ namespace Core { namespace Random { std::pair -Ra::Core::Random::BlinnPhongSphereSampler::getDir( UniformGenerator* generator, Scalar roughness ) { +Ra::Core::Random::BlinnPhongSphereSampler::getDir( UniformGenerator* generator, Scalar shininess ) { Vector3 dir; Vector2 u = generator->get2D(); - Scalar cosTheta = std::pow( 1_ra - u[0], 1_ra / ( roughness + 2 ) ); + Scalar cosTheta = std::pow( 1_ra - u[0], 1_ra / ( shininess + 2 ) ); Scalar sinTheta = std::sqrt( 1_ra - cosTheta * cosTheta ); Scalar phi = 2 * Math::Pi * u[1]; @@ -19,12 +19,12 @@ Ra::Core::Random::BlinnPhongSphereSampler::getDir( UniformGenerator* generator, dir[1] = sinTheta * std::sin( phi ); dir[2] = cosTheta; - return { dir, ( roughness + 2 ) * std::pow( 1_ra - u[0], roughness ) / ( 2 * Math::Pi ) }; + return { dir, ( shininess + 2 ) * std::pow( 1_ra - u[0], shininess ) / ( 2 * Math::Pi ) }; } -Scalar BlinnPhongSphereSampler::pdf( Vector3 dir, Vector3 normal, Scalar roughness ) { +Scalar BlinnPhongSphereSampler::pdf( Vector3 dir, Vector3 normal, Scalar shininess ) { dir.normalize(); - return ( roughness + 2 ) * std::pow( dir.dot( normal ), roughness ) / ( 2 * Math::Pi ); + return ( sininess + 2 ) * std::pow( dir.dot( normal ), shininess ) / ( 2 * Math::Pi ); } Vector3 BlinnPhongSphereSampler::reflect( Vector3 inDir, Vector3 normal ) { diff --git a/src/Core/Random/BlinnPhongSphereSampler.hpp b/src/Core/Random/BlinnPhongSphereSampler.hpp index a494867e003..c973f25a48f 100644 --- a/src/Core/Random/BlinnPhongSphereSampler.hpp +++ b/src/Core/Random/BlinnPhongSphereSampler.hpp @@ -6,16 +6,35 @@ namespace Ra { namespace Core { namespace Random { +/// @brief Implementation of SphereSampler following the Blinn-Phong reflectance model. Inherit from +/// CosineWeightedSphereSampler to compute the lambertian component. class RA_CORE_API BlinnPhongSphereSampler : public CosineWeightedSphereSampler { public: BlinnPhongSphereSampler() {}; ~BlinnPhongSphereSampler() {}; - static std::pair getDir( UniformGenerator* generator, Scalar roughness ); + /// @brief Static method to sample the sphere according to Blinn-Phong model. All computations + /// are done in canonical frame. + /// @param generator Uniform random generator used to sample. + /// @param shininess Blinn-Phong exponent. + /// @return Returns a pair made of sampled direction and probability density function value + /// associated. + static std::pair getDir( UniformGenerator* generator, Scalar shininess ); - static Scalar pdf( Vector3 dir, Vector3 normal, Scalar roughness ); + /// @brief Static method to compute probability density function value associated with a + /// outgoing direction and a normal vector according to Blinn-Phong reflectance model. + /// @param dir Outgoing direction in world frame. + /// @param normal Normal vector in world frame, gives the orientation of the sampled hemisphere. + /// @param shininess Blinn-Phong exponent. + /// @return Scalar probability. + static Scalar pdf( Vector3 dir, Vector3 normal, Scalar shininess ); + /// @brief Compute the reflected direction of the inDir direction by the surface represented by + /// the normal vector. + /// @param inDir ingoing direction, must be in the same frame than normal. + /// @param normal normal to the surface that reflect, must be in the same frame than inDir. + /// @return reflected direction in the same frame than parameters. static Vector3 reflect( Vector3 inDir, Vector3 normal ); }; diff --git a/src/Core/Random/CosineWeightedSphereSampler.hpp b/src/Core/Random/CosineWeightedSphereSampler.hpp index af475fc2629..f855f9d31b0 100644 --- a/src/Core/Random/CosineWeightedSphereSampler.hpp +++ b/src/Core/Random/CosineWeightedSphereSampler.hpp @@ -6,14 +6,19 @@ namespace Ra { namespace Core { namespace Random { +/// @brief Cosine weighted implementation of SphereSampler. Used for lambertian reflectance. class RA_CORE_API CosineWeightedSphereSampler : public SphereSampler { public: CosineWeightedSphereSampler() {}; ~CosineWeightedSphereSampler() {}; + /// @brief Implementation of getDir method from SphereSampler. Also called by the same static + /// getDir method. static std::pair getDirImplem( UniformGenerator* generator ); + /// @brief Implementation of pdf method from SphereSampler. Also called by the same static pdf + /// method. static Scalar pdfImplem( Vector3 dir, Vector3 normal ); }; diff --git a/src/Core/Random/MersenneTwisterGenerator.hpp b/src/Core/Random/MersenneTwisterGenerator.hpp index dd462e9fe75..e3bd8977fe6 100644 --- a/src/Core/Random/MersenneTwisterGenerator.hpp +++ b/src/Core/Random/MersenneTwisterGenerator.hpp @@ -8,16 +8,20 @@ namespace Ra { namespace Core { namespace Random { -class RA_CORE_API MersenneTwisterGenerator : public UniformGenerator { +/// @brief Implementation of the UniformGenerator class using the std Mersenne Twister Generator +/// (std::mt19937). +class RA_CORE_API MersenneTwisterGenerator : public UniformGenerator +{ public: MersenneTwisterGenerator(); ~MersenneTwisterGenerator(); Scalar get1D() override; + private: std::mt19937 m_randomEngine; }; } // namespace Random } // namespace Core -} // namespace Ra \ No newline at end of file +} // namespace Ra diff --git a/src/Core/Random/SphereSampler.hpp b/src/Core/Random/SphereSampler.hpp index 11930f2683f..b3a4cb92a06 100644 --- a/src/Core/Random/SphereSampler.hpp +++ b/src/Core/Random/SphereSampler.hpp @@ -7,6 +7,9 @@ namespace Ra { namespace Core { namespace Random { +/// @brief Interface used to sample a hemisphere. This class is a CRTP in order to benefit from +/// polymorphism and static methods. +/// @tparam T is the class that implement this interface. template class RA_CORE_API SphereSampler { @@ -14,10 +17,20 @@ class RA_CORE_API SphereSampler SphereSampler() {}; ~SphereSampler() {}; + /// @brief Samples the sphere. Static method that calls the implemented one from the implemented + /// class T. All computations are done in canonical frame. + /// @param generator Uniform random generator used for sampling. + /// @return Returns a pair made of sampled direction and probability density function value + /// associated. static std::pair getDir( UniformGenerator* generator ) { return T::getDirImplem( generator ); } + /// @brief Compute probability density function value associated with a outgoing direction and a + /// normal vector. Static method that calls the implemented one from the implemented class T. + /// @param dir Outgoing direction in world frame. + /// @param normal Normal vector in world frame, gives the orientation of the sampled hemisphere. + /// @return Scalar probability. static Scalar pdf( Vector3 dir, Vector3 normal ) { return T::pdfImplem( dir, normal ); } }; diff --git a/src/Core/Random/UniformGenerator.hpp b/src/Core/Random/UniformGenerator.hpp index c62d26e2637..f0d3ffdd0e5 100644 --- a/src/Core/Random/UniformGenerator.hpp +++ b/src/Core/Random/UniformGenerator.hpp @@ -8,20 +8,35 @@ namespace Ra { namespace Core { namespace Random { -class RA_CORE_API UniformGenerator { +/// @brief Interface used for implementing uniform random generator. +class RA_CORE_API UniformGenerator +{ public: UniformGenerator() {}; ~UniformGenerator() {}; + /// @brief Virtual method used to get a one dimention random scalar. + /// @return random Scalar between 0 and 1. virtual Scalar get1D() = 0; - + + /// @brief Virtual method used to get a two dimension random vector. + /// default implementation calls get1D() twice. + /// @return random Vector2 between 0 and 1. virtual Vector2 get2D(); + /// @brief Virtual method used to get a three dimension random vector. + /// default implementation calls get1D() three times. + /// @return random Vector3 between 0 and 1. virtual Vector3 get3D(); - virtual VectorN getXD(int dim); + /// @brief Virtual method used to get a X dimension random vector. + /// default implementation calls get1D() X times. + /// @param dim int dimention of the vector. + /// @return random VectorN (with N corresponding to dim) between 0 and 1. + virtual VectorN getXD( int dim ); + protected: std::uniform_real_distribution m_unifDistributionRand { 0, 1 }; }; } // namespace Random } // namespace Core -} // namespace Ra \ No newline at end of file +} // namespace Ra diff --git a/src/Core/Random/UniformSphereSampler.hpp b/src/Core/Random/UniformSphereSampler.hpp index 0d767c9b7ad..3a4c3a7abc3 100644 --- a/src/Core/Random/UniformSphereSampler.hpp +++ b/src/Core/Random/UniformSphereSampler.hpp @@ -6,14 +6,19 @@ namespace Ra { namespace Core { namespace Random { +/// @brief Uniform implementation of SphereSampler. class RA_CORE_API UniformSphereSampler : public SphereSampler { public: UniformSphereSampler() {}; ~UniformSphereSampler() {}; + /// @brief Implementation of getDir method from SphereSampler. Also called by the same static + /// getDir method. static std::pair getDirImplem( UniformGenerator* generator ); + /// @brief Implementation of pdf method from SphereSampler. Also called by the same static pdf + /// method. static Scalar pdfImplem( Vector3 dir, Vector3 normal ); }; From 8c3ff9f2a60afa3586bbf7258c202ab254381bef Mon Sep 17 00:00:00 2001 From: grandch Date: Wed, 26 Jul 2023 16:13:06 +0200 Subject: [PATCH 44/56] quick doc for example app --- examples/PlotImportanceSampler/main.cpp | 59 +++++++------------ .../PlotImportanceSampler/plot-samples.py | 7 +++ src/Core/Random/BlinnPhongSphereSampler.cpp | 2 +- 3 files changed, 29 insertions(+), 39 deletions(-) diff --git a/examples/PlotImportanceSampler/main.cpp b/examples/PlotImportanceSampler/main.cpp index 1efd587afd5..5a7ab122ffc 100644 --- a/examples/PlotImportanceSampler/main.cpp +++ b/examples/PlotImportanceSampler/main.cpp @@ -1,4 +1,4 @@ -#include +// Include the samplers and a random generator #include #include #include @@ -13,50 +13,31 @@ int main( int /*argc*/, char** /*argv*/ ) { using namespace Ra::Core; using json = nlohmann::json; + //! [Creating the random generator to feed the samplers] Random::MersenneTwisterGenerator generator = Random::MersenneTwisterGenerator(); + //! [Creating the samplers] std::vector uSamplesDir, cSamplesDir, bSamplesDir4, bSamplesDir16, bSamplesDir64, - bSamplesDir128, bpmat, lambmat; - - Material::BlinnPhongMaterialModel bpmaterial = Material::BlinnPhongMaterialModel(); + bSamplesDir128; + //! [Sampling (here 500 times) with each sampler] for ( int i = 0; i < 500; i++ ) { - // uSamplesDir.push_back( Random::UniformSphereSampler::getDir( &generator ).first ); - // cSamplesDir.push_back( Random::CosineWeightedSphereSampler::getDir( &generator ).first ); - // bSamplesDir4.push_back( Random::BlinnPhongSphereSampler::getDir( &generator, 4 ).first ); - // bSamplesDir16.push_back( Random::BlinnPhongSphereSampler::getDir( &generator, 16 ).first - // ); bSamplesDir64.push_back( Random::BlinnPhongSphereSampler::getDir( &generator, 64 - // ).first ); bSamplesDir128.push_back( - // Random::BlinnPhongSphereSampler::getDir( &generator, 128 ).first ); - - bpmaterial.m_ns = 4; - auto sample = - bpmaterial.sample( { -1, 0, 1 }, { 0, 0, 1 }, { 0, 1, 0 }, { 1, 0, 0 }, { 0, 0 } ); - if ( sample.has_value() ) bSamplesDir4.push_back( sample.value().first ); - - bpmaterial.m_ns = 16; - sample = bpmaterial.sample( { -1, 0, 1 }, { 0, 0, 1 }, { 0, 1, 0 }, { 1, 0, 0 }, { 0, 0 } ); - if ( sample.has_value() ) bSamplesDir16.push_back( sample.value().first ); - - bpmaterial.m_ns = 64; - sample = bpmaterial.sample( { -1, 0, 1 }, { 0, 0, 1 }, { 0, 1, 0 }, { 1, 0, 0 }, { 0, 0 } ); - if ( sample.has_value() ) bSamplesDir64.push_back( sample.value().first ); - - bpmaterial.m_ns = 128; - sample = bpmaterial.sample( { -1, 0, 1 }, { 0, 0, 1 }, { 0, 1, 0 }, { 1, 0, 0 }, { 0, 0 } ); - if ( sample.has_value() ) bSamplesDir128.push_back( sample.value().first ); + uSamplesDir.push_back( Random::UniformSphereSampler::getDir( &generator ).first ); + cSamplesDir.push_back( Random::CosineWeightedSphereSampler::getDir( &generator ).first ); + bSamplesDir4.push_back( Random::BlinnPhongSphereSampler::getDir( &generator, 4 ).first ); + bSamplesDir16.push_back( Random::BlinnPhongSphereSampler::getDir( &generator, 16 ).first ); + bSamplesDir64.push_back( Random::BlinnPhongSphereSampler::getDir( &generator, 64 ).first ); + bSamplesDir128.push_back( + Random::BlinnPhongSphereSampler::getDir( &generator, 128 ).first ); } - json j = { //{ "UniformSampleDir", uSamplesDir }, - //{ "CosineWeightedSampleDir", cSamplesDir }, - { "BlinnPhongSampleDir 4", bSamplesDir4 }, - { "BlinnPhongSampleDir 16", bSamplesDir16 }, - { "BlinnPhongSampleDir 64", bSamplesDir64 }, - { "BlinnPhongSampleDir 128", bSamplesDir128 } }; - // {"BlinnPhongMaterial", bpmat}}; - // { "UniformSamplePoint", uSamplesPoint }, - // { "CosineWeightedSamplePoint", cSamplesPoint }, - // { "BlinnPhongSamplePoint", bSamplesPoint } + //! [Creating a json format to write the samples in and write to a file named "samples.json"] + json j = { { "UniformSamples", uSamplesDir }, + { "CosineWeightedSamples", cSamplesDir }, + { "BlinnPhongSamples 4", bSamplesDir4 }, + { "BlinnPhongSamples 16", bSamplesDir16 }, + { "BlinnPhongSamples 64", bSamplesDir64 }, + { "BlinnPhongSamples 128", bSamplesDir128 } }; std::ofstream o( "samples.json" ); @@ -64,5 +45,7 @@ int main( int /*argc*/, char** /*argv*/ ) { o.close(); + //! [Samples can now be displayed with the python script named "plot-samples.py"] + return 0; } diff --git a/examples/PlotImportanceSampler/plot-samples.py b/examples/PlotImportanceSampler/plot-samples.py index 3e2c4620a3f..6c5a9fd90a5 100644 --- a/examples/PlotImportanceSampler/plot-samples.py +++ b/examples/PlotImportanceSampler/plot-samples.py @@ -5,6 +5,13 @@ import math import sys +""" +This python script is used to plot the samples writted to a json file by the main.cpp Radium example app in the PlotImportanceSampler folder. + +To launch this script use the command +python3 plot-samples.py /path/to/jsonfile.json +""" + def plotDir(array, ax): for p in array: ax.scatter(p[0], p[1], p[2], c='#1f77b4', s=1) diff --git a/src/Core/Random/BlinnPhongSphereSampler.cpp b/src/Core/Random/BlinnPhongSphereSampler.cpp index 25ca75572eb..d31e10771d1 100644 --- a/src/Core/Random/BlinnPhongSphereSampler.cpp +++ b/src/Core/Random/BlinnPhongSphereSampler.cpp @@ -24,7 +24,7 @@ Ra::Core::Random::BlinnPhongSphereSampler::getDir( UniformGenerator* generator, Scalar BlinnPhongSphereSampler::pdf( Vector3 dir, Vector3 normal, Scalar shininess ) { dir.normalize(); - return ( sininess + 2 ) * std::pow( dir.dot( normal ), shininess ) / ( 2 * Math::Pi ); + return ( shininess + 2 ) * std::pow( dir.dot( normal ), shininess ) / ( 2 * Math::Pi ); } Vector3 BlinnPhongSphereSampler::reflect( Vector3 inDir, Vector3 normal ) { From 09fd139654c893eacf2603258ddbe737a2153aec Mon Sep 17 00:00:00 2001 From: grandch Date: Thu, 27 Jul 2023 18:35:46 +0200 Subject: [PATCH 45/56] doc --- doc/developer.md | 2 ++ doc/developer/corematerials.md | 24 ++++++++++++++++++++++++ doc/developer/corerandom.md | 19 +++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 doc/developer/corematerials.md create mode 100644 doc/developer/corerandom.md diff --git a/doc/developer.md b/doc/developer.md index 60166ecbb31..fd6ef3cffca 100644 --- a/doc/developer.md +++ b/doc/developer.md @@ -28,6 +28,8 @@ Radium offers several cmake functions to configure and build your extension. - \subpage develmeshes - \subpage develanimation +- \subpage develcorematerials +- \subpage develcorerandom \page engine Engine diff --git a/doc/developer/corematerials.md b/doc/developer/corematerials.md new file mode 100644 index 00000000000..231bc845277 --- /dev/null +++ b/doc/developer/corematerials.md @@ -0,0 +1,24 @@ +\page develcorematerials Core Materials +[TOC] + +A Ra::Core::Material::MaterialModel is a way to control the appearance of an object when rendering. + +For now, a Ra::Core::Material::MaterialModel only provides the _Bidirectional Scattering Distribution function (BSDF)_ to be applied on an object. + +This _BSDF_ is composed of three methods. + +# Methods of the Ra::Core::Material + +## Evaluate BSDF + +This method, wich is defined as the operator `()` by the interface in Ra::Core::Material::MaterialModel gives the color value of the object for given ingoing, outgoing and surface normal directions. + +## Sample BSDF + +This method, named `sample()` by the interface in Ra::Core::Material::MaterialModel gives the outgoing direction according to the choosen reflectance model for a given ingoing and surface normal direction. + +A Ra::Core::Material::MaterialModel use a Ra::Core::Random::SphereSampler fed with a Ra::Core::Random::UniformGenerator in order to sample. To learn more about samplers and generators, please read the [Random](@ref develcorerandom) section. + +## Probability density function corresponding to BSDF + +This method, named `pdf()` by the interface in Ra::Core::Material::MaterialModel gives the probability for a pair of ingoing and outgoing direction to exist. diff --git a/doc/developer/corerandom.md b/doc/developer/corerandom.md new file mode 100644 index 00000000000..bd81a22ac8b --- /dev/null +++ b/doc/developer/corerandom.md @@ -0,0 +1,19 @@ +\page develcorerandom Core Random +[TOC] + +The `Ra::Core::Random` namespace contain two interfaces, Ra::Core::Random::UniformGenerator and Ra::Core::Random::SphereSampler. + +# Generators + +A generator is an implementation of the interface Ra::Core::Random::UniformGenerator. It provides an uniform random distribution between 0 and 1. The interface provides four methods to get a random scalar or a 2D, 3D or nD vector. By default, the vectors are built by calling n times the `get1D()` method. + +# Samplers + +A sampler follow the interface Ra::Core::Random::SphereSampler. A sphere sampler generate a direction from the center of the sphere to a point on the surface of the sphere according to a probability distribution. To achieve this, it has two methods. A method `getDir()` that maps an uniform generator into the probability distribution to generate a direction in the canonical frame and a method `pdf()` that compute the probability density function value of a direction with a given normal direction (both directions are in world frame). + +There is an example app called PlotImportanceSampler that can write samples from several samplers in a json file. The json file can then be read by a python script called plot-samples.py. +To launch this script do + +~~~{.bash} +python3 /path/to/plot-samples.py /path/to/jsonfile.json +~~~ From 86a561d0a38313bc1aac2048e464f44853d73cd8 Mon Sep 17 00:00:00 2001 From: grandch Date: Mon, 31 Jul 2023 13:35:43 +0200 Subject: [PATCH 46/56] wip unittests --- src/Core/Random/BlinnPhongSphereSampler.cpp | 2 +- tests/unittest/CMakeLists.txt | 1 + tests/unittest/Core/random.cpp | 195 ++++++++++++++++++++ 3 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 tests/unittest/Core/random.cpp diff --git a/src/Core/Random/BlinnPhongSphereSampler.cpp b/src/Core/Random/BlinnPhongSphereSampler.cpp index d31e10771d1..dc77a6dd0da 100644 --- a/src/Core/Random/BlinnPhongSphereSampler.cpp +++ b/src/Core/Random/BlinnPhongSphereSampler.cpp @@ -28,7 +28,7 @@ Scalar BlinnPhongSphereSampler::pdf( Vector3 dir, Vector3 normal, Scalar shinine } Vector3 BlinnPhongSphereSampler::reflect( Vector3 inDir, Vector3 normal ) { - return -inDir + 2 * inDir.dot( normal ) * normal; + return ( -inDir + 2 * inDir.dot( normal ) * normal ).normalized(); } } // namespace Random diff --git a/tests/unittest/CMakeLists.txt b/tests/unittest/CMakeLists.txt index aa26cd009d9..496468e1f74 100644 --- a/tests/unittest/CMakeLists.txt +++ b/tests/unittest/CMakeLists.txt @@ -22,6 +22,7 @@ set(test_src Core/obb.cpp Core/observer.cpp Core/polyline.cpp + Core/random.cpp Core/raycast.cpp Core/resources.cpp Core/string.cpp diff --git a/tests/unittest/Core/random.cpp b/tests/unittest/Core/random.cpp new file mode 100644 index 00000000000..b5a71a7a625 --- /dev/null +++ b/tests/unittest/Core/random.cpp @@ -0,0 +1,195 @@ +#include +#include +#include +#include +#include +#include + +#include + +using namespace Ra::Core; + +/// @brief Fake random generator class to test the samplers +class FakeGenerator : public Random::UniformGenerator +{ + public: + FakeGenerator() {}; + ~FakeGenerator() {}; + + Scalar get1D() override { return m_1D; } + + Vector2 get2D() override { return m_2D; } + + Vector3 get3D() override { return m_3D; } + + VectorN getXD( int dim ) override { return m_XD; } + + void set1D( Scalar s ) { m_1D = s; } + void set2D( Vector2 v ) { m_2D = v; } + void set3D( Vector3 v ) { m_3D = v; } + void setXD( VectorN v ) { m_XD = v; } + + private: + Scalar m_1D; + Vector2 m_2D; + Vector3 m_3D; + VectorN m_XD; +}; + +TEST_CASE( "Core/Random/UniformSphereSampler" ) { + auto fg = FakeGenerator(); + SECTION( "getDir" ) { + fg.set2D( { 0, 0 } ); + auto p = Random::UniformSphereSampler::getDir( &fg ); + Vector3 d = p.first; + REQUIRE( Math::areApproxEqual( d.x(), 0_ra ) ); + REQUIRE( Math::areApproxEqual( d.y(), 0_ra ) ); + REQUIRE( Math::areApproxEqual( d.z(), 1_ra ) ); + + fg.set2D( { 1, 1 } ); + p = Random::UniformSphereSampler::getDir( &fg ); + d = p.first; + REQUIRE( Math::areApproxEqual( d.x(), 0.84147_ra ) ); + REQUIRE( Math::areApproxEqual( d.y(), 0_ra ) ); + // REQUIRE(Math::areApproxEqual(d.z(), 0.5403_ra)); + REQUIRE( d.z() == 0.5403_ra ); + + fg.set2D( { 0.5, 0.5 } ); + p = Random::UniformSphereSampler::getDir( &fg ); + d = p.first; + REQUIRE( Math::areApproxEqual( d.x(), -0.48_ra ) ); + REQUIRE( Math::areApproxEqual( d.y(), 0_ra ) ); + REQUIRE( Math::areApproxEqual( d.z(), 0.88_ra ) ); + } + + SECTION( "pdf" ) { + Vector3 normal, dir; + Scalar usspdf; + + normal = { 0, 0, 1 }; + dir = { 0, 0, 1 }; + usspdf = Random::UniformSphereSampler::pdf( dir, normal ); + REQUIRE( Math::areApproxEqual( usspdf, 1 / ( 2 * Math::Pi ) ) ); + + dir = { 0, 1, 0 }; + usspdf = Random::UniformSphereSampler::pdf( dir, normal ); + REQUIRE( Math::areApproxEqual( usspdf, 1 / ( 2 * Math::Pi ) ) ); + + dir = { 1, 0, 0 }; + usspdf = Random::UniformSphereSampler::pdf( dir, normal ); + REQUIRE( Math::areApproxEqual( usspdf, 1 / ( 2 * Math::Pi ) ) ); + } +} + +TEST_CASE( "Core/Random/CosineWeightedSphereSampler" ) { + auto fg = FakeGenerator(); + SECTION( "getDir" ) { + fg.set2D( { 0, 0 } ); + auto p = Random::CosineWeightedSphereSampler::getDir( &fg ); + Vector3 d = p.first; + REQUIRE( Math::areApproxEqual( d.x(), 0_ra ) ); + REQUIRE( Math::areApproxEqual( d.y(), 0_ra ) ); + REQUIRE( Math::areApproxEqual( d.z(), 1_ra ) ); + + fg.set2D( { 1, 1 } ); + p = Random::CosineWeightedSphereSampler::getDir( &fg ); + d = p.first; + REQUIRE( Math::areApproxEqual( d.x(), 0.84147_ra ) ); // failed + REQUIRE( Math::areApproxEqual( d.y(), 0_ra ) ); + // REQUIRE(Math::areApproxEqual(d.z(), 0.54_ra)); + REQUIRE( d.z() == 0.5403_ra ); + + fg.set2D( { 0.5, 0.5 } ); + p = Random::CosineWeightedSphereSampler::getDir( &fg ); + d = p.first; + REQUIRE( Math::areApproxEqual( d.x(), -0.65_ra ) ); + REQUIRE( Math::areApproxEqual( d.y(), 0_ra ) ); + REQUIRE( Math::areApproxEqual( d.z(), 0.76_ra ) ); + } + + SECTION( "pdf" ) { + Vector3 normal, dir; + Scalar usspdf; + + normal = { 0, 0, 1 }; + dir = { 0, 0, 1 }; + usspdf = Random::CosineWeightedSphereSampler::pdf( dir, normal ); + REQUIRE( Math::areApproxEqual( usspdf, 1 / Math::Pi ) ); + + dir = { 0, 1, 0 }; + usspdf = Random::CosineWeightedSphereSampler::pdf( dir, normal ); + REQUIRE( Math::areApproxEqual( usspdf, 0_ra ) ); + + dir = { 1, 0, 0 }; + usspdf = Random::CosineWeightedSphereSampler::pdf( dir, normal ); + REQUIRE( Math::areApproxEqual( usspdf, 0_ra ) ); + } +} + +TEST_CASE( "Core/Random/BlinnPhongSphereSampler" ) { + auto fg = FakeGenerator(); + SECTION( "getDir" ) { + fg.set2D( { 0, 0 } ); + auto p = Random::BlinnPhongSphereSampler::getDir( &fg, 8 ); + Vector3 d = p.first; + REQUIRE( Math::areApproxEqual( d.x(), 0_ra ) ); + REQUIRE( Math::areApproxEqual( d.y(), 0_ra ) ); + REQUIRE( Math::areApproxEqual( d.z(), 1_ra ) ); + + fg.set2D( { 1, 1 } ); + p = Random::BlinnPhongSphereSampler::getDir( &fg, 32 ); + d = p.first; + REQUIRE( Math::areApproxEqual( d.x(), 1_ra ) ); + REQUIRE( Math::areApproxEqual( d.y(), 0_ra ) ); + REQUIRE( Math::areApproxEqual( d.z(), 0_ra ) ); + + fg.set2D( { 0.5, 0.5 } ); + p = Random::BlinnPhongSphereSampler::getDir( &fg, 128 ); + d = p.first; + // REQUIRE(Math::areApproxEqual(d.x(), -0.1_ra)); + REQUIRE( d.x() == -0.10299_ra ); + REQUIRE( Math::areApproxEqual( d.y(), 0_ra ) ); + REQUIRE( Math::areApproxEqual( d.z(), 0.99_ra ) ); + } + + // SECTION("pdf") { + // Vector3 normal, dir; + // Scalar usspdf; + + // normal = {0,0,1}; + // dir = {0,0,1}; + // usspdf = Random::BlinnPhongSphereSampler::pdf(dir, normal); + // REQUIRE(Math::areApproxEqual(usspdf, 1 / ( 2 * Math::Pi ))); + + // dir = {0,1,0}; + // usspdf = Random::BlinnPhongSphereSampler::pdf(dir, normal); + // REQUIRE(Math::areApproxEqual(usspdf, 1 / ( 2 * Math::Pi ))); + + // dir = {1,0,0}; + // usspdf = Random::BlinnPhongSphereSampler::pdf(dir, normal); + // REQUIRE(Math::areApproxEqual(usspdf, 1 / ( 2 * Math::Pi ))); + // } + + SECTION( "reflect" ) { + Vector3 normal = { 0, 0, 1 }; + + Vector3 reflected = Random::BlinnPhongSphereSampler::reflect( { 0, 0, -1 }, normal ); + REQUIRE( Math::areApproxEqual( reflected.x(), 0_ra ) ); + REQUIRE( Math::areApproxEqual( reflected.y(), 0_ra ) ); + // REQUIRE(Math::areApproxEqual(reflected.z(), 1_ra)); + REQUIRE( reflected.z() == -1_ra ); + + reflected = Random::BlinnPhongSphereSampler::reflect( { 1, 0, 0 }, normal ); + // REQUIRE(Math::areApproxEqual(reflected.x(), 1_ra)); + REQUIRE( reflected.x() == -1_ra ); + REQUIRE( Math::areApproxEqual( reflected.y(), 0_ra ) ); + REQUIRE( Math::areApproxEqual( reflected.z(), 0_ra ) ); + + reflected = Random::BlinnPhongSphereSampler::reflect( { 0.5, 0.5, -0.5 }, normal ); + // REQUIRE(Math::areApproxEqual(reflected.x(), 0_ra)); + // REQUIRE(Math::areApproxEqual(reflected.y(), 0_ra)); + // REQUIRE(Math::areApproxEqual(reflected.z(), 1_ra)); + // std::cout << std::endl << std::endl << "REFLECT" << std::endl << std::endl << + // reflected.x() << ", " << reflected.y() << ", " << reflected.z() << std::endl; + } +} From bc363aba1b1850893df9ed4cd8ad07eb01891629 Mon Sep 17 00:00:00 2001 From: grandch Date: Mon, 31 Jul 2023 15:14:27 +0200 Subject: [PATCH 47/56] fix blinnphong pdf --- src/Core/Material/BlinnPhongMaterialModel.cpp | 11 ++++++----- src/Core/Random/BlinnPhongSphereSampler.cpp | 11 ++++++++--- src/Core/Random/BlinnPhongSphereSampler.hpp | 5 +++-- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/Core/Material/BlinnPhongMaterialModel.cpp b/src/Core/Material/BlinnPhongMaterialModel.cpp index 0f92b4b3e2b..7872b4e6d25 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.cpp +++ b/src/Core/Material/BlinnPhongMaterialModel.cpp @@ -87,11 +87,12 @@ BlinnPhongMaterialModel::sample( Vector3 w_i, Vector3 normal, Vector3 tangent, V } Scalar BlinnPhongMaterialModel::pdf( Vector3 w_i, Vector3 w_o, Vector3 normal ) { - return std::clamp( - m_diffuseLuminance * Core::Random::CosineWeightedSphereSampler::pdf( w_o, normal ) + - m_specularLuminance * Core::Random::BlinnPhongSphereSampler::pdf( w_o, normal, m_ns ), - 0_ra, - 1_ra ); + return std::clamp( m_diffuseLuminance * + Core::Random::CosineWeightedSphereSampler::pdf( w_o, normal ) + + m_specularLuminance * + Core::Random::BlinnPhongSphereSampler::pdf( w_i, w_o, normal, m_ns ), + 0_ra, + 1_ra ); } void BlinnPhongMaterialModel::computeLuminance() { diff --git a/src/Core/Random/BlinnPhongSphereSampler.cpp b/src/Core/Random/BlinnPhongSphereSampler.cpp index dc77a6dd0da..2cd516d584f 100644 --- a/src/Core/Random/BlinnPhongSphereSampler.cpp +++ b/src/Core/Random/BlinnPhongSphereSampler.cpp @@ -22,9 +22,14 @@ Ra::Core::Random::BlinnPhongSphereSampler::getDir( UniformGenerator* generator, return { dir, ( shininess + 2 ) * std::pow( 1_ra - u[0], shininess ) / ( 2 * Math::Pi ) }; } -Scalar BlinnPhongSphereSampler::pdf( Vector3 dir, Vector3 normal, Scalar shininess ) { - dir.normalize(); - return ( shininess + 2 ) * std::pow( dir.dot( normal ), shininess ) / ( 2 * Math::Pi ); +Scalar BlinnPhongSphereSampler::pdf( Vector3 w_i, Vector3 w_o, Vector3 normal, Scalar shininess ) { + w_i.normalize(); + w_o.normalize(); + + Vector3 halfway = ( w_i + w_o ).normalized(); + Scalar cosTheta = normal.dot( halfway ); + + return ( shininess + 2 ) * std::pow( cosTheta, shininess ) / ( 2 * Math::Pi ); } Vector3 BlinnPhongSphereSampler::reflect( Vector3 inDir, Vector3 normal ) { diff --git a/src/Core/Random/BlinnPhongSphereSampler.hpp b/src/Core/Random/BlinnPhongSphereSampler.hpp index c973f25a48f..aa0c7fbcf64 100644 --- a/src/Core/Random/BlinnPhongSphereSampler.hpp +++ b/src/Core/Random/BlinnPhongSphereSampler.hpp @@ -24,11 +24,12 @@ class RA_CORE_API BlinnPhongSphereSampler : public CosineWeightedSphereSampler /// @brief Static method to compute probability density function value associated with a /// outgoing direction and a normal vector according to Blinn-Phong reflectance model. - /// @param dir Outgoing direction in world frame. + /// @param w_i ingoing direction in world frame. + /// @param w_o Outgoing direction in world frame. /// @param normal Normal vector in world frame, gives the orientation of the sampled hemisphere. /// @param shininess Blinn-Phong exponent. /// @return Scalar probability. - static Scalar pdf( Vector3 dir, Vector3 normal, Scalar shininess ); + static Scalar pdf( Vector3 w_i, Vector3 w_o, Vector3 normal, Scalar shininess ); /// @brief Compute the reflected direction of the inDir direction by the surface represented by /// the normal vector. From b1de2bae536176bdb909b0942d3aa7e3f8b8c71f Mon Sep 17 00:00:00 2001 From: grandch Date: Mon, 31 Jul 2023 16:28:40 +0200 Subject: [PATCH 48/56] fix reflect method --- src/Core/Random/BlinnPhongSphereSampler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Core/Random/BlinnPhongSphereSampler.cpp b/src/Core/Random/BlinnPhongSphereSampler.cpp index 2cd516d584f..6ebf6a76d2a 100644 --- a/src/Core/Random/BlinnPhongSphereSampler.cpp +++ b/src/Core/Random/BlinnPhongSphereSampler.cpp @@ -33,7 +33,7 @@ Scalar BlinnPhongSphereSampler::pdf( Vector3 w_i, Vector3 w_o, Vector3 normal, S } Vector3 BlinnPhongSphereSampler::reflect( Vector3 inDir, Vector3 normal ) { - return ( -inDir + 2 * inDir.dot( normal ) * normal ).normalized(); + return { -inDir.x(), -inDir.y(), inDir.z() }; } } // namespace Random From 326b312b96acfac606b329f7437b3118d9a309db Mon Sep 17 00:00:00 2001 From: grandch Date: Mon, 31 Jul 2023 16:38:12 +0200 Subject: [PATCH 49/56] wip unittests --- tests/unittest/Core/random.cpp | 60 ++++++++++++++++------------------ 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/tests/unittest/Core/random.cpp b/tests/unittest/Core/random.cpp index b5a71a7a625..a14bfb11867 100644 --- a/tests/unittest/Core/random.cpp +++ b/tests/unittest/Core/random.cpp @@ -51,8 +51,7 @@ TEST_CASE( "Core/Random/UniformSphereSampler" ) { d = p.first; REQUIRE( Math::areApproxEqual( d.x(), 0.84147_ra ) ); REQUIRE( Math::areApproxEqual( d.y(), 0_ra ) ); - // REQUIRE(Math::areApproxEqual(d.z(), 0.5403_ra)); - REQUIRE( d.z() == 0.5403_ra ); + REQUIRE( Math::areApproxEqual( d.z(), 0.5403_ra ) ); fg.set2D( { 0.5, 0.5 } ); p = Random::UniformSphereSampler::getDir( &fg ); @@ -94,10 +93,9 @@ TEST_CASE( "Core/Random/CosineWeightedSphereSampler" ) { fg.set2D( { 1, 1 } ); p = Random::CosineWeightedSphereSampler::getDir( &fg ); d = p.first; - REQUIRE( Math::areApproxEqual( d.x(), 0.84147_ra ) ); // failed + REQUIRE( Math::areApproxEqual( d.x(), 0.84147_ra ) ); REQUIRE( Math::areApproxEqual( d.y(), 0_ra ) ); - // REQUIRE(Math::areApproxEqual(d.z(), 0.54_ra)); - REQUIRE( d.z() == 0.5403_ra ); + REQUIRE( Math::areApproxEqual( d.z(), 0.54_ra ) ); fg.set2D( { 0.5, 0.5 } ); p = Random::CosineWeightedSphereSampler::getDir( &fg ); @@ -146,29 +144,31 @@ TEST_CASE( "Core/Random/BlinnPhongSphereSampler" ) { fg.set2D( { 0.5, 0.5 } ); p = Random::BlinnPhongSphereSampler::getDir( &fg, 128 ); d = p.first; - // REQUIRE(Math::areApproxEqual(d.x(), -0.1_ra)); - REQUIRE( d.x() == -0.10299_ra ); + REQUIRE( Math::areApproxEqual( d.x(), -0.1_ra ) ); REQUIRE( Math::areApproxEqual( d.y(), 0_ra ) ); REQUIRE( Math::areApproxEqual( d.z(), 0.99_ra ) ); } - // SECTION("pdf") { - // Vector3 normal, dir; - // Scalar usspdf; - - // normal = {0,0,1}; - // dir = {0,0,1}; - // usspdf = Random::BlinnPhongSphereSampler::pdf(dir, normal); - // REQUIRE(Math::areApproxEqual(usspdf, 1 / ( 2 * Math::Pi ))); - - // dir = {0,1,0}; - // usspdf = Random::BlinnPhongSphereSampler::pdf(dir, normal); - // REQUIRE(Math::areApproxEqual(usspdf, 1 / ( 2 * Math::Pi ))); + SECTION( "pdf" ) { + Vector3 normal; + Scalar usspdf; - // dir = {1,0,0}; - // usspdf = Random::BlinnPhongSphereSampler::pdf(dir, normal); - // REQUIRE(Math::areApproxEqual(usspdf, 1 / ( 2 * Math::Pi ))); - // } + normal = { 0, 0, 1 }; + usspdf = Random::BlinnPhongSphereSampler::pdf( + { 0, 0, 1 }, + Random::BlinnPhongSphereSampler::reflect( { 0, 0, 1 }, normal ), + normal, + 8 ); + REQUIRE( Math::areApproxEqual( usspdf, 1.59155_ra ) ); + + usspdf = + Random::BlinnPhongSphereSampler::pdf( { 0, 1, 0 }, { 0.02, -0.97, 0.01 }, normal, 4 ); + REQUIRE( Math::areApproxEqual( usspdf, 0.038187_ra ) ); + + usspdf = Random::BlinnPhongSphereSampler::pdf( + { 1, 0, 0.5 }, { -1.01, 0.03, 0.49 }, normal, 32 ); + REQUIRE( Math::areApproxEqual( usspdf, 5.33004_ra ) ); + } SECTION( "reflect" ) { Vector3 normal = { 0, 0, 1 }; @@ -176,20 +176,16 @@ TEST_CASE( "Core/Random/BlinnPhongSphereSampler" ) { Vector3 reflected = Random::BlinnPhongSphereSampler::reflect( { 0, 0, -1 }, normal ); REQUIRE( Math::areApproxEqual( reflected.x(), 0_ra ) ); REQUIRE( Math::areApproxEqual( reflected.y(), 0_ra ) ); - // REQUIRE(Math::areApproxEqual(reflected.z(), 1_ra)); - REQUIRE( reflected.z() == -1_ra ); + REQUIRE( Math::areApproxEqual( reflected.z(), 1_ra ) ); reflected = Random::BlinnPhongSphereSampler::reflect( { 1, 0, 0 }, normal ); - // REQUIRE(Math::areApproxEqual(reflected.x(), 1_ra)); - REQUIRE( reflected.x() == -1_ra ); + REQUIRE( Math::areApproxEqual( reflected.x(), -1_ra ) ); REQUIRE( Math::areApproxEqual( reflected.y(), 0_ra ) ); REQUIRE( Math::areApproxEqual( reflected.z(), 0_ra ) ); reflected = Random::BlinnPhongSphereSampler::reflect( { 0.5, 0.5, -0.5 }, normal ); - // REQUIRE(Math::areApproxEqual(reflected.x(), 0_ra)); - // REQUIRE(Math::areApproxEqual(reflected.y(), 0_ra)); - // REQUIRE(Math::areApproxEqual(reflected.z(), 1_ra)); - // std::cout << std::endl << std::endl << "REFLECT" << std::endl << std::endl << - // reflected.x() << ", " << reflected.y() << ", " << reflected.z() << std::endl; + REQUIRE( Math::areApproxEqual( reflected.x(), -0.5_ra ) ); + REQUIRE( Math::areApproxEqual( reflected.y(), -0.5_ra ) ); + REQUIRE( Math::areApproxEqual( reflected.z(), -0.5_ra ) ); } } From ecdedef6bc91f883ca91590d3720298b90961a6b Mon Sep 17 00:00:00 2001 From: grandch Date: Mon, 31 Jul 2023 20:09:20 +0200 Subject: [PATCH 50/56] refix reflect method --- src/Core/Random/BlinnPhongSphereSampler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Core/Random/BlinnPhongSphereSampler.cpp b/src/Core/Random/BlinnPhongSphereSampler.cpp index 6ebf6a76d2a..f46ab1070b7 100644 --- a/src/Core/Random/BlinnPhongSphereSampler.cpp +++ b/src/Core/Random/BlinnPhongSphereSampler.cpp @@ -33,7 +33,7 @@ Scalar BlinnPhongSphereSampler::pdf( Vector3 w_i, Vector3 w_o, Vector3 normal, S } Vector3 BlinnPhongSphereSampler::reflect( Vector3 inDir, Vector3 normal ) { - return { -inDir.x(), -inDir.y(), inDir.z() }; + return -inDir + 2 * inDir.dot( normal ) * normal ).normalized(); } } // namespace Random From c3a0886e730b9a7854df183504291f54742de842 Mon Sep 17 00:00:00 2001 From: grandch Date: Mon, 31 Jul 2023 20:12:14 +0200 Subject: [PATCH 51/56] forgot ( --- src/Core/Random/BlinnPhongSphereSampler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Core/Random/BlinnPhongSphereSampler.cpp b/src/Core/Random/BlinnPhongSphereSampler.cpp index f46ab1070b7..2cd516d584f 100644 --- a/src/Core/Random/BlinnPhongSphereSampler.cpp +++ b/src/Core/Random/BlinnPhongSphereSampler.cpp @@ -33,7 +33,7 @@ Scalar BlinnPhongSphereSampler::pdf( Vector3 w_i, Vector3 w_o, Vector3 normal, S } Vector3 BlinnPhongSphereSampler::reflect( Vector3 inDir, Vector3 normal ) { - return -inDir + 2 * inDir.dot( normal ) * normal ).normalized(); + return ( -inDir + 2 * inDir.dot( normal ) * normal ).normalized(); } } // namespace Random From decdc5dd29bca9977323b4f592fce2335671fa9b Mon Sep 17 00:00:00 2001 From: grandch Date: Thu, 3 Aug 2023 16:25:14 +0200 Subject: [PATCH 52/56] rewrite specular sampling methods --- src/Core/Material/BlinnPhongMaterialModel.cpp | 18 ++++++------------ src/Core/Random/BlinnPhongSphereSampler.cpp | 2 ++ 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/Core/Material/BlinnPhongMaterialModel.cpp b/src/Core/Material/BlinnPhongMaterialModel.cpp index 7872b4e6d25..04120a60985 100644 --- a/src/Core/Material/BlinnPhongMaterialModel.cpp +++ b/src/Core/Material/BlinnPhongMaterialModel.cpp @@ -64,20 +64,14 @@ BlinnPhongMaterialModel::sample( Vector3 w_i, Vector3 normal, Vector3 tangent, V } // specular part else if ( distrib < m_diffuseLuminance + m_specularLuminance ) { - // compute incoming direction in canonical frame - Vector3 w_iLocal = w_i.dot( normal ) * normal + w_i.dot( tangent ) * tangent + - w_i.dot( bitangent ) * bitangent; std::pair smpl = Core::Random::BlinnPhongSphereSampler::getDir( m_generator.get(), m_ns ); - - // compute reflection in canonical frame using sample as microfacet normal - Vector3 localReflection = - Core::Random::BlinnPhongSphereSampler::reflect( w_iLocal, smpl.first ); - // compute outgoing direction in world frame using normal, tangent and bitangent vectors - Vector3 w_o( localReflection.dot( tangent ), - localReflection.dot( bitangent ), - localReflection.dot( normal ) ); - std::pair result { w_o, smpl.second }; + Vector3 localMicroFacetNormal = smpl.first; + Vector3 microFacetNormal( localMicroFacetNormal.dot( tangent ), + localMicroFacetNormal.dot( bitangent ), + localMicroFacetNormal.dot( normal ) ); + Vector3 reflected = Core::Random::BlinnPhongSphereSampler::reflect( w_i, microFacetNormal ); + std::pair result { reflected, smpl.second }; return result; } diff --git a/src/Core/Random/BlinnPhongSphereSampler.cpp b/src/Core/Random/BlinnPhongSphereSampler.cpp index 2cd516d584f..c450d0b8445 100644 --- a/src/Core/Random/BlinnPhongSphereSampler.cpp +++ b/src/Core/Random/BlinnPhongSphereSampler.cpp @@ -33,6 +33,8 @@ Scalar BlinnPhongSphereSampler::pdf( Vector3 w_i, Vector3 w_o, Vector3 normal, S } Vector3 BlinnPhongSphereSampler::reflect( Vector3 inDir, Vector3 normal ) { + inDir.normalize(); + normal.normalize(); return ( -inDir + 2 * inDir.dot( normal ) * normal ).normalized(); } From f1fb47df78a0fb443f1af106a89af1257da8881a Mon Sep 17 00:00:00 2001 From: grandch Date: Thu, 3 Aug 2023 16:25:56 +0200 Subject: [PATCH 53/56] first step refactoring --- src/Engine/Data/BlinnPhongMaterial.cpp | 4 ++++ src/Engine/Data/BlinnPhongMaterial.hpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/Engine/Data/BlinnPhongMaterial.cpp b/src/Engine/Data/BlinnPhongMaterial.cpp index a905ce8483c..019158fc1d1 100644 --- a/src/Engine/Data/BlinnPhongMaterial.cpp +++ b/src/Engine/Data/BlinnPhongMaterial.cpp @@ -17,6 +17,7 @@ static const std::string materialName { "BlinnPhong" }; nlohmann::json BlinnPhongMaterial::s_parametersMetadata = {}; BlinnPhongMaterial::BlinnPhongMaterial( const std::string& instanceName ) : + m_coreMaterial( new Core::Material::BlinnPhongMaterialModel() ), Material( instanceName, materialName, Material::MaterialAspect::MAT_OPAQUE ) {} BlinnPhongMaterial::~BlinnPhongMaterial() { @@ -27,10 +28,13 @@ void BlinnPhongMaterial::updateRenderingParameters() { // update the rendering parameters auto& renderParameters = getParameters(); renderParameters.addParameter( "material.kd", m_kd ); + m_coreMaterial->setDiffuseColor( m_kd ); renderParameters.addParameter( "material.hasPerVertexKd", m_perVertexColor ); renderParameters.addParameter( "material.renderAsSplat", m_renderAsSplat ); renderParameters.addParameter( "material.ks", m_ks ); + m_coreMaterial->setSpecularColor( m_ks ); renderParameters.addParameter( "material.ns", m_ns ); + m_coreMaterial->setShininess( m_ns ); renderParameters.addParameter( "material.alpha", std::min( m_alpha, m_kd[3] ) ); Texture* tex = getTexture( BlinnPhongMaterial::TextureSemantic::TEX_DIFFUSE ); if ( tex != nullptr ) { renderParameters.addParameter( "material.tex.kd", tex ); } diff --git a/src/Engine/Data/BlinnPhongMaterial.hpp b/src/Engine/Data/BlinnPhongMaterial.hpp index a41ae9ecee5..a5e77b18d51 100644 --- a/src/Engine/Data/BlinnPhongMaterial.hpp +++ b/src/Engine/Data/BlinnPhongMaterial.hpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -89,6 +90,8 @@ class RA_ENGINE_API BlinnPhongMaterial final : public Material, public Parameter inline bool isColoredByVertexAttrib() const override; + inline Core::Material::BlinnPhongMaterialModel* getCoreMaterial() { return m_coreMaterial; } + public: Core::Utils::Color m_kd { 0.7, 0.7, 0.7, 1.0 }; Core::Utils::Color m_ks { 0.3, 0.3, 0.3, 1.0 }; @@ -110,6 +113,7 @@ class RA_ENGINE_API BlinnPhongMaterial final : public Material, public Parameter std::map m_textures; std::map m_pendingTextures; static nlohmann::json s_parametersMetadata; + Core::Material::BlinnPhongMaterialModel* m_coreMaterial; /** * Add an new texture, from a given file, to control the specified BSDF parameter. From 90eac6de462be629e1f86fc3893533a4f84fa081 Mon Sep 17 00:00:00 2001 From: grandch Date: Thu, 3 Aug 2023 16:26:36 +0200 Subject: [PATCH 54/56] wip unit tests --- tests/unittest/Core/random.cpp | 69 +++++++++++++++++----------------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/tests/unittest/Core/random.cpp b/tests/unittest/Core/random.cpp index a14bfb11867..67ea05f6cf8 100644 --- a/tests/unittest/Core/random.cpp +++ b/tests/unittest/Core/random.cpp @@ -39,24 +39,24 @@ class FakeGenerator : public Random::UniformGenerator TEST_CASE( "Core/Random/UniformSphereSampler" ) { auto fg = FakeGenerator(); SECTION( "getDir" ) { - fg.set2D( { 0, 0 } ); + fg.set2D( { 0_ra, 0_ra } ); auto p = Random::UniformSphereSampler::getDir( &fg ); Vector3 d = p.first; REQUIRE( Math::areApproxEqual( d.x(), 0_ra ) ); REQUIRE( Math::areApproxEqual( d.y(), 0_ra ) ); REQUIRE( Math::areApproxEqual( d.z(), 1_ra ) ); - fg.set2D( { 1, 1 } ); + fg.set2D( { 1_ra, 1_ra } ); p = Random::UniformSphereSampler::getDir( &fg ); d = p.first; REQUIRE( Math::areApproxEqual( d.x(), 0.84147_ra ) ); REQUIRE( Math::areApproxEqual( d.y(), 0_ra ) ); - REQUIRE( Math::areApproxEqual( d.z(), 0.5403_ra ) ); + REQUIRE( Math::areApproxEqual( d.z(), 0.5403_ra, 1000_ra ) ); - fg.set2D( { 0.5, 0.5 } ); + fg.set2D( { 0.5_ra, 0.5_ra } ); p = Random::UniformSphereSampler::getDir( &fg ); d = p.first; - REQUIRE( Math::areApproxEqual( d.x(), -0.48_ra ) ); + REQUIRE( Math::areApproxEqual( d.x(), -0.48_ra, 1000_ra ) ); REQUIRE( Math::areApproxEqual( d.y(), 0_ra ) ); REQUIRE( Math::areApproxEqual( d.z(), 0.88_ra ) ); } @@ -65,16 +65,16 @@ TEST_CASE( "Core/Random/UniformSphereSampler" ) { Vector3 normal, dir; Scalar usspdf; - normal = { 0, 0, 1 }; - dir = { 0, 0, 1 }; + normal = { 0_ra, 0_ra, 1_ra }; + dir = { 0_ra, 0_ra, 1_ra }; usspdf = Random::UniformSphereSampler::pdf( dir, normal ); REQUIRE( Math::areApproxEqual( usspdf, 1 / ( 2 * Math::Pi ) ) ); - dir = { 0, 1, 0 }; + dir = { 0_ra, 1_ra, 0_ra }; usspdf = Random::UniformSphereSampler::pdf( dir, normal ); REQUIRE( Math::areApproxEqual( usspdf, 1 / ( 2 * Math::Pi ) ) ); - dir = { 1, 0, 0 }; + dir = { 1_ra, 0_ra, 0_ra }; usspdf = Random::UniformSphereSampler::pdf( dir, normal ); REQUIRE( Math::areApproxEqual( usspdf, 1 / ( 2 * Math::Pi ) ) ); } @@ -83,21 +83,21 @@ TEST_CASE( "Core/Random/UniformSphereSampler" ) { TEST_CASE( "Core/Random/CosineWeightedSphereSampler" ) { auto fg = FakeGenerator(); SECTION( "getDir" ) { - fg.set2D( { 0, 0 } ); + fg.set2D( { 0_ra, 0_ra } ); auto p = Random::CosineWeightedSphereSampler::getDir( &fg ); Vector3 d = p.first; REQUIRE( Math::areApproxEqual( d.x(), 0_ra ) ); REQUIRE( Math::areApproxEqual( d.y(), 0_ra ) ); REQUIRE( Math::areApproxEqual( d.z(), 1_ra ) ); - fg.set2D( { 1, 1 } ); + fg.set2D( { 1_ra, 1_ra } ); p = Random::CosineWeightedSphereSampler::getDir( &fg ); d = p.first; REQUIRE( Math::areApproxEqual( d.x(), 0.84147_ra ) ); REQUIRE( Math::areApproxEqual( d.y(), 0_ra ) ); - REQUIRE( Math::areApproxEqual( d.z(), 0.54_ra ) ); + REQUIRE( Math::areApproxEqual( d.z(), 0.54_ra, 1000_ra ) ); - fg.set2D( { 0.5, 0.5 } ); + fg.set2D( { 0.5_ra, 0.5_ra } ); p = Random::CosineWeightedSphereSampler::getDir( &fg ); d = p.first; REQUIRE( Math::areApproxEqual( d.x(), -0.65_ra ) ); @@ -109,16 +109,16 @@ TEST_CASE( "Core/Random/CosineWeightedSphereSampler" ) { Vector3 normal, dir; Scalar usspdf; - normal = { 0, 0, 1 }; - dir = { 0, 0, 1 }; + normal = { 0_ra, 0_ra, 1_ra }; + dir = { 0_ra, 0_ra, 1_ra }; usspdf = Random::CosineWeightedSphereSampler::pdf( dir, normal ); REQUIRE( Math::areApproxEqual( usspdf, 1 / Math::Pi ) ); - dir = { 0, 1, 0 }; + dir = { 0_ra, 1_ra, 0_ra }; usspdf = Random::CosineWeightedSphereSampler::pdf( dir, normal ); REQUIRE( Math::areApproxEqual( usspdf, 0_ra ) ); - dir = { 1, 0, 0 }; + dir = { 1_ra, 0_ra, 0_ra }; usspdf = Random::CosineWeightedSphereSampler::pdf( dir, normal ); REQUIRE( Math::areApproxEqual( usspdf, 0_ra ) ); } @@ -127,24 +127,24 @@ TEST_CASE( "Core/Random/CosineWeightedSphereSampler" ) { TEST_CASE( "Core/Random/BlinnPhongSphereSampler" ) { auto fg = FakeGenerator(); SECTION( "getDir" ) { - fg.set2D( { 0, 0 } ); + fg.set2D( { 0_ra, 0_ra } ); auto p = Random::BlinnPhongSphereSampler::getDir( &fg, 8 ); Vector3 d = p.first; REQUIRE( Math::areApproxEqual( d.x(), 0_ra ) ); REQUIRE( Math::areApproxEqual( d.y(), 0_ra ) ); REQUIRE( Math::areApproxEqual( d.z(), 1_ra ) ); - fg.set2D( { 1, 1 } ); + fg.set2D( { 1_ra, 1_ra } ); p = Random::BlinnPhongSphereSampler::getDir( &fg, 32 ); d = p.first; REQUIRE( Math::areApproxEqual( d.x(), 1_ra ) ); REQUIRE( Math::areApproxEqual( d.y(), 0_ra ) ); REQUIRE( Math::areApproxEqual( d.z(), 0_ra ) ); - fg.set2D( { 0.5, 0.5 } ); + fg.set2D( { 0.5_ra, 0.5_ra } ); p = Random::BlinnPhongSphereSampler::getDir( &fg, 128 ); d = p.first; - REQUIRE( Math::areApproxEqual( d.x(), -0.1_ra ) ); + REQUIRE( Math::areApproxEqual( d.x(), -0.1_ra, 1000_ra ) ); REQUIRE( Math::areApproxEqual( d.y(), 0_ra ) ); REQUIRE( Math::areApproxEqual( d.z(), 0.99_ra ) ); } @@ -153,37 +153,38 @@ TEST_CASE( "Core/Random/BlinnPhongSphereSampler" ) { Vector3 normal; Scalar usspdf; - normal = { 0, 0, 1 }; + normal = { 0_ra, 0_ra, 1_ra }; usspdf = Random::BlinnPhongSphereSampler::pdf( - { 0, 0, 1 }, - Random::BlinnPhongSphereSampler::reflect( { 0, 0, 1 }, normal ), + { 0_ra, 0_ra, 1_ra }, + Random::BlinnPhongSphereSampler::reflect( { 0_ra, 0_ra, 1_ra }, normal ), normal, - 8 ); + 8_ra ); REQUIRE( Math::areApproxEqual( usspdf, 1.59155_ra ) ); - usspdf = - Random::BlinnPhongSphereSampler::pdf( { 0, 1, 0 }, { 0.02, -0.97, 0.01 }, normal, 4 ); + usspdf = Random::BlinnPhongSphereSampler::pdf( + { 0_ra, 1_ra, 0_ra }, { 0.02_ra, -0.97_ra, 0.01_ra }, normal, 4_ra ); REQUIRE( Math::areApproxEqual( usspdf, 0.038187_ra ) ); usspdf = Random::BlinnPhongSphereSampler::pdf( - { 1, 0, 0.5 }, { -1.01, 0.03, 0.49 }, normal, 32 ); - REQUIRE( Math::areApproxEqual( usspdf, 5.33004_ra ) ); + { 1_ra, 0_ra, 0.5_ra }, { -1.01_ra, 0.03_ra, 0.49_ra }, normal, 32_ra ); + REQUIRE( Math::areApproxEqual( usspdf, 5.33004_ra, 1000_ra ) ); } SECTION( "reflect" ) { - Vector3 normal = { 0, 0, 1 }; + Vector3 normal = { 0_ra, 0_ra, 1_ra }; - Vector3 reflected = Random::BlinnPhongSphereSampler::reflect( { 0, 0, -1 }, normal ); + Vector3 reflected = + Random::BlinnPhongSphereSampler::reflect( { 0_ra, 0_ra, -1_ra }, normal ); REQUIRE( Math::areApproxEqual( reflected.x(), 0_ra ) ); REQUIRE( Math::areApproxEqual( reflected.y(), 0_ra ) ); - REQUIRE( Math::areApproxEqual( reflected.z(), 1_ra ) ); + REQUIRE( Math::areApproxEqual( reflected.z(), -1_ra, 1000_ra ) ); - reflected = Random::BlinnPhongSphereSampler::reflect( { 1, 0, 0 }, normal ); + reflected = Random::BlinnPhongSphereSampler::reflect( { 1_ra, 0_ra, 0_ra }, normal ); REQUIRE( Math::areApproxEqual( reflected.x(), -1_ra ) ); REQUIRE( Math::areApproxEqual( reflected.y(), 0_ra ) ); REQUIRE( Math::areApproxEqual( reflected.z(), 0_ra ) ); - reflected = Random::BlinnPhongSphereSampler::reflect( { 0.5, 0.5, -0.5 }, normal ); + reflected = Random::BlinnPhongSphereSampler::reflect( { 0.5_ra, 0.5_ra, -0.5_ra }, normal ); REQUIRE( Math::areApproxEqual( reflected.x(), -0.5_ra ) ); REQUIRE( Math::areApproxEqual( reflected.y(), -0.5_ra ) ); REQUIRE( Math::areApproxEqual( reflected.z(), -0.5_ra ) ); From c385d8a224a83e1a2aa1576a17927726b1837a2e Mon Sep 17 00:00:00 2001 From: grandch Date: Fri, 25 Aug 2023 14:50:46 +0200 Subject: [PATCH 55/56] tests --- tests/unittest/Core/random.cpp | 226 ++++++++++++++++++++++----------- 1 file changed, 154 insertions(+), 72 deletions(-) diff --git a/tests/unittest/Core/random.cpp b/tests/unittest/Core/random.cpp index 67ea05f6cf8..9e3c36c8952 100644 --- a/tests/unittest/Core/random.cpp +++ b/tests/unittest/Core/random.cpp @@ -36,29 +36,93 @@ class FakeGenerator : public Random::UniformGenerator VectorN m_XD; }; +Vector3 uniformSamplerGetDir( FakeGenerator* fg ) { + Vector3 dir; + Vector2 u = fg->get2D(); + + Scalar cosTheta = std::cos( u[0] ); + Scalar sinTheta = std::cos( Math::Pi / 2_ra - u[0] ); + Scalar phi = 2 * Math::Pi * u[1]; + + dir[0] = sinTheta * std::cos( phi ); + dir[1] = sinTheta * std::sin( phi ); + dir[2] = cosTheta; + + return dir; +} + +Vector3 cosineWeightedSamplerGetDir( FakeGenerator* fg ) { + Vector3 dir; + Vector2 u = fg->get2D(); + + Scalar cosTheta = std::cos( std::sqrt( u[0] ) ); + Scalar sinTheta = std::cos( Math::Pi / 2_ra - std::sqrt( u[0] ) ); + Scalar phi = 2 * Math::Pi * u[1]; + + dir[0] = sinTheta * std::cos( phi ); + dir[1] = sinTheta * std::sin( phi ); + dir[2] = cosTheta; + + return dir; +} + +Vector3 blinnPhongSamplerGetDir( FakeGenerator* fg, Scalar shininess ) { + Vector3 dir; + Vector2 u = fg->get2D(); + + Scalar cosTheta = std::pow( 1_ra - u[0], 1_ra / ( shininess + 2_ra ) ); + Scalar sinTheta = std::sqrt( 1_ra - cosTheta * cosTheta ); + Scalar phi = 2 * Math::Pi * u[1]; + + dir[0] = sinTheta * std::cos( phi ); + dir[1] = sinTheta * std::sin( phi ); + dir[2] = cosTheta; + + return dir; +} + +Scalar blinnPhongPdf( Vector3 w_i, Vector3 w_o, Vector3 normal, Scalar shininess ) { + w_i.normalize(); + w_o.normalize(); + + Vector3 halfway = ( w_i + w_o ).normalized(); + Scalar cosTheta = normal.dot( halfway ); + + return ( shininess + 2_ra ) * std::pow( cosTheta, shininess ) / ( 2_ra * Math::Pi ); +} + +Vector3 blinnPhongReflect( Vector3 inDir, Vector3 normal ) { + inDir.normalize(); + normal.normalize(); + return ( -inDir + 2 * inDir.dot( normal ) * normal ).normalized(); +} + TEST_CASE( "Core/Random/UniformSphereSampler" ) { - auto fg = FakeGenerator(); SECTION( "getDir" ) { + auto fg = FakeGenerator(); fg.set2D( { 0_ra, 0_ra } ); - auto p = Random::UniformSphereSampler::getDir( &fg ); - Vector3 d = p.first; - REQUIRE( Math::areApproxEqual( d.x(), 0_ra ) ); - REQUIRE( Math::areApproxEqual( d.y(), 0_ra ) ); - REQUIRE( Math::areApproxEqual( d.z(), 1_ra ) ); + auto p = Random::UniformSphereSampler::getDir( &fg ); + Vector3 d = p.first; + Vector3 dtest = uniformSamplerGetDir( &fg ); + REQUIRE( Math::areApproxEqual( d.x(), dtest.x() ) ); + REQUIRE( Math::areApproxEqual( d.y(), dtest.y() ) ); + REQUIRE( Math::areApproxEqual( d.z(), dtest.z() ) ); fg.set2D( { 1_ra, 1_ra } ); - p = Random::UniformSphereSampler::getDir( &fg ); - d = p.first; - REQUIRE( Math::areApproxEqual( d.x(), 0.84147_ra ) ); - REQUIRE( Math::areApproxEqual( d.y(), 0_ra ) ); - REQUIRE( Math::areApproxEqual( d.z(), 0.5403_ra, 1000_ra ) ); + p = Random::UniformSphereSampler::getDir( &fg ); + d = p.first; + dtest = uniformSamplerGetDir( &fg ); + REQUIRE( Math::areApproxEqual( d.x(), dtest.x() ) ); + REQUIRE( Math::areApproxEqual( d.y(), dtest.y() ) ); + REQUIRE( Math::areApproxEqual( d.z(), dtest.z() ) ); fg.set2D( { 0.5_ra, 0.5_ra } ); - p = Random::UniformSphereSampler::getDir( &fg ); - d = p.first; - REQUIRE( Math::areApproxEqual( d.x(), -0.48_ra, 1000_ra ) ); - REQUIRE( Math::areApproxEqual( d.y(), 0_ra ) ); - REQUIRE( Math::areApproxEqual( d.z(), 0.88_ra ) ); + p = Random::UniformSphereSampler::getDir( &fg ); + d = p.first; + dtest = uniformSamplerGetDir( &fg ); + REQUIRE( Math::areApproxEqual( d.x(), dtest.x() ) ); + REQUIRE( Math::areApproxEqual( d.y(), dtest.y() ) ); + REQUIRE( Math::areApproxEqual( d.z(), dtest.z() ) ); } SECTION( "pdf" ) { @@ -68,41 +132,44 @@ TEST_CASE( "Core/Random/UniformSphereSampler" ) { normal = { 0_ra, 0_ra, 1_ra }; dir = { 0_ra, 0_ra, 1_ra }; usspdf = Random::UniformSphereSampler::pdf( dir, normal ); - REQUIRE( Math::areApproxEqual( usspdf, 1 / ( 2 * Math::Pi ) ) ); + REQUIRE( Math::areApproxEqual( usspdf, 1_ra / ( 2_ra * Math::Pi ) ) ); dir = { 0_ra, 1_ra, 0_ra }; usspdf = Random::UniformSphereSampler::pdf( dir, normal ); - REQUIRE( Math::areApproxEqual( usspdf, 1 / ( 2 * Math::Pi ) ) ); + REQUIRE( Math::areApproxEqual( usspdf, 1_ra / ( 2_ra * Math::Pi ) ) ); dir = { 1_ra, 0_ra, 0_ra }; usspdf = Random::UniformSphereSampler::pdf( dir, normal ); - REQUIRE( Math::areApproxEqual( usspdf, 1 / ( 2 * Math::Pi ) ) ); + REQUIRE( Math::areApproxEqual( usspdf, 1_ra / ( 2_ra * Math::Pi ) ) ); } } TEST_CASE( "Core/Random/CosineWeightedSphereSampler" ) { - auto fg = FakeGenerator(); SECTION( "getDir" ) { + auto fg = FakeGenerator(); fg.set2D( { 0_ra, 0_ra } ); - auto p = Random::CosineWeightedSphereSampler::getDir( &fg ); - Vector3 d = p.first; - REQUIRE( Math::areApproxEqual( d.x(), 0_ra ) ); - REQUIRE( Math::areApproxEqual( d.y(), 0_ra ) ); - REQUIRE( Math::areApproxEqual( d.z(), 1_ra ) ); + auto p = Random::CosineWeightedSphereSampler::getDir( &fg ); + Vector3 d = p.first; + Vector3 dtest = cosineWeightedSamplerGetDir( &fg ); + REQUIRE( Math::areApproxEqual( d.x(), dtest.x() ) ); + REQUIRE( Math::areApproxEqual( d.y(), dtest.y() ) ); + REQUIRE( Math::areApproxEqual( d.z(), dtest.z() ) ); fg.set2D( { 1_ra, 1_ra } ); - p = Random::CosineWeightedSphereSampler::getDir( &fg ); - d = p.first; - REQUIRE( Math::areApproxEqual( d.x(), 0.84147_ra ) ); - REQUIRE( Math::areApproxEqual( d.y(), 0_ra ) ); - REQUIRE( Math::areApproxEqual( d.z(), 0.54_ra, 1000_ra ) ); + p = Random::CosineWeightedSphereSampler::getDir( &fg ); + d = p.first; + dtest = cosineWeightedSamplerGetDir( &fg ); + REQUIRE( Math::areApproxEqual( d.x(), dtest.x() ) ); + REQUIRE( Math::areApproxEqual( d.y(), dtest.y() ) ); + REQUIRE( Math::areApproxEqual( d.z(), dtest.z() ) ); fg.set2D( { 0.5_ra, 0.5_ra } ); - p = Random::CosineWeightedSphereSampler::getDir( &fg ); - d = p.first; - REQUIRE( Math::areApproxEqual( d.x(), -0.65_ra ) ); - REQUIRE( Math::areApproxEqual( d.y(), 0_ra ) ); - REQUIRE( Math::areApproxEqual( d.z(), 0.76_ra ) ); + p = Random::CosineWeightedSphereSampler::getDir( &fg ); + d = p.first; + dtest = cosineWeightedSamplerGetDir( &fg ); + REQUIRE( Math::areApproxEqual( d.x(), dtest.x() ) ); + REQUIRE( Math::areApproxEqual( d.y(), dtest.y() ) ); + REQUIRE( Math::areApproxEqual( d.z(), dtest.z() ) ); } SECTION( "pdf" ) { @@ -112,62 +179,74 @@ TEST_CASE( "Core/Random/CosineWeightedSphereSampler" ) { normal = { 0_ra, 0_ra, 1_ra }; dir = { 0_ra, 0_ra, 1_ra }; usspdf = Random::CosineWeightedSphereSampler::pdf( dir, normal ); - REQUIRE( Math::areApproxEqual( usspdf, 1 / Math::Pi ) ); + REQUIRE( Math::areApproxEqual( usspdf, 1_ra / Math::Pi ) ); dir = { 0_ra, 1_ra, 0_ra }; usspdf = Random::CosineWeightedSphereSampler::pdf( dir, normal ); REQUIRE( Math::areApproxEqual( usspdf, 0_ra ) ); - dir = { 1_ra, 0_ra, 0_ra }; + dir = { 1_ra, 0_ra, 0.3_ra }; usspdf = Random::CosineWeightedSphereSampler::pdf( dir, normal ); - REQUIRE( Math::areApproxEqual( usspdf, 0_ra ) ); + REQUIRE( Math::areApproxEqual( usspdf, dir.normalized().dot( normal ) / Math::Pi ) ); } } TEST_CASE( "Core/Random/BlinnPhongSphereSampler" ) { - auto fg = FakeGenerator(); SECTION( "getDir" ) { + auto fg = FakeGenerator(); fg.set2D( { 0_ra, 0_ra } ); - auto p = Random::BlinnPhongSphereSampler::getDir( &fg, 8 ); - Vector3 d = p.first; - REQUIRE( Math::areApproxEqual( d.x(), 0_ra ) ); - REQUIRE( Math::areApproxEqual( d.y(), 0_ra ) ); - REQUIRE( Math::areApproxEqual( d.z(), 1_ra ) ); + auto p = Random::BlinnPhongSphereSampler::getDir( &fg, 8_ra ); + Vector3 d = p.first; + Vector3 dtest = blinnPhongSamplerGetDir( &fg, 8_ra ); + REQUIRE( Math::areApproxEqual( d.x(), dtest.x() ) ); + REQUIRE( Math::areApproxEqual( d.y(), dtest.y() ) ); + REQUIRE( Math::areApproxEqual( d.z(), dtest.z() ) ); fg.set2D( { 1_ra, 1_ra } ); - p = Random::BlinnPhongSphereSampler::getDir( &fg, 32 ); - d = p.first; - REQUIRE( Math::areApproxEqual( d.x(), 1_ra ) ); - REQUIRE( Math::areApproxEqual( d.y(), 0_ra ) ); - REQUIRE( Math::areApproxEqual( d.z(), 0_ra ) ); + p = Random::BlinnPhongSphereSampler::getDir( &fg, 32_ra ); + d = p.first; + dtest = blinnPhongSamplerGetDir( &fg, 32_ra ); + REQUIRE( Math::areApproxEqual( d.x(), dtest.x() ) ); + REQUIRE( Math::areApproxEqual( d.y(), dtest.y() ) ); + REQUIRE( Math::areApproxEqual( d.z(), dtest.z() ) ); fg.set2D( { 0.5_ra, 0.5_ra } ); - p = Random::BlinnPhongSphereSampler::getDir( &fg, 128 ); - d = p.first; - REQUIRE( Math::areApproxEqual( d.x(), -0.1_ra, 1000_ra ) ); - REQUIRE( Math::areApproxEqual( d.y(), 0_ra ) ); - REQUIRE( Math::areApproxEqual( d.z(), 0.99_ra ) ); + p = Random::BlinnPhongSphereSampler::getDir( &fg, 128_ra ); + d = p.first; + dtest = blinnPhongSamplerGetDir( &fg, 128_ra ); + REQUIRE( Math::areApproxEqual( d.x(), dtest.x() ) ); + REQUIRE( Math::areApproxEqual( d.y(), dtest.y() ) ); + REQUIRE( Math::areApproxEqual( d.z(), dtest.z() ) ); } SECTION( "pdf" ) { Vector3 normal; - Scalar usspdf; + Scalar pdf, testpdf; normal = { 0_ra, 0_ra, 1_ra }; - usspdf = Random::BlinnPhongSphereSampler::pdf( + pdf = Random::BlinnPhongSphereSampler::pdf( { 0_ra, 0_ra, 1_ra }, Random::BlinnPhongSphereSampler::reflect( { 0_ra, 0_ra, 1_ra }, normal ), normal, 8_ra ); - REQUIRE( Math::areApproxEqual( usspdf, 1.59155_ra ) ); - - usspdf = Random::BlinnPhongSphereSampler::pdf( + testpdf = + blinnPhongPdf( { 0_ra, 0_ra, 1_ra }, + Random::BlinnPhongSphereSampler::reflect( { 0_ra, 0_ra, 1_ra }, normal ), + normal, + 8_ra ); + REQUIRE( Math::areApproxEqual( pdf, testpdf ) ); + + pdf = Random::BlinnPhongSphereSampler::pdf( { 0_ra, 1_ra, 0_ra }, { 0.02_ra, -0.97_ra, 0.01_ra }, normal, 4_ra ); - REQUIRE( Math::areApproxEqual( usspdf, 0.038187_ra ) ); + testpdf = + blinnPhongPdf( { 0_ra, 1_ra, 0_ra }, { 0.02_ra, -0.97_ra, 0.01_ra }, normal, 4_ra ); + REQUIRE( Math::areApproxEqual( pdf, testpdf ) ); - usspdf = Random::BlinnPhongSphereSampler::pdf( + pdf = Random::BlinnPhongSphereSampler::pdf( { 1_ra, 0_ra, 0.5_ra }, { -1.01_ra, 0.03_ra, 0.49_ra }, normal, 32_ra ); - REQUIRE( Math::areApproxEqual( usspdf, 5.33004_ra, 1000_ra ) ); + testpdf = + blinnPhongPdf( { 1_ra, 0_ra, 0.5_ra }, { -1.01_ra, 0.03_ra, 0.49_ra }, normal, 32_ra ); + REQUIRE( Math::areApproxEqual( pdf, testpdf ) ); } SECTION( "reflect" ) { @@ -175,18 +254,21 @@ TEST_CASE( "Core/Random/BlinnPhongSphereSampler" ) { Vector3 reflected = Random::BlinnPhongSphereSampler::reflect( { 0_ra, 0_ra, -1_ra }, normal ); - REQUIRE( Math::areApproxEqual( reflected.x(), 0_ra ) ); - REQUIRE( Math::areApproxEqual( reflected.y(), 0_ra ) ); - REQUIRE( Math::areApproxEqual( reflected.z(), -1_ra, 1000_ra ) ); + Vector3 testreflect = blinnPhongReflect( { 0_ra, 0_ra, -1_ra }, normal ); + REQUIRE( Math::areApproxEqual( reflected.x(), testreflect.x() ) ); + REQUIRE( Math::areApproxEqual( reflected.y(), testreflect.y() ) ); + REQUIRE( Math::areApproxEqual( reflected.z(), testreflect.z() ) ); - reflected = Random::BlinnPhongSphereSampler::reflect( { 1_ra, 0_ra, 0_ra }, normal ); - REQUIRE( Math::areApproxEqual( reflected.x(), -1_ra ) ); - REQUIRE( Math::areApproxEqual( reflected.y(), 0_ra ) ); - REQUIRE( Math::areApproxEqual( reflected.z(), 0_ra ) ); + reflected = Random::BlinnPhongSphereSampler::reflect( { 1_ra, 0_ra, 0_ra }, normal ); + testreflect = blinnPhongReflect( { 1_ra, 0_ra, 0_ra }, normal ); + REQUIRE( Math::areApproxEqual( reflected.x(), testreflect.x() ) ); + REQUIRE( Math::areApproxEqual( reflected.y(), testreflect.y() ) ); + REQUIRE( Math::areApproxEqual( reflected.z(), testreflect.z() ) ); reflected = Random::BlinnPhongSphereSampler::reflect( { 0.5_ra, 0.5_ra, -0.5_ra }, normal ); - REQUIRE( Math::areApproxEqual( reflected.x(), -0.5_ra ) ); - REQUIRE( Math::areApproxEqual( reflected.y(), -0.5_ra ) ); - REQUIRE( Math::areApproxEqual( reflected.z(), -0.5_ra ) ); + testreflect = blinnPhongReflect( { 0.5_ra, 0.5_ra, -0.5_ra }, normal ); + REQUIRE( Math::areApproxEqual( reflected.x(), testreflect.x() ) ); + REQUIRE( Math::areApproxEqual( reflected.y(), testreflect.y() ) ); + REQUIRE( Math::areApproxEqual( reflected.z(), testreflect.z() ) ); } } From 3f80c49fabbb30812d7526f6939c5f2fffa65778 Mon Sep 17 00:00:00 2001 From: grandch Date: Fri, 25 Aug 2023 15:14:21 +0200 Subject: [PATCH 56/56] virtual destructor uniform generator --- src/Core/Random/MersenneTwisterGenerator.cpp | 7 +++---- src/Core/Random/MersenneTwisterGenerator.hpp | 2 +- src/Core/Random/UniformGenerator.hpp | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Core/Random/MersenneTwisterGenerator.cpp b/src/Core/Random/MersenneTwisterGenerator.cpp index 59daa02b3a9..d04ac43db39 100644 --- a/src/Core/Random/MersenneTwisterGenerator.cpp +++ b/src/Core/Random/MersenneTwisterGenerator.cpp @@ -4,9 +4,8 @@ namespace Ra { namespace Core { namespace Random { -MersenneTwisterGenerator::MersenneTwisterGenerator() : m_randomEngine( std::mt19937( std::time( nullptr ) ) ) {} - -Ra::Core::Random::MersenneTwisterGenerator::~MersenneTwisterGenerator() {} +MersenneTwisterGenerator::MersenneTwisterGenerator() : + m_randomEngine( std::mt19937( std::time( nullptr ) ) ) {} Scalar Ra::Core::Random::MersenneTwisterGenerator::get1D() { return m_unifDistributionRand( m_randomEngine ); @@ -14,4 +13,4 @@ Scalar Ra::Core::Random::MersenneTwisterGenerator::get1D() { } // namespace Random } // namespace Core -} // namespace Ra \ No newline at end of file +} // namespace Ra diff --git a/src/Core/Random/MersenneTwisterGenerator.hpp b/src/Core/Random/MersenneTwisterGenerator.hpp index e3bd8977fe6..655440a92a5 100644 --- a/src/Core/Random/MersenneTwisterGenerator.hpp +++ b/src/Core/Random/MersenneTwisterGenerator.hpp @@ -14,7 +14,7 @@ class RA_CORE_API MersenneTwisterGenerator : public UniformGenerator { public: MersenneTwisterGenerator(); - ~MersenneTwisterGenerator(); + ~MersenneTwisterGenerator() override = default; Scalar get1D() override; diff --git a/src/Core/Random/UniformGenerator.hpp b/src/Core/Random/UniformGenerator.hpp index f0d3ffdd0e5..5952b046ba4 100644 --- a/src/Core/Random/UniformGenerator.hpp +++ b/src/Core/Random/UniformGenerator.hpp @@ -13,7 +13,7 @@ class RA_CORE_API UniformGenerator { public: UniformGenerator() {}; - ~UniformGenerator() {}; + virtual ~UniformGenerator() = 0; /// @brief Virtual method used to get a one dimention random scalar. /// @return random Scalar between 0 and 1.