From f7ce947030f3428142ef0787403ca78492e62acb Mon Sep 17 00:00:00 2001 From: Ben Date: Thu, 5 Sep 2019 23:32:52 +0100 Subject: [PATCH] Specularity --- resources/cornell.mtl | 2 +- src/common.hpp | 3 ++- src/definitions/materials/BRDF.cpp | 9 +------- src/definitions/materials/material.cpp | 29 +++++++++++++++++++++---- src/definitions/materials/material.hpp | 20 ++++++++--------- src/definitions/materials/specular.cpp | 5 +++++ src/definitions/materials/specular.hpp | 8 +++++++ src/definitions/materials/texture.hpp | 20 +++++++++++++++++ src/definitions/primatives/plane.cpp | 1 - src/definitions/primatives/plane.hpp | 2 +- src/definitions/primatives/sphere.hpp | 2 +- src/definitions/primatives/triangle.hpp | 2 +- src/definitions/scene.cpp | 1 + src/engine/progressiverenderer.cpp | 9 ++++---- src/engine/renderengine.cpp | 23 ++++++++++++++------ src/maths.hpp | 2 +- src/util/assetloader.cpp | 2 +- test/main.cpp | 22 ++++++++++--------- 18 files changed, 110 insertions(+), 52 deletions(-) create mode 100644 src/definitions/materials/specular.cpp create mode 100644 src/definitions/materials/specular.hpp create mode 100644 src/definitions/materials/texture.hpp diff --git a/resources/cornell.mtl b/resources/cornell.mtl index 73014d7..0b2dbe3 100644 --- a/resources/cornell.mtl +++ b/resources/cornell.mtl @@ -50,7 +50,7 @@ Ks 0.000000 0.000000 0.000000 Ke 0.000000 0.000000 0.000000 Ni 1.000000 d 1.000000 -illum 30 +illum 10------- newmtl rightWall Ns 9.803922 diff --git a/src/common.hpp b/src/common.hpp index 7cb6a6a..c55180e 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -23,7 +23,8 @@ enum OperationMode { enum RenderMode { MODE_RENDER_PATHTRACE, MODE_RENDER_NORMALS, - MODE_RENDER_PATHLENGTH, + MODE_RENDER_PATH_BOUNCES, + MODE_RENDER_PATH_LENGTH, MODE_RENDER_DEFAULT }; diff --git a/src/definitions/materials/BRDF.cpp b/src/definitions/materials/BRDF.cpp index 0c118b7..67dd6b5 100644 --- a/src/definitions/materials/BRDF.cpp +++ b/src/definitions/materials/BRDF.cpp @@ -1,13 +1,6 @@ #include "BRDF.hpp" -#include - -std::default_random_engine generator; - -float rand01() { - std::uniform_real_distribution distribution(0, 1); - return distribution(generator); -} +#include "random.hpp" glm::vec3 CosineBRDF(glm::vec3 normal) { const float TWO_PI = 2.0f * PI; diff --git a/src/definitions/materials/material.cpp b/src/definitions/materials/material.cpp index fa2671a..1232c5e 100644 --- a/src/definitions/materials/material.cpp +++ b/src/definitions/materials/material.cpp @@ -1,18 +1,39 @@ #include "material.hpp" +#include "specular.hpp" +#include "random.hpp" #include "BRDF.hpp" Material::Material() { } -Material::Material(glm::vec3 col, float emittance) +Material::Material(glm::vec3 col, float specularity, float emittance) : Colour(col), - Emittance(emittance) { - if (Emittance > 0.0f) { Emissive = true; } else { Emissive = false; } + Emittance(emittance) { + Transparent = false; + if (Emittance > 0.0f) { Emissive = true; } + else { Emissive = false; } + Specularity = specularity; } + glm::vec3 Material::Bounce(glm::vec3 in, glm::vec3 normal) { - return CosineBRDF(normal); + if (Specularity == 0.0f) { + return CosineBRDF(normal); + } + + if (Specularity == 1.0f) { + return Reflect(in, normal); + } + + float r = rand01(); + + if (r > Specularity) { + return CosineBRDF(normal); + } else { + return Reflect(in, normal); + } + } diff --git a/src/definitions/materials/material.hpp b/src/definitions/materials/material.hpp index 73f648f..4d47c87 100644 --- a/src/definitions/materials/material.hpp +++ b/src/definitions/materials/material.hpp @@ -4,25 +4,25 @@ #include "../../common.hpp" #include "../../maths.hpp" -class Texture {}; +class Texture; class Material { public: Material(); - Material(glm::vec3 col, float emittance = 0.0f); + Material(glm::vec3 col, float specularity, float emmitance = 0.0f); glm::vec3 Bounce(glm::vec3 in, glm::vec3 normal); glm::vec3 Colour; - // Texture* Tex; - // Texture* NormalTexture; - // Texture* MetalnessTexture; - // Texture* GlossTexture; + Texture* Tex; + Texture* NormalTexture; + Texture* GlossTexture; float Emittance; - float Index; // refractive index - float Gloss; // reflection cone angle in radians - float Tint; // specular and refractive tinting - float Reflectivity; // metallic reflection + float Specularity; // 1.0f = perfect reflective + // 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; }; diff --git a/src/definitions/materials/specular.cpp b/src/definitions/materials/specular.cpp new file mode 100644 index 0000000..d8d8491 --- /dev/null +++ b/src/definitions/materials/specular.cpp @@ -0,0 +1,5 @@ +#include "specular.hpp" + +glm::vec3 Reflect(glm::vec3 I, glm::vec3 N) { + return I - 2 * glm::dot(I, N) * N; +} diff --git a/src/definitions/materials/specular.hpp b/src/definitions/materials/specular.hpp new file mode 100644 index 0000000..eee8f22 --- /dev/null +++ b/src/definitions/materials/specular.hpp @@ -0,0 +1,8 @@ +#ifndef INFERNO_DEFINITIONS_MATERIALS_SPECULAR_H_ +#define INFERNO_DEFINITIONS_MATERIALS_SPECULAR_H_ + +#include "../../maths.hpp" + +glm::vec3 Reflect(glm::vec3 I, glm::vec3 N); + +#endif diff --git a/src/definitions/materials/texture.hpp b/src/definitions/materials/texture.hpp new file mode 100644 index 0000000..9ab6932 --- /dev/null +++ b/src/definitions/materials/texture.hpp @@ -0,0 +1,20 @@ +#ifndef INFERNO_DEFINITIONS_MATERIALS_TEXTURE_H_ +#define INFERNO_DEFINITIONS_MATERIALS_TEXTURE_H_ + +#include "../../common.hpp" + +class Texture { +public: + Texture(); + + void Load(std::string texturePath); + + glm::vec3 Sample(float u, float v); + glm::vec3 SampleNormal(float u, float v); +// glm::vec3 SampleSpecular (float u, float v); + +private: + +}; + +#endif diff --git a/src/definitions/primatives/plane.cpp b/src/definitions/primatives/plane.cpp index 07b061a..843db82 100644 --- a/src/definitions/primatives/plane.cpp +++ b/src/definitions/primatives/plane.cpp @@ -2,7 +2,6 @@ #include "../ray.hpp" bool Plane::Intersect(Ray& ray, float& t) { - t = INFINITY; float dNormal = glm::dot(normal, ray.direction); if (dNormal > 1e-6) { glm::vec3 v = center - ray.origin; diff --git a/src/definitions/primatives/plane.hpp b/src/definitions/primatives/plane.hpp index b0c28b3..af24c6f 100644 --- a/src/definitions/primatives/plane.hpp +++ b/src/definitions/primatives/plane.hpp @@ -5,7 +5,7 @@ class Plane : public Primative { public: - Plane(glm::vec3 center, glm::vec3 normal, Material* mat = nullptr) + Plane(glm::vec3 center, glm::vec3 normal, Material* mat = new Material()) : Primative(center, normal, mat) { } bool Intersect(Ray& ray, float& t) override; diff --git a/src/definitions/primatives/sphere.hpp b/src/definitions/primatives/sphere.hpp index 7d0deb3..b5ffe41 100644 --- a/src/definitions/primatives/sphere.hpp +++ b/src/definitions/primatives/sphere.hpp @@ -5,7 +5,7 @@ class Sphere : public Primative { public: - Sphere(glm::vec3 center, float radius, Material* mat = nullptr) + Sphere(glm::vec3 center, float radius, Material* mat = new Material()) : Primative(center, radius, mat) { } bool Intersect(Ray& ray, float& t) override; diff --git a/src/definitions/primatives/triangle.hpp b/src/definitions/primatives/triangle.hpp index 2f79d1b..6d3e953 100644 --- a/src/definitions/primatives/triangle.hpp +++ b/src/definitions/primatives/triangle.hpp @@ -5,7 +5,7 @@ class Triangle : public Primative { public: - Triangle(glm::vec3 p0, glm::vec3 p1, glm::vec3 p2, glm::vec3 n0, glm::vec3 n1, glm::vec3 n2, Material* mat = nullptr) + Triangle(glm::vec3 p0, glm::vec3 p1, glm::vec3 p2, glm::vec3 n0, glm::vec3 n1, glm::vec3 n2, Material* mat = new Material()) : Primative(p0, p1, p2, n0, n1, n2, mat) { } bool Intersect(Ray& ray, float& t) override; diff --git a/src/definitions/scene.cpp b/src/definitions/scene.cpp index 659e703..0c8eb47 100644 --- a/src/definitions/scene.cpp +++ b/src/definitions/scene.cpp @@ -8,5 +8,6 @@ Scene::Scene(int width, int height) { } glm::vec3 Scene::SampleSky(Ray ray) { + // return { 0.9f, 0.9f, 0.9f }; return { 0.0f, 0.0f, 0.0f }; } diff --git a/src/engine/progressiverenderer.cpp b/src/engine/progressiverenderer.cpp index f8efe61..18c1ac7 100644 --- a/src/engine/progressiverenderer.cpp +++ b/src/engine/progressiverenderer.cpp @@ -40,7 +40,7 @@ void ProgressiveRenderer::Input() { while (SDL_PollEvent(&e)) if (e.type == SDL_QUIT) m_interface->Close(); - //const Uint8* state = SDL_GetKeyboardState(NULL); + const Uint8* state = SDL_GetKeyboardState(NULL); //if (state[SDL_SCANCODE_W]) m_scene->objects[0]->center.y += 0.01f; //if (state[SDL_SCANCODE_S]) m_scene->objects[0]->center.y -= 0.01f; @@ -52,11 +52,10 @@ void ProgressiveRenderer::Input() { ImGui::NewFrame(); ImGui::Begin("Debug"); - if (m_engine->Mode != MODE_RENDER_NORMALS && m_engine->Mode != MODE_RENDER_PATHLENGTH) { + if (m_engine->Mode == MODE_RENDER_PATHTRACE) { std::stringstream str; str << "SPP: " << m_engine->SPP; ImGui::Text(str.str().c_str()); - } - else if (m_engine->Mode == MODE_RENDER_PATHLENGTH) { + } else if (m_engine->Mode == MODE_RENDER_PATH_BOUNCES) { std::stringstream str; str << "Depth SPP: " << m_engine->SPPDepth; ImGui::Text(str.str().c_str()); } @@ -74,7 +73,7 @@ void ProgressiveRenderer::Input() { } ImGui::PlotLines("FrameTimes", FrameTimes.data(), FrameTimes.size(), 0, NULL, lower, upper, ImVec2(0, 40)); - const char* renderItems[] = { "PathTrace", "Normals", "Path Length" }; + const char* renderItems[] = { "PathTrace", "Normals", "Path Bounces", "Path Length" }; ImGui::Combo("Render Mode", &m_renderModeSelected, renderItems, IM_ARRAYSIZE(renderItems)); m_mode = (RenderMode)m_renderModeSelected; diff --git a/src/engine/renderengine.cpp b/src/engine/renderengine.cpp index debcc6d..a823777 100644 --- a/src/engine/renderengine.cpp +++ b/src/engine/renderengine.cpp @@ -45,9 +45,9 @@ void workerThread(RenderThreadPool* threadpool, ProgressiveRenderer* renderer, i int depth = 0; glm::vec3 col = renderer->m_engine->GetColour(ray, depth); - if (renderer->m_engine->Mode == MODE_RENDER_NORMALS) { + if (renderer->m_engine->Mode == MODE_RENDER_NORMALS || renderer->m_engine->Mode == MODE_RENDER_PATH_LENGTH) { threadpool->MappedThreadFrameBuffer->SetPixelSafe(x, y, col); - } else if (renderer->m_engine->Mode == MODE_RENDER_PATHLENGTH) { + } else if (renderer->m_engine->Mode == MODE_RENDER_PATH_BOUNCES) { col.r = depth; col.g = depth / 3.0f; col.b = depth / 3.0f; threadpool->MappedThreadFrameBuffer->AddPixelSafeDepth(x, y, col); } else { @@ -75,15 +75,25 @@ void RenderEngine::SetScene(Scene* scene) { glm::vec3 RenderEngine::GetColour(Ray ray, int& depth) { if (depth > 5) return { 0.0f, 0.0f, 0.0f }; - float t; Primative* hit = nullptr; + float t = INFINITY; Primative* hit = nullptr; bool didhit = TraceRayScene(ray, m_scene, t, hit); if (!didhit) return m_scene->SampleSky(ray); glm::vec3 hitPoint = ray.origin + ray.direction * t; glm::vec3 normal = hit->SurfaceNormal(hitPoint); if (Mode == MODE_RENDER_NORMALS) { return GetNormalColour(normal); } + if (Mode == MODE_RENDER_PATH_LENGTH) { if (t > 1000.0f) t = 1000.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.5f; float T = 0.5f; + // float pattern = (modulo(s * S) < 0.5f) ^ (modulo(t * T) < 0.5f); + // colour.r = pattern; colour.g = pattern; colour.b = pattern; + //} if (hit->material->Emissive) return (colour * hit->material->Emittance); @@ -94,8 +104,7 @@ glm::vec3 RenderEngine::GetColour(Ray ray, int& depth) { // Prevent acne if (glm::dot(newRay.direction, normal) < 0.0f) { newRay.origin = ray.origin + ray.direction * t - normal * EPSILON; - } - else { + } else { newRay.origin = ray.origin + ray.direction * t + normal * EPSILON; } @@ -104,7 +113,7 @@ glm::vec3 RenderEngine::GetColour(Ray ray, int& depth) { } void RenderEngine::PostProcess(glm::vec3* src, glm::vec3* dst, int w, int h) { - if (Mode == MODE_RENDER_NORMALS) { + if (Mode == MODE_RENDER_NORMALS || Mode == MODE_RENDER_PATH_LENGTH) { SPP = 0; for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { @@ -113,7 +122,7 @@ void RenderEngine::PostProcess(glm::vec3* src, glm::vec3* dst, int w, int h) { return; } - if (Mode == MODE_RENDER_PATHLENGTH) { + if (Mode == MODE_RENDER_PATH_BOUNCES) { SPP = 0; SPPDepth++; for (int y = 0; y < h; y++) diff --git a/src/maths.hpp b/src/maths.hpp index d10ace9..089bc36 100644 --- a/src/maths.hpp +++ b/src/maths.hpp @@ -13,7 +13,7 @@ const float DEG2RAD = 0.01745329251994329576923690768f; const float RAD2DEG = 57.2957795130823208767981548141f; const float PI = 3.14159265358979323846264338327f; -const float EPSILON = 0.00001000000000000000000000000f; +const float EPSILON = 0.00000100000000000000000000000f; enum Axis { AXIS_X, diff --git a/src/util/assetloader.cpp b/src/util/assetloader.cpp index 8af1b24..1ddc76d 100644 --- a/src/util/assetloader.cpp +++ b/src/util/assetloader.cpp @@ -68,7 +68,7 @@ std::vector LoadTrianglesBasic(std::string path, std::string basePath tinyobj::material_t material = materials[shapes[s].mesh.material_ids[f]]; - Material* mat = new Material({ material.diffuse[0], material.diffuse[1], material.diffuse[2] }, material.illum); + Material* mat = new Material({ material.diffuse[0], material.diffuse[1], material.diffuse[2] }, 0.0f, material.illum); // glm::vec3 normal = getNormal( // {avx[0], avy[0], avz[0]}, diff --git a/test/main.cpp b/test/main.cpp index f6997fb..5695deb 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -18,23 +18,25 @@ int main(int argc, char** argv) { Scene* scene = new Scene(width, height); scene->camera = new Camera(width, height); - //scene->objects.push_back(new Sphere({ 0.0f, 0.0f, -4.0f }, 1.0f)); - //scene->objects.push_back(new Sphere({ 2.0f, 0.0f, -8.0f }, 1.0f)); - //scene->objects.push_back(new Sphere({ -2.0f, 0.0f, -8.0f }, 1.0f)); - //scene->objects.push_back(new Plane( { 0.0f, -25.0f, 0.0f }, { 0.0f, -1.0f, 0.0f })); + scene->objects.push_back(new Sphere({ 0.6f, 0.0f, -3.5f }, 0.5f, new Material({ 1.0f, .5f, .5f }, 0.3f))); + //scene->objects.push_back(new Sphere({ 0.0f, 0.0f, -8.0f }, 1.0f, new Material({ 1.0f, 1.0f, 1.0f }, 0.7f))); + //scene->objects.push_back(new Sphere({ 2.0f, 0.0f, -6.0f }, 1.0f, new Material({ 1.0f, 1.0f, 1.0f }, 0.0f))); + //scene->objects.push_back(new Sphere({ -2.0f, 0.0f, -9.0f }, 1.0f, new Material({ 1.0f, 1.0f, 1.0f }, 0.0f))); + //scene->objects.push_back(new Plane( { 0.0f, -1.0f, 0.0f }, { 0.0f, -1.0f, 0.0f }, new Material({ 1.0f, 1.0f, 0.0f }, .3f))); //std::vector tris = LoadTrianglesBasic("E://Projects//Inferno//resources//dragon-normals.obj", "E://Projects//Inferno//resources"); //for (const auto& object : tris) // object->Translate({ 0.0f, -5.0f, -20.0f }); - std::vector tris = LoadTrianglesBasic("E://Projects//Inferno//resources//lucy-normals.obj", "E://Projects//Inferno//resources"); + //std::vector tris = LoadTrianglesBasic("E://Projects//Inferno//resources//lucy-normals.obj", "E://Projects//Inferno//resources"); - Mesh* mesh = new Mesh(tris); - mesh->Translate({ 0.0f, -1.01f, -3.0f }); - mesh->Optimise(); - scene->meshs.push_back(mesh); + //Mesh* mesh = new Mesh(tris); + //mesh->Translate({ 0.0f, -1.01f, -3.0f }); + //mesh->Optimise(); + //scene->meshs.push_back(mesh); - tris = LoadTrianglesBasic("E://Projects//Inferno//resources//cornell-box.obj", "E://Projects//Inferno//resources"); + //std::vector tris = LoadTrianglesBasic("E://Projects//Inferno//resources//cornell-box.obj", "E://Projects//Inferno//resources"); + std::vector tris = LoadTrianglesBasic("E://Projects//Inferno//resources//cornell.obj", "E://Projects//Inferno//resources"); Mesh* mesh1 = new Mesh(tris); mesh1->Translate({ 0.0f, -1.0f, -3.0f });