Fix shit
This commit is contained in:
@@ -1,102 +1,93 @@
|
||||
#pragma once
|
||||
|
||||
#include "Maths.h"
|
||||
|
||||
namespace dae
|
||||
{
|
||||
namespace BRDF
|
||||
{
|
||||
/**
|
||||
* \param kd Diffuse Reflection Coefficient
|
||||
* \param cd Diffuse Color
|
||||
* \return Lambert Diffuse Color
|
||||
*/
|
||||
static ColorRGB Lambert(float kd, const ColorRGB& cd)
|
||||
{
|
||||
//todo: W3
|
||||
throw std::runtime_error("Not Implemented Yet");
|
||||
return {};
|
||||
}
|
||||
namespace dae {
|
||||
namespace BRDF {
|
||||
/**
|
||||
* \param kd Diffuse Reflection Coefficient
|
||||
* \param cd Diffuse Color
|
||||
* \return Lambert Diffuse Color
|
||||
*/
|
||||
static ColorRGB Lambert(float kd, const ColorRGB &cd) {
|
||||
return (kd / PI) * cd;
|
||||
}
|
||||
|
||||
static ColorRGB Lambert(const ColorRGB& kd, const ColorRGB& cd)
|
||||
{
|
||||
//todo: W3
|
||||
throw std::runtime_error("Not Implemented Yet");
|
||||
return {};
|
||||
}
|
||||
static ColorRGB Lambert(const ColorRGB &kd, const ColorRGB &cd) {
|
||||
return (kd * PI) * cd;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief todo
|
||||
* \param ks Specular Reflection Coefficient
|
||||
* \param exp Phong Exponent
|
||||
* \param l Incoming (incident) Light Direction
|
||||
* \param v View Direction
|
||||
* \param n Normal of the Surface
|
||||
* \return Phong Specular Color
|
||||
*/
|
||||
static ColorRGB Phong(float ks, float exp, const Vector3& l, const Vector3& v, const Vector3& n)
|
||||
{
|
||||
//todo: W3
|
||||
throw std::runtime_error("Not Implemented Yet");
|
||||
return {};
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief BRDF Fresnel Function >> Schlick
|
||||
* \param h Normalized Halfvector between View and Light directions
|
||||
* \param v Normalized View direction
|
||||
* \param f0 Base reflectivity of a surface based on IOR (Indices Of Refrection), this is different for Dielectrics (Non-Metal) and Conductors (Metal)
|
||||
* \return
|
||||
*/
|
||||
static ColorRGB FresnelFunction_Schlick(const Vector3& h, const Vector3& v, const ColorRGB& f0)
|
||||
{
|
||||
//todo: W3
|
||||
throw std::runtime_error("Not Implemented Yet");
|
||||
return {};
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief BRDF NormalDistribution >> Trowbridge-Reitz GGX (UE4 implemetation - squared(roughness))
|
||||
* \param n Surface normal
|
||||
* \param h Normalized half vector
|
||||
* \param roughness Roughness of the material
|
||||
* \return BRDF Normal Distribution Term using Trowbridge-Reitz GGX
|
||||
*/
|
||||
static float NormalDistribution_GGX(const Vector3& n, const Vector3& h, float roughness)
|
||||
{
|
||||
//todo: W3
|
||||
throw std::runtime_error("Not Implemented Yet");
|
||||
return {};
|
||||
}
|
||||
/**
|
||||
* \brief todo
|
||||
* \param ks Specular Reflection Coefficient
|
||||
* \param exp Phong Exponent
|
||||
* \param l Incoming (incident) Light Direction
|
||||
* \param v View Direction
|
||||
* \param n Normal of the Surface
|
||||
* \return Phong Specular Color
|
||||
*/
|
||||
static ColorRGB Phong(float ks, float exp, const Vector3 &l, const Vector3 &v, const Vector3 &n) {
|
||||
Vector3 reflect{l - 2 * Vector3::Dot(n, l) * n};
|
||||
float cosAngle{Vector3::Dot(reflect, v)};
|
||||
return {ks * powf(std::max(0.f, cosAngle), exp) * colors::White};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief BRDF Geometry Function >> Schlick GGX (Direct Lighting + UE4 implementation - squared(roughness))
|
||||
* \param n Normal of the surface
|
||||
* \param v Normalized view direction
|
||||
* \param roughness Roughness of the material
|
||||
* \return BRDF Geometry Term using SchlickGGX
|
||||
*/
|
||||
static float GeometryFunction_SchlickGGX(const Vector3& n, const Vector3& v, float roughness)
|
||||
{
|
||||
//todo: W3
|
||||
throw std::runtime_error("Not Implemented Yet");
|
||||
return {};
|
||||
}
|
||||
/**
|
||||
* \brief BRDF Fresnel Function >> Schlick
|
||||
* \param h Normalized Halfvector between View and Light directions
|
||||
* \param v Normalized View direction
|
||||
* \param f0 Base reflectivity of a surface based on IOR (Indices Of Refrection), this is different for Dielectrics (Non-Metal) and Conductors (Metal)
|
||||
* \return
|
||||
*/
|
||||
static ColorRGB FresnelFunction_Schlick(const Vector3 &h, const Vector3 &v, const ColorRGB &f0) {
|
||||
const float base = std::pow(1 - Vector3::Dot(h, v), 5);
|
||||
auto returnValue{f0 + (colors::White - f0) * base};
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief BRDF Geometry Function >> Smith (Direct Lighting)
|
||||
* \param n Normal of the surface
|
||||
* \param v Normalized view direction
|
||||
* \param l Normalized light direction
|
||||
* \param roughness Roughness of the material
|
||||
* \return BRDF Geometry Term using Smith (> SchlickGGX(n,v,roughness) * SchlickGGX(n,l,roughness))
|
||||
*/
|
||||
static float GeometryFunction_Smith(const Vector3& n, const Vector3& v, const Vector3& l, float roughness)
|
||||
{
|
||||
//todo: W3
|
||||
throw std::runtime_error("Not Implemented Yet");
|
||||
return {};
|
||||
}
|
||||
/**
|
||||
* \brief BRDF NormalDistribution >> Trowbridge-Reitz GGX (UE4 implemetation - squared(roughness))
|
||||
* \param n Surface normal
|
||||
* \param h Normalized half vector
|
||||
* \param roughness Roughness of the material
|
||||
* \return BRDF Normal Distribution Term using Trowbridge-Reitz GGX
|
||||
*/
|
||||
static float NormalDistribution_GGX(const Vector3 &n, const Vector3 &h, float roughness) {
|
||||
const float a = roughness * roughness;
|
||||
const float a2 = a * a;
|
||||
|
||||
}
|
||||
const float dot{Vector3::Dot(n, h)};
|
||||
const float div{dot * dot * (a2 - 1) + 1};
|
||||
return a2 / (M_PI * div * div);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief BRDF Geometry Function >> Schlick GGX (Direct Lighting + UE4 implementation - squared(roughness))
|
||||
* \param n Normal of the surface
|
||||
* \param v Normalized view direction
|
||||
* \param roughness Roughness of the material
|
||||
* \return BRDF Geometry Term using SchlickGGX
|
||||
*/
|
||||
static float GeometryFunction_SchlickGGX(const Vector3 &n, const Vector3 &v, float roughness) {
|
||||
float cosAngle{ Vector3::Dot(n,v) };
|
||||
float k{ (roughness + 1) * (roughness + 1) / 8 };
|
||||
|
||||
return {cosAngle / (cosAngle * (1 - k) + k) };
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief BRDF Geometry Function >> Smith (Direct Lighting)
|
||||
* \param n Normal of the surface
|
||||
* \param v Normalized view direction
|
||||
* \param l Normalized light direction
|
||||
* \param roughness Roughness of the material
|
||||
* \return BRDF Geometry Term using Smith (> SchlickGGX(n,v,roughness) * SchlickGGX(n,l,roughness))
|
||||
*/
|
||||
static float GeometryFunction_Smith(const Vector3 &n, const Vector3 &v, const Vector3 &l, float roughness) {
|
||||
return { GeometryFunction_SchlickGGX(n,v,roughness) * GeometryFunction_SchlickGGX(n,l,roughness) };
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,10 @@ namespace dae
|
||||
|
||||
Matrix cameraToWorld{};
|
||||
|
||||
void SetFOV(float fov)
|
||||
{
|
||||
fovAngle = fov;
|
||||
}
|
||||
|
||||
Matrix CalculateCameraToWorld()
|
||||
{
|
||||
@@ -49,9 +53,14 @@ namespace dae
|
||||
{
|
||||
const float deltaTime = pTimer->GetElapsed();
|
||||
|
||||
|
||||
|
||||
//Keyboard Input
|
||||
const uint8_t* pKeyboardState = SDL_GetKeyboardState(nullptr);
|
||||
{
|
||||
|
||||
|
||||
|
||||
float speed{10.f};
|
||||
|
||||
if (pKeyboardState[SDL_SCANCODE_W]) {
|
||||
@@ -98,7 +107,7 @@ namespace dae
|
||||
if(dirty)
|
||||
{
|
||||
Matrix rotMat{
|
||||
Matrix::CreateRotationX(TO_RADIANS * totalPitch) * Matrix::CreateRotationY(TO_RADIANS * totalYaw)
|
||||
Matrix::CreateRotationX(-TO_RADIANS * totalPitch) * Matrix::CreateRotationY(-TO_RADIANS * totalYaw)
|
||||
};
|
||||
|
||||
forward = rotMat.TransformVector(Vector3::UnitZ);
|
||||
|
||||
@@ -50,9 +50,10 @@ namespace dae
|
||||
return *this;
|
||||
}
|
||||
|
||||
const ColorRGB& operator-(const ColorRGB& c)
|
||||
const ColorRGB operator-(const ColorRGB& c)
|
||||
{
|
||||
return *this -= c;
|
||||
return { r - c.r, g - c.g, b - c.b };
|
||||
//TODO: fixed this
|
||||
}
|
||||
|
||||
ColorRGB operator-(const ColorRGB& c) const
|
||||
@@ -142,7 +143,7 @@ namespace dae
|
||||
static ColorRGB Yellow{ 1,1,0 };
|
||||
static ColorRGB Cyan{ 0,1,1 };
|
||||
static ColorRGB Magenta{ 1,0,1 };
|
||||
static ColorRGB White{ 1,1,1 };
|
||||
static ColorRGB White{ 1.f,1.f,1.f };
|
||||
static ColorRGB Black{ 0,0,0 };
|
||||
static ColorRGB Gray{ 0.5f,0.5f,0.5f };
|
||||
}
|
||||
|
||||
@@ -59,9 +59,7 @@ namespace dae
|
||||
|
||||
ColorRGB Shade(const HitRecord& hitRecord = {}, const Vector3& l = {}, const Vector3& v = {}) override
|
||||
{
|
||||
//todo: W3
|
||||
throw std::runtime_error("Not Implemented Yet");
|
||||
return {};
|
||||
return BRDF::Lambert(m_DiffuseReflectance, m_DiffuseColor);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -84,10 +82,10 @@ namespace dae
|
||||
|
||||
ColorRGB Shade(const HitRecord& hitRecord = {}, const Vector3& l = {}, const Vector3& v = {}) override
|
||||
{
|
||||
//todo: W3
|
||||
throw std::runtime_error("Not Implemented Yet");
|
||||
return {};
|
||||
}
|
||||
return BRDF::Lambert(m_DiffuseReflectance, m_DiffuseColor)
|
||||
+ BRDF::Phong(m_SpecularReflectance, m_PhongExponent, l, v, hitRecord.normal);
|
||||
//W Rizz
|
||||
}
|
||||
|
||||
private:
|
||||
ColorRGB m_DiffuseColor{ colors::White };
|
||||
@@ -109,9 +107,31 @@ namespace dae
|
||||
|
||||
ColorRGB Shade(const HitRecord& hitRecord = {}, const Vector3& l = {}, const Vector3& v = {}) override
|
||||
{
|
||||
//todo: W3
|
||||
throw std::runtime_error("Not Implemented Yet");
|
||||
return {};
|
||||
Vector3 invV{ -v };
|
||||
Vector3 h{ ((invV + l) / (invV + l).Magnitude()) };
|
||||
|
||||
ColorRGB dielectricAlbedo{ 0.04f, 0.04f, 0.04f };
|
||||
ColorRGB f0{ (m_Metalness <= 0.f) ? dielectricAlbedo : m_Albedo };
|
||||
|
||||
Vector3 n{ hitRecord.normal };
|
||||
|
||||
ColorRGB fresnel{ BRDF::FresnelFunction_Schlick(h, invV, f0) };
|
||||
float normalDistribution{ BRDF::NormalDistribution_GGX(n, h, m_Roughness) };
|
||||
float geometryFunction{ BRDF::GeometryFunction_Smith(n, invV, l, m_Roughness) };
|
||||
// return ColorRGB{geometryFunction, geometryFunction, geometryFunction};
|
||||
// TODO: these dots should be passed around, not recalculated
|
||||
const ColorRGB specular{
|
||||
fresnel * normalDistribution * geometryFunction /
|
||||
(4.f * Vector3::Dot(invV, n) * Vector3::Dot(l, n))
|
||||
};
|
||||
|
||||
if(m_Metalness)
|
||||
return specular;
|
||||
|
||||
ColorRGB kd{ ColorRGB(1, 1, 1) - fresnel};
|
||||
ColorRGB diffuse{ BRDF::Lambert(kd, f0) };
|
||||
|
||||
return diffuse + specular;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
//External includes
|
||||
#include <iostream>
|
||||
#include "SDL.h"
|
||||
#include "SDL_surface.h"
|
||||
|
||||
@@ -19,6 +20,11 @@ Renderer::Renderer(SDL_Window *pWindow) :
|
||||
SDL_GetWindowSize(pWindow, &m_Width, &m_Height);
|
||||
m_pBufferPixels = static_cast<uint32_t *>(m_pBuffer->pixels);
|
||||
|
||||
m_xvalues.reserve(m_Width);
|
||||
for (uint16_t x{}; x < m_Width; ++x) {
|
||||
m_xvalues.push_back(x);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Renderer::Render(Scene *pScene) const {
|
||||
@@ -30,9 +36,15 @@ void Renderer::Render(Scene *pScene) const {
|
||||
|
||||
float apsectRatio = static_cast<float>(m_Width) / m_Height;
|
||||
float fov = tan((camera.fovAngle * (PI / 180.f)) / 2);
|
||||
for (int px{}; px < m_Width; ++px) {
|
||||
for (int py{}; py < m_Height; ++py) {
|
||||
float NDCx = ((2 * ((px + 0.5) / m_Width) - 1) * apsectRatio) * fov;
|
||||
for (int px{}; px < m_Width; px += 1) {
|
||||
for (int py{}; py < m_Height; py += 1) {
|
||||
|
||||
int actualPx = px;
|
||||
// if (py % 2 != 0) {
|
||||
// actualPx = px + 1;
|
||||
// }
|
||||
|
||||
float NDCx = ((2 * ((actualPx + 0.5) / m_Width) - 1) * apsectRatio) * fov;
|
||||
float NDCy = (1 - 2 * ((py + 0.5) / m_Height)) * fov;
|
||||
|
||||
|
||||
@@ -49,43 +61,208 @@ void Renderer::Render(Scene *pScene) const {
|
||||
HitRecord closestHit{};
|
||||
pScene->GetClosestHit(ray, closestHit);
|
||||
|
||||
|
||||
if (closestHit.didHit) {
|
||||
finalColor = materials[closestHit.materialIndex]->Shade();
|
||||
for (const Light &light: lights) {
|
||||
Vector3 lightDirection{LightUtils::GetDirectionToLight(light, closestHit.origin)};
|
||||
float rayMaxValue = lightDirection.Normalize();
|
||||
Ray lightRay = Ray{closestHit.origin + closestHit.normal * 0.01f, lightDirection, 0.0001f,
|
||||
rayMaxValue};
|
||||
bool doesLightHit = pScene->DoesHit(lightRay);
|
||||
|
||||
for(const Light& light : lights)
|
||||
{
|
||||
Vector3 lightDirection{ LightUtils::GetDirectionToLight(light, closestHit.origin) };
|
||||
const float lightDistance = lightDirection.Normalize();
|
||||
|
||||
const Ray lightRay{
|
||||
closestHit.origin + closestHit.normal * 0.01f,
|
||||
lightDirection, 0.0001f, lightDistance
|
||||
};
|
||||
if (m_CurrentLightingMode == LightingMode::Radiance) {
|
||||
if (!m_ShadowsEnabled or (m_ShadowsEnabled and !doesLightHit)) {
|
||||
auto radiance = LightUtils::GetRadiance(light, closestHit.origin);
|
||||
finalColor += radiance;
|
||||
}
|
||||
|
||||
if(pScene->DoesHit(lightRay))
|
||||
{
|
||||
finalColor *= 0.5;
|
||||
break;
|
||||
|
||||
} else if (m_CurrentLightingMode == LightingMode::ObservedArea) {
|
||||
if (!m_ShadowsEnabled or (m_ShadowsEnabled and !doesLightHit)) {
|
||||
// float observedArea = std::clamp(
|
||||
// LightUtils::LambertCosineLaw(closestHit.normal, lightDirection), 0.0f, 1.0f);
|
||||
// finalColor.r += observedArea;
|
||||
// finalColor.g += observedArea;
|
||||
// finalColor.b += observedArea;
|
||||
}
|
||||
} else if (m_CurrentLightingMode == LightingMode::Combined) {
|
||||
if (!m_ShadowsEnabled or (m_ShadowsEnabled and !doesLightHit)) {
|
||||
auto radiance = LightUtils::GetRadiance(light, closestHit.origin);
|
||||
float observedArea = std::clamp(
|
||||
LightUtils::LambertCosineLaw(closestHit.normal, lightDirection), 0.0f, 1.0f);
|
||||
|
||||
finalColor += radiance * observedArea *
|
||||
materials[closestHit.materialIndex]->Shade(closestHit, lightDirection,
|
||||
rayDir);
|
||||
}
|
||||
} else if (m_CurrentLightingMode == LightingMode::BRDF) {
|
||||
if (!m_ShadowsEnabled or (m_ShadowsEnabled and !doesLightHit)) {
|
||||
auto radiance = LightUtils::GetRadiance(light, closestHit.origin);
|
||||
float observedArea = std::clamp(
|
||||
LightUtils::LambertCosineLaw(closestHit.normal, lightDirection), 0.0f, 1.0f);
|
||||
|
||||
finalColor += materials[closestHit.materialIndex]->Shade(closestHit, lightDirection, ray.direction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// if (m_CurrentLightingMode == LightingMode::ObservedArea) {
|
||||
// if (closestHit.didHit) {
|
||||
// for (const Light &light: lights) {
|
||||
// Vector3 lightDirection{LightUtils::GetDirectionToLight(light, closestHit.origin)};
|
||||
// const float lightDistance = lightDirection.Normalize();
|
||||
//
|
||||
// float law = std::clamp(LightUtils::LambertCosineLaw(closestHit.normal, lightDirection), 0.0f, 1.0f);
|
||||
//// finalColor += materials[closestHit.materialIndex]->Shade() * law;
|
||||
// finalColor += ColorRGB{law, law, law};
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (m_ShadowsEnabled) {
|
||||
//
|
||||
// if (closestHit.didHit) {
|
||||
//// finalColor = materials[closestHit.materialIndex]->Shade();
|
||||
// if (m_ShadowsEnabled) {
|
||||
// for (const Light &light: lights) {
|
||||
// Vector3 lightDirection{LightUtils::GetDirectionToLight(light, closestHit.origin)};
|
||||
// const float lightDistance = lightDirection.Normalize();
|
||||
//
|
||||
// const Ray lightRay{
|
||||
// closestHit.origin + closestHit.normal * 0.01f,
|
||||
// lightDirection, 0.0001f, lightDistance
|
||||
// };
|
||||
//
|
||||
// if (pScene->DoesHit(lightRay)) {
|
||||
// finalColor *= 0.5;
|
||||
// continue;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
finalColor.MaxToOne();
|
||||
|
||||
m_pBufferPixels[px + (py * m_Width)] = SDL_MapRGB(m_pBuffer->format,
|
||||
static_cast<uint8_t>(finalColor.r * 255),
|
||||
static_cast<uint8_t>(finalColor.g * 255),
|
||||
static_cast<uint8_t>(finalColor.b * 255));
|
||||
m_pBufferPixels[actualPx + (py * m_Width)] = SDL_MapRGB(m_pBuffer->format,
|
||||
static_cast<uint8_t>(finalColor.r * 255),
|
||||
static_cast<uint8_t>(finalColor.g * 255),
|
||||
static_cast<uint8_t>(finalColor.b * 255));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// go over the pixels and avg the pixels i skipped
|
||||
// for (int px2{1}; px2 < m_Width; px2 += 2) {
|
||||
// for (int py{1}; py < m_Height; py += 1) {
|
||||
// if (px2 == m_Width - 1 || py == m_Height - 1) continue;
|
||||
// if (px2 == 0 || py == 0) continue;
|
||||
//
|
||||
// int px = px2;
|
||||
// if (py % 2 != 0) {
|
||||
// px = px2 + 1;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// uint8_t r = 0;
|
||||
// uint8_t g = 0;
|
||||
// uint8_t b = 0;
|
||||
// SDL_GetRGB(m_pBufferPixels[px + (py * m_Width)], m_pBuffer->format, &r, &g, &b);
|
||||
// ColorRGB currentColor = ColorRGB{r / 255.f, g / 255.f, b / 255.f};
|
||||
//
|
||||
// SDL_GetRGB(m_pBufferPixels[(px - 1) + (py * m_Width)], m_pBuffer->format, &r, &g, &b);
|
||||
// ColorRGB leftColor = ColorRGB{r / 255.f, g / 255.f, b / 255.f};
|
||||
//
|
||||
// SDL_GetRGB(m_pBufferPixels[(px + 1) + (py * m_Width)], m_pBuffer->format, &r, &g, &b);
|
||||
// ColorRGB rightColor = ColorRGB{r / 255.f, g / 255.f, b / 255.f};
|
||||
//
|
||||
// SDL_GetRGB(m_pBufferPixels[px + ((py - 1) * m_Width)], m_pBuffer->format, &r, &g, &b);
|
||||
// ColorRGB upColor = ColorRGB{r / 255.f, g / 255.f, b / 255.f};
|
||||
//
|
||||
// SDL_GetRGB(m_pBufferPixels[px + ((py + 1) * m_Width)], m_pBuffer->format, &r, &g, &b);
|
||||
// ColorRGB downColor = ColorRGB{r / 255.f, g / 255.f, b / 255.f};
|
||||
//
|
||||
// float avgR = (leftColor.r + rightColor.r + upColor.r + downColor.r) / 4;
|
||||
// float avgG = (leftColor.g + rightColor.g + upColor.g + downColor.g) / 4;
|
||||
// float avgB = (leftColor.b + rightColor.b + upColor.b + downColor.b) / 4;
|
||||
// ColorRGB avgColor = ColorRGB{avgR, avgG, avgB};
|
||||
//
|
||||
// m_pBufferPixels[px + (py * m_Width)] = SDL_MapRGB(m_pBuffer->format,
|
||||
// static_cast<uint8_t>(avgColor.r * 255),
|
||||
// static_cast<uint8_t>(avgColor.g * 255),
|
||||
// static_cast<uint8_t>(avgColor.b * 255));
|
||||
// }
|
||||
// }
|
||||
|
||||
//@END
|
||||
//Update SDL Surface
|
||||
SDL_UpdateWindowSurface(m_pWindow);
|
||||
}
|
||||
|
||||
ColorRGB Renderer::Raytrace(const dae::Ray &viewRay, dae::Scene *pScene) const {
|
||||
ColorRGB finalColor{0.f, 0.f, 0.f};
|
||||
|
||||
auto &materials = pScene->GetMaterials();
|
||||
Camera &camera = pScene->GetCamera();
|
||||
auto &lights = pScene->GetLights();
|
||||
|
||||
HitRecord closestHit{};
|
||||
pScene->GetClosestHit(viewRay, closestHit);
|
||||
|
||||
if (closestHit.didHit) {
|
||||
|
||||
for (const Light &light: lights) {
|
||||
|
||||
Vector3 lightDirection{LightUtils::GetDirectionToLight(light, closestHit.origin)};
|
||||
const float lightDistance = lightDirection.Normalize();
|
||||
|
||||
const Ray lightRay{
|
||||
closestHit.origin + closestHit.normal * 0.0001f,
|
||||
lightDirection, 0.0001f, lightDistance
|
||||
};
|
||||
|
||||
if (m_ShadowsEnabled && pScene->DoesHit(lightRay))
|
||||
continue;
|
||||
|
||||
float cosAngle = LightUtils::LambertCosineLaw(closestHit.normal, lightDirection);
|
||||
|
||||
|
||||
return finalColor;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Renderer::SaveBufferToImage() const {
|
||||
return SDL_SaveBMP(m_pBuffer, "RayTracing_Buffer.bmp");
|
||||
}
|
||||
|
||||
|
||||
void Renderer::CycleLightingMode() {
|
||||
switch (m_CurrentLightingMode) {
|
||||
case LightingMode::ObservedArea:
|
||||
m_CurrentLightingMode = LightingMode::Radiance;
|
||||
std::cout << "Radiance" << std::endl;
|
||||
break;
|
||||
case LightingMode::Radiance:
|
||||
m_CurrentLightingMode = LightingMode::BRDF;
|
||||
std::cout << "BRDF" << std::endl;
|
||||
break;
|
||||
case LightingMode::BRDF:
|
||||
m_CurrentLightingMode = LightingMode::Combined;
|
||||
std::cout << "Combined" << std::endl;
|
||||
break;
|
||||
case LightingMode::Combined:
|
||||
m_CurrentLightingMode = LightingMode::ObservedArea;
|
||||
std::cout << "Observed Area" << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include "Camera.h"
|
||||
#include "DataTypes.h"
|
||||
|
||||
struct SDL_Window;
|
||||
struct SDL_Surface;
|
||||
@@ -24,12 +25,27 @@ namespace dae
|
||||
void Render(Scene* pScene) const;
|
||||
bool SaveBufferToImage() const;
|
||||
|
||||
void CycleLightingMode();
|
||||
void ToggleShadows() { m_ShadowsEnabled = !m_ShadowsEnabled; }
|
||||
|
||||
private:
|
||||
enum class LightingMode {
|
||||
ObservedArea,
|
||||
Radiance,
|
||||
BRDF,
|
||||
Combined
|
||||
};
|
||||
LightingMode m_CurrentLightingMode{ LightingMode::Combined };
|
||||
bool m_ShadowsEnabled{ true };
|
||||
|
||||
|
||||
|
||||
SDL_Window* m_pWindow{};
|
||||
|
||||
SDL_Surface* m_pBuffer{};
|
||||
uint32_t* m_pBufferPixels{};
|
||||
|
||||
|
||||
int m_Width{};
|
||||
int m_Height{};
|
||||
|
||||
@@ -37,5 +53,9 @@ namespace dae
|
||||
|
||||
Camera m_Camera{};
|
||||
|
||||
};
|
||||
ColorRGB Raytrace(const Ray& viewRay, Scene* pScene) const;
|
||||
|
||||
std::vector<uint16_t> m_xvalues;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -179,4 +179,39 @@ namespace dae {
|
||||
|
||||
AddPointLight({0.f, 5.f, -5.f}, 70.f, colors::White);
|
||||
}
|
||||
|
||||
void Scene_W3::Initialize()
|
||||
{
|
||||
sceneName = "Week 3";
|
||||
m_Camera.origin = { 0,3,-9 };
|
||||
m_Camera.SetFOV(45.f);
|
||||
|
||||
const auto matCT_GrayRoughMetal = AddMaterial(new Material_CookTorrence({ .972f, .960f, .915f }, 1.f, 1.f));
|
||||
const auto matCT_GrayMediumMetal = AddMaterial(new Material_CookTorrence({ .972f, .960f, .915f }, 1.f, .6f));
|
||||
const auto matCT_GraySmoothMetal = AddMaterial(new Material_CookTorrence({ .972f, .960f, .915f }, 1.f, .1f));
|
||||
const auto matCT_GrayRoughPlastic = AddMaterial(new Material_CookTorrence({ .75f, .75f, .75f }, .0f, 1.f));
|
||||
const auto matCT_GrayMediumPlastic = AddMaterial(new Material_CookTorrence({ .75f, .75f, .75f }, .0f, .6f));
|
||||
const auto matCT_GraySmoothPlastic = AddMaterial(new Material_CookTorrence({ .75f, .75f, .75f }, .0f, .1f));
|
||||
|
||||
const auto matLambert_GrayBlue = AddMaterial(new Material_Lambert({ .49f, 0.57f, 0.57f }, 1.f));
|
||||
|
||||
AddPlane(Vector3{ 0.f, 0.f, 10.f }, Vector3{ 0.f, 0.f, -1.f }, matLambert_GrayBlue); //BACK
|
||||
AddPlane(Vector3{ 0.f, 0.f, 0.f }, Vector3{ 0.f, 1.f, 0.f }, matLambert_GrayBlue); //BOTTOM
|
||||
AddPlane(Vector3{ 0.f, 10.f, 0.f }, Vector3{ 0.f, -1.f, 0.f }, matLambert_GrayBlue); //TOP
|
||||
AddPlane(Vector3{ 5.f, 0.f, 0.f }, Vector3{ -1.f, 0.f, 0.f }, matLambert_GrayBlue); //RIGHT
|
||||
AddPlane(Vector3{ -5.f, 0.f, 0.f }, Vector3{ 1.f, 0.f, 0.f }, matLambert_GrayBlue); //LEFT
|
||||
|
||||
AddSphere(Vector3{ -1.75f, 1.f, 0.f }, .75f, matCT_GrayRoughMetal);
|
||||
AddSphere(Vector3{ 0.f, 1.f, 0.f }, .75f, matCT_GrayMediumMetal);
|
||||
AddSphere(Vector3{ 1.75f, 1.f, 0.f }, .75f, matCT_GraySmoothMetal);
|
||||
AddSphere(Vector3{ -1.75f, 3.f, 0.f }, .75f, matCT_GrayRoughPlastic);
|
||||
AddSphere(Vector3{ 0.f, 3.f, 0.f }, .75f, matCT_GrayMediumPlastic);
|
||||
AddSphere(Vector3{ 1.75f, 3.f, 0.f }, .75f, matCT_GraySmoothPlastic);
|
||||
|
||||
|
||||
|
||||
AddPointLight(Vector3{ 0.f, 5.f, 5.f }, 50.f, ColorRGB{ 1.f, .61f, .45f }); //Backlight
|
||||
AddPointLight(Vector3{ -2.5f, 5.f, -5.f }, 70.f, ColorRGB{ 1.f, .8f, .45f }); //Front Light Left
|
||||
AddPointLight(Vector3{ 2.5f, 2.5f, -5.f }, 50.f, ColorRGB{ .34f, .47f, .68f });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,4 +93,19 @@ namespace dae
|
||||
|
||||
void Initialize() override;
|
||||
};
|
||||
|
||||
|
||||
class Scene_W3 final : public Scene
|
||||
{
|
||||
public:
|
||||
Scene_W3() = default;
|
||||
~Scene_W3() override = default;
|
||||
|
||||
Scene_W3(const Scene_W1&) = delete;
|
||||
Scene_W3(Scene_W1&&) noexcept = delete;
|
||||
Scene_W3& operator=(const Scene_W1&) = delete;
|
||||
Scene_W3& operator=(Scene_W1&&) noexcept = delete;
|
||||
|
||||
void Initialize() override;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -119,10 +119,19 @@ namespace dae
|
||||
|
||||
inline ColorRGB GetRadiance(const Light& light, const Vector3& target)
|
||||
{
|
||||
//todo W3
|
||||
throw std::runtime_error("Not Implemented Yet");
|
||||
return {};
|
||||
switch(light.type)
|
||||
{
|
||||
case LightType::Point:
|
||||
return light.color * light.intensity / (light.origin - target).SqrMagnitude();
|
||||
case LightType::Directional:
|
||||
return light.color * light.intensity;
|
||||
}
|
||||
}
|
||||
|
||||
inline float LambertCosineLaw(const Vector3& normal, const Vector3& lightDirection)
|
||||
{
|
||||
return Vector3::Dot(normal, lightDirection);
|
||||
}
|
||||
}
|
||||
|
||||
namespace Utils
|
||||
|
||||
@@ -47,7 +47,7 @@ int main(int argc, char* args[])
|
||||
const auto pTimer = new Timer();
|
||||
const auto pRenderer = new Renderer(pWindow);
|
||||
|
||||
const auto pScene = new Scene_W2();
|
||||
const auto pScene = new Scene_W3();
|
||||
pScene->Initialize();
|
||||
|
||||
//Start loop
|
||||
@@ -59,6 +59,7 @@ int main(int argc, char* args[])
|
||||
float printTimer = 0.f;
|
||||
bool isLooping = true;
|
||||
bool takeScreenshot = false;
|
||||
bool mouseLocked = false;
|
||||
while (isLooping)
|
||||
{
|
||||
//--------- Get input events ---------
|
||||
@@ -74,6 +75,33 @@ int main(int argc, char* args[])
|
||||
if (e.key.keysym.scancode == SDL_SCANCODE_X)
|
||||
takeScreenshot = true;
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
if (e.key.keysym.scancode == SDL_SCANCODE_F2)
|
||||
pRenderer->ToggleShadows();
|
||||
if (e.key.keysym.scancode == SDL_SCANCODE_F3)
|
||||
pRenderer->CycleLightingMode();
|
||||
|
||||
if (e.key.keysym.scancode == SDL_SCANCODE_ESCAPE)
|
||||
{
|
||||
//release the mouse
|
||||
if(mouseLocked)
|
||||
{
|
||||
SDL_SetRelativeMouseMode(SDL_FALSE);
|
||||
mouseLocked = false;
|
||||
} else {
|
||||
SDL_SetRelativeMouseMode(SDL_TRUE);
|
||||
mouseLocked = true;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
//on focus lock mouse
|
||||
case SDL_WINDOWEVENT:
|
||||
if (e.window.event == SDL_WINDOWEVENT_FOCUS_GAINED)
|
||||
SDL_SetRelativeMouseMode(SDL_TRUE);
|
||||
mouseLocked = true;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user