Proper specular gloss using cone bounces
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <glm/gtx/rotate_vector.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <math.h>
|
||||
@@ -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<float> 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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user