Fresnel Reflections
This commit is contained in:
@@ -4,13 +4,12 @@ project(Inferno)
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} CMakeModules/)
|
||||
cmake_policy(SET CMP0037 OLD)
|
||||
#set(CMAKE_BUILD_TYPE Debug)
|
||||
#set(CMAKE_CXX_FLAGS "-g")
|
||||
set(CMAKE_CXX_FLAGS "-Ofast -mtune=native")
|
||||
set(CMAKE_CXX_FLAGS "-Ofast")
|
||||
|
||||
set(executable output)
|
||||
set(SrcDIR ./src)
|
||||
set(TestDIR ./test)
|
||||
set(CurrentTest stanford_dragon_cornell.cpp)
|
||||
set(CurrentTest main.cpp)
|
||||
|
||||
set(IncludeDIR ./include)
|
||||
|
||||
|
||||
@@ -8,16 +8,6 @@ Material::Material() {
|
||||
|
||||
}
|
||||
|
||||
Material::Material(glm::vec3 col, float specularity, float emittance)
|
||||
: Colour(col),
|
||||
Emittance(emittance) {
|
||||
Transparent = false;
|
||||
if (Emittance > 0.0f) { Emissive = true; }
|
||||
else { Emissive = false; }
|
||||
|
||||
Specularity = specularity;
|
||||
}
|
||||
|
||||
Material::Material(glm::vec3 colour, float emittance, float specularity, float index, float gloss, bool transparent, bool emissive)
|
||||
: Colour(colour),
|
||||
Emittance(emittance),
|
||||
@@ -31,44 +21,25 @@ Material::Material(glm::vec3 colour, float emittance, float specularity, float i
|
||||
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) {
|
||||
return CosineBRDF(normal);
|
||||
}
|
||||
|
||||
float r;
|
||||
if (Specularity == 1.0f) {
|
||||
return Reflect(in, normal);
|
||||
r = 1.0f;
|
||||
} else {
|
||||
r = rand01();
|
||||
}
|
||||
|
||||
float r = rand01();
|
||||
float fresnel = FresnelReflect(this, normal, in);
|
||||
|
||||
if (r > Specularity) {
|
||||
if (r > fresnel) {
|
||||
return CosineBRDF(normal);
|
||||
} else {
|
||||
glm::vec3 reflect = Reflect(in, normal);
|
||||
|
||||
|
||||
if (Gloss == 0.0f)
|
||||
return reflect;
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ class Texture;
|
||||
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);
|
||||
@@ -30,7 +29,7 @@ public:
|
||||
|
||||
class GlossyMaterial : public Material {
|
||||
public:
|
||||
GlossyMaterial(glm::vec3 colour, float shine, float gloss)
|
||||
GlossyMaterial(glm::vec3 colour, float shine, float gloss, float index = 1.5f)
|
||||
: Material(colour, 0.0f, shine, 1.0f, gloss, false, false) { };
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,55 @@
|
||||
#include "specular.hpp"
|
||||
|
||||
#include "random.hpp"
|
||||
#include "material.hpp"
|
||||
|
||||
glm::vec3 Reflect(glm::vec3 I, glm::vec3 N) {
|
||||
return I - 2 * glm::dot(I, N) * N;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
float FresnelReflect (Material* mat, glm::vec3 normal, glm::vec3 incident) {
|
||||
float n1 = 1.0f;
|
||||
float n2 = mat->Index;
|
||||
|
||||
// Schlick aproximation
|
||||
float r0 = (n1-n2) / (n1+n2);
|
||||
r0 *= r0;
|
||||
float cosX = -glm::dot(normal, incident);
|
||||
if (n1 > n2) {
|
||||
float n = n1/n2;
|
||||
float sinT2 = n*n*(1.0-cosX*cosX);
|
||||
// Total internal reflection
|
||||
if (sinT2 > 1.0)
|
||||
return 1.0;
|
||||
cosX = sqrt(1.0-sinT2);
|
||||
}
|
||||
float x = 1.0-cosX;
|
||||
float ret = r0+(1.0-r0)*x*x*x*x*x;
|
||||
|
||||
ret = (mat->Specularity + (1.0 - mat->Specularity) * ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
|
||||
#include "../../maths.hpp"
|
||||
|
||||
class Material;
|
||||
|
||||
glm::vec3 Reflect(glm::vec3 I, glm::vec3 N);
|
||||
glm::vec3 ConeBounce(glm::vec3 reflectDir, float theta);
|
||||
float FresnelReflect (Material* mat, glm::vec3 normal, glm::vec3 incident);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,6 +7,7 @@ bool Plane::Intersect(Ray& ray, float& t) {
|
||||
glm::vec3 v = center - ray.origin;
|
||||
float distance = glm::dot(v, normal) / dNormal;
|
||||
if (distance >= 0.0f) {
|
||||
if (distance > 20.0f) return false;
|
||||
t = distance;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ private:
|
||||
// and are used to set them, must be indexed correctly
|
||||
// according to the enums
|
||||
int m_renderModeSelected = 0;
|
||||
int m_toneMapModeSelected = 0;
|
||||
int m_toneMapModeSelected = 1;
|
||||
|
||||
|
||||
int m_framesRendererd = 0;
|
||||
|
||||
@@ -78,9 +78,6 @@ glm::vec3 RenderEngine::GetColour(Ray ray, int& depth) {
|
||||
float t = INFINITY; Primative* hit = nullptr;
|
||||
bool didhit = TraceRayScene(ray, m_scene, t, hit);
|
||||
if (!didhit) {
|
||||
if (depth > 0) {
|
||||
return m_scene->SampleSky(ray) * 0.2f;
|
||||
}
|
||||
return m_scene->SampleSky(ray);
|
||||
}
|
||||
|
||||
@@ -89,20 +86,28 @@ glm::vec3 RenderEngine::GetColour(Ray ray, int& depth) {
|
||||
if (Mode == MODE_RENDER_NORMALS) { return GetNormalColour(normal); }
|
||||
if (Mode == MODE_RENDER_PATH_LENGTH) { if (t > 255.0f) t = 255.0f; return { (float)t, (float)t, (float)t }; }
|
||||
|
||||
glm::vec3 colour = hit->material->Colour;
|
||||
//if (hit->type == TYPE_PLANE) {
|
||||
// glm::vec2 uv = hit->TexCoords(hitPoint);
|
||||
// float angle = fastDegreetoRadian(.0f);
|
||||
// float s = uv.x * cos(angle) - uv.y * sin(angle);
|
||||
// float t = uv.y * cos(angle) + uv.x * sin(angle);
|
||||
// float S = 0.4f; float T = 0.4f;
|
||||
// float pattern = (modulo(s * S) < 0.5f) ^ (modulo(t * T) < 0.5f);
|
||||
// colour.r = pattern; colour.g = pattern; colour.b = pattern;
|
||||
//}
|
||||
Material* mat = hit->material;
|
||||
glm::vec3 colour = mat->Colour;
|
||||
|
||||
if (hit->material->Emissive) return (colour * hit->material->Emittance);
|
||||
if (hit->type == TYPE_PLANE) {
|
||||
glm::vec2 uv = hit->TexCoords(hitPoint);
|
||||
float angle = fastDegreetoRadian(.0f);
|
||||
float s = uv.x * cos(angle) - uv.y * sin(angle);
|
||||
float t = uv.y * cos(angle) + uv.x * sin(angle);
|
||||
float S = 0.4f; float T = 0.4f;
|
||||
float pattern = (modulo(s * S) < 0.5f) ^ (modulo(t * T) < 0.5f);
|
||||
if (pattern == 1) {
|
||||
mat->Specularity = 0.9f;
|
||||
mat->Gloss = fastRadianToDegree(0.02f);
|
||||
} else {
|
||||
mat->Specularity = 0.9f;
|
||||
mat->Gloss = fastRadianToDegree(0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 direction = hit->material->Bounce(ray.direction, normal);
|
||||
if (mat->Emissive) return (colour * mat->Emittance);
|
||||
|
||||
glm::vec3 direction = mat->Bounce(ray.direction, normal);
|
||||
|
||||
Ray newRay{ hitPoint, direction };
|
||||
|
||||
|
||||
43
test/lucy_cornell.cpp
Normal file
43
test/lucy_cornell.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "../src/inferno.hpp"
|
||||
|
||||
static const int width = 600;
|
||||
static const int height = 600;
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
InfernoEngine inferno;
|
||||
|
||||
inferno.SetMode(MODE_OPERATION_PROGRESSIVE_GUI);
|
||||
|
||||
inferno.InitWindow(width, height);
|
||||
|
||||
Scene* scene = new Scene(width, height);
|
||||
scene->camera = new Camera(width, height);
|
||||
|
||||
Sky* sky = new SolidSky({ 0.0f, 0.0f, 0.0f }, 0.0f);
|
||||
scene->sky = sky;
|
||||
|
||||
Material* mat = new GlossyMaterial({ 1.0f, 1.0f, 1.0f }, 0.2f, fastDegreetoRadian(30.0f));
|
||||
//std::vector<Triangle*> tris = LoadTrianglesBasic("E://Projects//Inferno//resources//models//dragon-cornell-size.obj", "E://Projects//Inferno//resources//models", mat);
|
||||
// std::vector<Triangle*> tris = LoadTrianglesBasic("/home/ben/programming/inferno/resources/models/dragon-cornell-size.obj", "/home/ben/programming/inferno/resources/models/", mat);
|
||||
|
||||
//Mesh* mesh = new Mesh(tris);
|
||||
//mesh->Translate({ 0.01f, -1.0, -3.6f });
|
||||
//mesh->Optimise();
|
||||
//scene->meshs.push_back(mesh);
|
||||
|
||||
// std::vector<Triangle*> tris1 = LoadTrianglesBasic("E://Projects//Inferno//resources//models//cornell-box.obj", "E://Projects//Inferno//resources//models//");
|
||||
std::vector<Triangle*> tris1 = LoadTrianglesBasic("/home/ben/programming/inferno/resources/models/cornell-box.obj", "/home/ben/programming/inferno/resources/models/");
|
||||
|
||||
Mesh* mesh1 = new Mesh(tris1);
|
||||
mesh1->Translate({ 0.01f, -1.0, -3.6f });
|
||||
scene->meshs.push_back(mesh1);
|
||||
|
||||
inferno.SetScene(scene);
|
||||
|
||||
inferno.Ready();
|
||||
inferno.Render();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
#include "../src/inferno.hpp"
|
||||
|
||||
static const int width = 1000;
|
||||
static const int height = 1000;
|
||||
static const int width = 700;
|
||||
static const int height = 700;
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
InfernoEngine inferno;
|
||||
@@ -18,7 +18,7 @@ int main(int argc, char** argv) {
|
||||
|
||||
Scene* scene = new Scene(width, height);
|
||||
|
||||
Sky* sky = new GradientSky({ 35.0f / 255.0f, 148.0f / 255.0f, 235.0f / 255.0f }, { 1.0f, 1.0f, 1.0f }, 5.0f);
|
||||
Sky* sky = new GradientSky({ 35.0f / 255.0f, 148.0f / 255.0f, 235.0f / 255.0f }, { 1.0f, 1.0f, 1.0f }, 3.0f);
|
||||
scene->sky = sky;
|
||||
|
||||
scene->camera = new Camera(width, height);
|
||||
@@ -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({ -2.1f, 0.0f, -8.0f }, 1.0f, new GlossyMaterial({ 0.817f, 0.374, 0.574 }, 0.5f, fastDegreetoRadian(0.0f)));
|
||||
Sphere sphere({ -2.1f, 0.0f, -8.0f }, 1.0f, new Material({ 0.817f, 0.374, 0.574 }, 0.0f, 0.0f, 0.0f, 0.0f, false, false));
|
||||
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)));
|
||||
Sphere sphere1({ 0.0f, 0.0f, -8.0f }, 1.0f, new GlossyMaterial({ 0.817f, 0.374, 0.574 }, 0.7f, fastDegreetoRadian(30.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)));
|
||||
Sphere sphere2({ 2.1f, 0.0f, -8.0f }, 1.0f, new GlossyMaterial({ 0.817f, 0.374, 0.574 }, 0.7f, fastDegreetoRadian(60.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));
|
||||
Sphere light({ 35.0f, 50.0f, 25.0f }, 25.0f, new Material({ 1.0f, 1.0f, 1.0f }, 100.0f, 0.0f, 1.5f, 0.0f, false, true));
|
||||
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 plane({ 0.0f, -1.0f, 0.0f }, { 0.0f, -1.0f, 0.0f }, new Material({ 0.2f, 0.2f, 0.2f }, 0.0f, 0.0f, 1.5f, 0.0f, false, false));
|
||||
scene->objects.push_back(&plane);
|
||||
|
||||
inferno.SetScene(scene);
|
||||
|
||||
@@ -18,26 +18,20 @@ int main(int argc, char** argv) {
|
||||
Sky* sky = new SolidSky({ 0.0f, 0.0f, 0.0f }, 0.0f);
|
||||
scene->sky = sky;
|
||||
|
||||
//Sphere* sphere = new Sphere({ -0.302, -0.385999, -3.74202 }, 0.03f, new Material({ 0.345f, 0.133f, 0.050f }, 300.0f, 0.0f, 0.0f, 0.0f, false, true));
|
||||
//scene->objects.push_back(sphere);
|
||||
|
||||
Plane* plane = new Plane({ 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f }, new Material({ 1.0f, 1.0f, 1.0f }, 0.0f, 0.0f, 0.0f, 0.0f, false, false));
|
||||
scene->objects.push_back(plane);
|
||||
|
||||
Material* mat = new GlossyMaterial({ 1.3f, 1.3f, 1.3f }, 0.2f, fastDegreetoRadian(30.0f));
|
||||
//std::vector<Triangle*> tris = LoadTrianglesBasic("E://Projects//Inferno//resources//models//dragon-cornell-size.obj", "E://Projects//Inferno//resources//models", mat);
|
||||
// std::vector<Triangle*> tris = LoadTrianglesBasic("/home/ben/programming/inferno/resources/models/dragon-cornell-size.obj", "/home/ben/programming/inferno/resources/models/", mat);
|
||||
|
||||
Sphere* sphere = new Sphere({ 0.0f, -0.6f, -4.0f }, 0.4f, mat);
|
||||
Sphere* sphere = new Sphere({ -0.302, -0.385999, -3.74202 }, 0.03f, new Material({ 0.345f, 0.133f, 0.050f }, 300.0f, 0.0f, 0.0f, 0.0f, false, true));
|
||||
scene->objects.push_back(sphere);
|
||||
|
||||
Material* mat = new GlossyMaterial({ 1.0f, 1.0f, 1.0f }, 0.2f, fastDegreetoRadian(30.0f));
|
||||
//std::vector<Triangle*> tris = LoadTrianglesBasic("E://Projects//Inferno//resources//models//dragon-cornell-size.obj", "E://Projects//Inferno//resources//models", mat);
|
||||
std::vector<Triangle*> tris = LoadTrianglesBasic("/home/ben/programming/inferno/resources/models/dragon-cornell-size.obj", "/home/ben/programming/inferno/resources/models/", mat);
|
||||
|
||||
//Mesh* mesh = new Mesh(tris);
|
||||
//mesh->Translate({ 0.01f, -1.0, -3.6f });
|
||||
//mesh->Optimise();
|
||||
//scene->meshs.push_back(mesh);
|
||||
|
||||
std::vector<Triangle*> tris1 = LoadTrianglesBasic("E://Projects//Inferno//resources//models//cornell-box.obj", "E://Projects//Inferno//resources//models//");
|
||||
//std::vector<Triangle*> tris1 = LoadTrianglesBasic("/home/ben/programming/inferno/resources/models/cornell-box.obj", "/home/ben/programming/inferno/resources/models/");
|
||||
// std::vector<Triangle*> tris1 = LoadTrianglesBasic("E://Projects//Inferno//resources//models//cornell-box.obj", "E://Projects//Inferno//resources//models//");
|
||||
std::vector<Triangle*> tris1 = LoadTrianglesBasic("/home/ben/programming/inferno/resources/models/cornell-box.obj", "/home/ben/programming/inferno/resources/models/");
|
||||
|
||||
Mesh* mesh1 = new Mesh(tris1);
|
||||
mesh1->Translate({ 0.01f, -1.0, -3.6f });
|
||||
|
||||
Reference in New Issue
Block a user