150 lines
4.4 KiB
C++
150 lines
4.4 KiB
C++
#include "renderengine.hpp"
|
|
|
|
#include "../pixel.hpp"
|
|
#include "../util/threadpool.hpp"
|
|
|
|
#include "../definitions/materials/material.hpp"
|
|
#include "../definitions/materials/texture.hpp"
|
|
#include "../definitions/materials/random.hpp"
|
|
|
|
#include "../definitions/primatives/primative.hpp"
|
|
#include "../definitions/camera.hpp"
|
|
#include "../definitions/scene.hpp"
|
|
#include "../definitions/ray.hpp"
|
|
|
|
#include "../display/displayinterface.hpp"
|
|
#include "../display/framebuffer.hpp"
|
|
|
|
#include "../engine/renderengine.hpp"
|
|
#include "../engine/progressiverenderer.hpp"
|
|
|
|
static glm::vec3 Black{ 0.0f, 0.0f, 0.0f };
|
|
static glm::vec3 White{ 1.0f, 1.0f, 1.0f };
|
|
static glm::vec3 Red { 1.0f, 0.2f, 0.2f };
|
|
static glm::vec3 Green{ 0.2f, 1.0f, 0.2f };
|
|
static glm::vec3 Blue { 0.2f, 0.2f, 1.0f };
|
|
|
|
void workerThread(RenderThreadPool* threadpool, ProgressiveRenderer* renderer, int idd, int yStart, int yRange) {
|
|
while (!renderer->Ready && !threadpool->Ready) {
|
|
static std::chrono::milliseconds dura(10);
|
|
std::this_thread::sleep_for(dura);
|
|
}
|
|
|
|
while (renderer->Ready && threadpool->Ready) {
|
|
|
|
for (int y = yStart; y < yStart + yRange; y++)
|
|
for (int x = 0; x < renderer->m_scene->w; x++) {
|
|
|
|
Ray ray = {};
|
|
|
|
if (renderer->MXAA)
|
|
ray = renderer->m_scene->camera->CastRay(x, y, rand01(), rand01());
|
|
else
|
|
ray = renderer->m_scene->camera->CastRay(x, y);
|
|
|
|
int depth = 0;
|
|
glm::vec3 col = renderer->m_engine->GetColour(ray, depth);
|
|
|
|
if (renderer->m_engine->Mode == MODE_RENDER_NORMALS || renderer->m_engine->Mode == MODE_RENDER_PATH_LENGTH) {
|
|
threadpool->ThreadFrameBuffer->SetPixelSafe(x, y, col, (int)renderer->m_engine->Mode);
|
|
} else if (renderer->m_engine->Mode == MODE_RENDER_PATH_BOUNCES) {
|
|
col.r = depth; col.g = depth / 3.0f; col.b = depth / 3.0f;
|
|
threadpool->ThreadFrameBuffer->AddPixelSafe(x, y, col, (int)renderer->m_engine->Mode);
|
|
} else {
|
|
threadpool->ThreadFrameBuffer->AddPixelSafe(x, y, col, (int)renderer->m_engine->Mode);
|
|
}
|
|
}
|
|
|
|
threadpool->ThreadStatus[idd] = true;
|
|
|
|
while (threadpool->ThreadStatus[idd]) {
|
|
static std::chrono::nanoseconds dura(1);
|
|
std::this_thread::sleep_for(dura);
|
|
}
|
|
}
|
|
}
|
|
|
|
RenderEngine::RenderEngine() {
|
|
|
|
}
|
|
|
|
void RenderEngine::SetScene(Scene* scene) {
|
|
m_scene = scene;
|
|
}
|
|
|
|
glm::vec3 RenderEngine::GetColour(Ray ray, int& depth) {
|
|
if (depth > 5) return { 0.0f, 0.0f, 0.0f };
|
|
|
|
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);
|
|
}
|
|
|
|
glm::vec3 hitPoint = ray.origin + ray.direction * t;
|
|
glm::vec3 normal = hit->Normal(hitPoint);
|
|
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;
|
|
//}
|
|
|
|
if (hit->material->Emissive) return (colour * hit->material->Emittance);
|
|
|
|
glm::vec3 direction = hit->material->Bounce(ray.direction, normal);
|
|
|
|
Ray newRay{ hitPoint, direction };
|
|
|
|
// Prevent acne
|
|
if (glm::dot(newRay.direction, normal) < 0.0f) {
|
|
newRay.origin = ray.origin + ray.direction * t - normal * EPSILON;
|
|
} else {
|
|
newRay.origin = ray.origin + ray.direction * t + normal * EPSILON;
|
|
}
|
|
|
|
depth++;
|
|
return GetColour(newRay, depth) * colour;
|
|
}
|
|
|
|
void RenderEngine::PostProcess(glm::vec3* src, glm::vec3* dst, int w, int h) {
|
|
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++) {
|
|
dst[y * w + x] = src[y * w + x];
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (Mode == MODE_RENDER_PATH_BOUNCES) {
|
|
SPP = 0;
|
|
SPPDepth++;
|
|
for (int y = 0; y < h; y++)
|
|
for (int x = 0; x < w; x++) {
|
|
dst[y * w + x] = src[y * w + x] / (float)SPPDepth;
|
|
}
|
|
return;
|
|
}
|
|
|
|
SPP++;
|
|
for (int y = 0; y < h; y++)
|
|
for (int x = 0; x < w; x++) {
|
|
dst[y * w + x] = src[y * w + x] / (float)SPP;
|
|
}
|
|
}
|
|
|
|
glm::vec3 RenderEngine::GetNormalColour(glm::vec3 normal) {
|
|
return ((normal + 1.0f) * 127.5f) / 255.0f;
|
|
}
|