diff --git a/src/definitions/materials/material.cpp b/src/definitions/materials/material.cpp index 1232c5e..9775d95 100644 --- a/src/definitions/materials/material.cpp +++ b/src/definitions/materials/material.cpp @@ -18,6 +18,40 @@ Material::Material(glm::vec3 col, float specularity, float emittance) Specularity = specularity; } +Material::Material(glm::vec3 colour, float emittance, float specularity, float index, float gloss, bool transparent, bool emissive) + : Colour(colour), + Emittance(emittance), + Specularity(specularity), + Index(index), + Gloss(gloss), + Transparent(transparent), + Emissive(emissive) { + + if (Emittance > 0.0f) { Emissive = true; } + else { Emissive = false; } +} + +glm::vec3 ConeBounce(glm::vec3 reflectDir, float theta) { + if (theta < EPSILON) { + return reflectDir; + } + + float u = rand01(); + float v = rand01(); + + theta = theta * (1 - (2 * acos(u) / PI)); + float m1 = sin(theta); + float m2 = cos(theta); + float a = v * 2 * PI; + glm::vec3 q = randomUnitVector(); + glm::vec3 s = glm::cross(reflectDir, q); + glm::vec3 t = glm::cross(reflectDir, s); + glm::vec3 d = { }; + d = d + (s * (m1 * cos(a))); + d = d + (t * (m1 * sin(a))); + d = d + (reflectDir * m2); + return glm::normalize(d); +} glm::vec3 Material::Bounce(glm::vec3 in, glm::vec3 normal) { if (Specularity == 0.0f) { @@ -33,7 +67,11 @@ glm::vec3 Material::Bounce(glm::vec3 in, glm::vec3 normal) { if (r > Specularity) { return CosineBRDF(normal); } else { - return Reflect(in, normal); - } + glm::vec3 reflect = Reflect(in, normal); + + if (Gloss == 0.0f) + return reflect; + return ConeBounce(reflect, Gloss); + } } diff --git a/src/definitions/materials/material.hpp b/src/definitions/materials/material.hpp index dc8f063..dcd5e3b 100644 --- a/src/definitions/materials/material.hpp +++ b/src/definitions/materials/material.hpp @@ -10,6 +10,7 @@ class Material { public: Material(); Material(glm::vec3 col, float specularity = 0.0f, float emmitance = 0.0f); + Material(glm::vec3 colour, float emittance, float Specularity, float index, float gloss, bool transparent, bool emissive); glm::vec3 Bounce(glm::vec3 in, glm::vec3 normal); @@ -19,12 +20,18 @@ public: Texture* GlossTexture = nullptr; float Emittance; float Specularity; // 1.0f = perfect reflective - // float Index; // refractive index - // float Gloss; // reflection cone angle in radians + float Index; // refractive index + float Gloss; // reflection cone angle in radians // float Tint; // specular and refractive tinting // float Reflectivity; // metallic reflection bool Transparent; bool Emissive; }; +class GlossyMaterial : public Material { +public: + GlossyMaterial(glm::vec3 colour, float shine, float gloss) + : Material(colour, 0.0f, shine, 1.0f, gloss, false, false) { }; +}; + #endif diff --git a/src/maths.hpp b/src/maths.hpp index 089bc36..cdde0d1 100644 --- a/src/maths.hpp +++ b/src/maths.hpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -30,6 +31,17 @@ inline float fastRadianToDegree(const float Radian) { return (Radian * RAD2DEG); inline float getFovAdjustment(const float fov) { return tanf(fov * PI / 360.0f); } inline float getAspectRatio(const float w, const float h) { return (float)w / (float)h; } +inline glm::vec3 randomUnitVector() { + std::default_random_engine generator; + std::uniform_real_distribution distribution(-1, 1); + + float x = distribution(generator); + float y = distribution(generator); + float z = distribution(generator); + + return glm::normalize(glm::vec3({x,y,z})); +} + // (-b += sqrt(b^2-4ac)) / 2a inline bool quadratic(float a, float b, float c, float& x0, float& x1) { float discr = b * b - 4.0f * a * c; diff --git a/test/main.cpp b/test/main.cpp index 0cfc9ba..3ad5f91 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -2,8 +2,8 @@ #include "../src/inferno.hpp" -static const int width = 1080; -static const int height = 720; +static const int width = 700; +static const int height = 700; int main(int argc, char** argv) { InfernoEngine inferno; @@ -26,17 +26,17 @@ int main(int argc, char** argv) { //Sphere sphere1({ 1.3f, -0.8f, -5.0f }, 0.2f, new Material({ 0.817f, 0.374, 0.574 })); //scene->objects.push_back(&sphere1); - Sphere sphere({ 0.0f, 0.0f, -5.0f }, 1.0f, new Material({ 0.817f, 0.374, 0.574 })); - // sphere.material->NormalTexture = new Texture("E:/Projects/Inferno/resources/textures/dirt-normal.jpg"); - sphere.material->NormalTexture = new Texture("/home/ben/programming/inferno/resources/textures/dirt-normal.jpg"); + Sphere sphere({ -2.1f, 0.0f, -8.0f }, 1.0f, new GlossyMaterial({ 0.817f, 0.374, 0.574 }, 0.5f, fastDegreetoRadian(0.0f))); scene->objects.push_back(&sphere); + Sphere sphere1({ 0.0f, 0.0f, -8.0f }, 1.0f, new GlossyMaterial({ 0.817f, 0.374, 0.574 }, 0.5f, fastDegreetoRadian(3.0f))); + scene->objects.push_back(&sphere1); + Sphere sphere2({ 2.1f, 0.0f, -8.0f }, 1.0f, new GlossyMaterial({ 0.817f, 0.374, 0.574 }, 0.5f, fastDegreetoRadian(30.0f))); + scene->objects.push_back(&sphere2); Sphere light({ 35.0f, 50.0f, 25.0f }, 25.0f, new Material({ 1.0f, 1.0f, 1.0f }, 0.0f, 200.0f)); scene->objects.push_back(&light); - Plane plane({ 0.0f,-1.0f, 0.0f }, { 0.0f, -1.0f, 0.0f }, new Material({ 0.2f, 0.2f, 0.2f })); - // plane.material->NormalTexture = new Texture("E:/Projects/Inferno/resources/textures/normals.png"); - plane.material->NormalTexture = new Texture("/home/ben/programming/inferno/resources/textures/normals.png"); + Plane plane({ 0.0f, -1.0f, 0.0f }, { 0.0f, -1.0f, 0.0f }, new Material({ 0.2f, 0.2f, 0.2f })); scene->objects.push_back(&plane); inferno.SetScene(scene);