Fix shit
This commit is contained in:
@@ -1,27 +1,20 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Maths.h"
|
#include "Maths.h"
|
||||||
|
|
||||||
namespace dae
|
namespace dae {
|
||||||
{
|
namespace BRDF {
|
||||||
namespace BRDF
|
|
||||||
{
|
|
||||||
/**
|
/**
|
||||||
* \param kd Diffuse Reflection Coefficient
|
* \param kd Diffuse Reflection Coefficient
|
||||||
* \param cd Diffuse Color
|
* \param cd Diffuse Color
|
||||||
* \return Lambert Diffuse Color
|
* \return Lambert Diffuse Color
|
||||||
*/
|
*/
|
||||||
static ColorRGB Lambert(float kd, const ColorRGB& cd)
|
static ColorRGB Lambert(float kd, const ColorRGB &cd) {
|
||||||
{
|
return (kd / PI) * cd;
|
||||||
//todo: W3
|
|
||||||
throw std::runtime_error("Not Implemented Yet");
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ColorRGB Lambert(const ColorRGB& kd, const ColorRGB& cd)
|
static ColorRGB Lambert(const ColorRGB &kd, const ColorRGB &cd) {
|
||||||
{
|
return (kd * PI) * cd;
|
||||||
//todo: W3
|
|
||||||
throw std::runtime_error("Not Implemented Yet");
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -33,13 +26,13 @@ namespace dae
|
|||||||
* \param n Normal of the Surface
|
* \param n Normal of the Surface
|
||||||
* \return Phong Specular Color
|
* \return Phong Specular Color
|
||||||
*/
|
*/
|
||||||
static ColorRGB Phong(float ks, float exp, const Vector3& l, const Vector3& v, const Vector3& n)
|
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};
|
||||||
//todo: W3
|
float cosAngle{Vector3::Dot(reflect, v)};
|
||||||
throw std::runtime_error("Not Implemented Yet");
|
return {ks * powf(std::max(0.f, cosAngle), exp) * colors::White};
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief BRDF Fresnel Function >> Schlick
|
* \brief BRDF Fresnel Function >> Schlick
|
||||||
* \param h Normalized Halfvector between View and Light directions
|
* \param h Normalized Halfvector between View and Light directions
|
||||||
@@ -47,11 +40,10 @@ namespace dae
|
|||||||
* \param f0 Base reflectivity of a surface based on IOR (Indices Of Refrection), this is different for Dielectrics (Non-Metal) and Conductors (Metal)
|
* \param f0 Base reflectivity of a surface based on IOR (Indices Of Refrection), this is different for Dielectrics (Non-Metal) and Conductors (Metal)
|
||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
static ColorRGB FresnelFunction_Schlick(const Vector3& h, const Vector3& v, const ColorRGB& f0)
|
static ColorRGB FresnelFunction_Schlick(const Vector3 &h, const Vector3 &v, const ColorRGB &f0) {
|
||||||
{
|
const float base = std::pow(1 - Vector3::Dot(h, v), 5);
|
||||||
//todo: W3
|
auto returnValue{f0 + (colors::White - f0) * base};
|
||||||
throw std::runtime_error("Not Implemented Yet");
|
return returnValue;
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -61,11 +53,13 @@ namespace dae
|
|||||||
* \param roughness Roughness of the material
|
* \param roughness Roughness of the material
|
||||||
* \return BRDF Normal Distribution Term using Trowbridge-Reitz GGX
|
* \return BRDF Normal Distribution Term using Trowbridge-Reitz GGX
|
||||||
*/
|
*/
|
||||||
static float NormalDistribution_GGX(const Vector3& n, const Vector3& h, float roughness)
|
static float NormalDistribution_GGX(const Vector3 &n, const Vector3 &h, float roughness) {
|
||||||
{
|
const float a = roughness * roughness;
|
||||||
//todo: W3
|
const float a2 = a * a;
|
||||||
throw std::runtime_error("Not Implemented Yet");
|
|
||||||
return {};
|
const float dot{Vector3::Dot(n, h)};
|
||||||
|
const float div{dot * dot * (a2 - 1) + 1};
|
||||||
|
return a2 / (M_PI * div * div);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -76,11 +70,11 @@ namespace dae
|
|||||||
* \param roughness Roughness of the material
|
* \param roughness Roughness of the material
|
||||||
* \return BRDF Geometry Term using SchlickGGX
|
* \return BRDF Geometry Term using SchlickGGX
|
||||||
*/
|
*/
|
||||||
static float GeometryFunction_SchlickGGX(const Vector3& n, const Vector3& v, float roughness)
|
static float GeometryFunction_SchlickGGX(const Vector3 &n, const Vector3 &v, float roughness) {
|
||||||
{
|
float cosAngle{ Vector3::Dot(n,v) };
|
||||||
//todo: W3
|
float k{ (roughness + 1) * (roughness + 1) / 8 };
|
||||||
throw std::runtime_error("Not Implemented Yet");
|
|
||||||
return {};
|
return {cosAngle / (cosAngle * (1 - k) + k) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -91,11 +85,8 @@ namespace dae
|
|||||||
* \param roughness Roughness of the material
|
* \param roughness Roughness of the material
|
||||||
* \return BRDF Geometry Term using Smith (> SchlickGGX(n,v,roughness) * SchlickGGX(n,l,roughness))
|
* \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)
|
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) };
|
||||||
//todo: W3
|
|
||||||
throw std::runtime_error("Not Implemented Yet");
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,10 @@ namespace dae
|
|||||||
|
|
||||||
Matrix cameraToWorld{};
|
Matrix cameraToWorld{};
|
||||||
|
|
||||||
|
void SetFOV(float fov)
|
||||||
|
{
|
||||||
|
fovAngle = fov;
|
||||||
|
}
|
||||||
|
|
||||||
Matrix CalculateCameraToWorld()
|
Matrix CalculateCameraToWorld()
|
||||||
{
|
{
|
||||||
@@ -49,9 +53,14 @@ namespace dae
|
|||||||
{
|
{
|
||||||
const float deltaTime = pTimer->GetElapsed();
|
const float deltaTime = pTimer->GetElapsed();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Keyboard Input
|
//Keyboard Input
|
||||||
const uint8_t* pKeyboardState = SDL_GetKeyboardState(nullptr);
|
const uint8_t* pKeyboardState = SDL_GetKeyboardState(nullptr);
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
float speed{10.f};
|
float speed{10.f};
|
||||||
|
|
||||||
if (pKeyboardState[SDL_SCANCODE_W]) {
|
if (pKeyboardState[SDL_SCANCODE_W]) {
|
||||||
@@ -98,7 +107,7 @@ namespace dae
|
|||||||
if(dirty)
|
if(dirty)
|
||||||
{
|
{
|
||||||
Matrix rotMat{
|
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);
|
forward = rotMat.TransformVector(Vector3::UnitZ);
|
||||||
|
|||||||
@@ -50,9 +50,10 @@ namespace dae
|
|||||||
return *this;
|
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
|
ColorRGB operator-(const ColorRGB& c) const
|
||||||
@@ -142,7 +143,7 @@ namespace dae
|
|||||||
static ColorRGB Yellow{ 1,1,0 };
|
static ColorRGB Yellow{ 1,1,0 };
|
||||||
static ColorRGB Cyan{ 0,1,1 };
|
static ColorRGB Cyan{ 0,1,1 };
|
||||||
static ColorRGB Magenta{ 1,0,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 Black{ 0,0,0 };
|
||||||
static ColorRGB Gray{ 0.5f,0.5f,0.5f };
|
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
|
ColorRGB Shade(const HitRecord& hitRecord = {}, const Vector3& l = {}, const Vector3& v = {}) override
|
||||||
{
|
{
|
||||||
//todo: W3
|
return BRDF::Lambert(m_DiffuseReflectance, m_DiffuseColor);
|
||||||
throw std::runtime_error("Not Implemented Yet");
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -84,9 +82,9 @@ namespace dae
|
|||||||
|
|
||||||
ColorRGB Shade(const HitRecord& hitRecord = {}, const Vector3& l = {}, const Vector3& v = {}) override
|
ColorRGB Shade(const HitRecord& hitRecord = {}, const Vector3& l = {}, const Vector3& v = {}) override
|
||||||
{
|
{
|
||||||
//todo: W3
|
return BRDF::Lambert(m_DiffuseReflectance, m_DiffuseColor)
|
||||||
throw std::runtime_error("Not Implemented Yet");
|
+ BRDF::Phong(m_SpecularReflectance, m_PhongExponent, l, v, hitRecord.normal);
|
||||||
return {};
|
//W Rizz
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -109,9 +107,31 @@ namespace dae
|
|||||||
|
|
||||||
ColorRGB Shade(const HitRecord& hitRecord = {}, const Vector3& l = {}, const Vector3& v = {}) override
|
ColorRGB Shade(const HitRecord& hitRecord = {}, const Vector3& l = {}, const Vector3& v = {}) override
|
||||||
{
|
{
|
||||||
//todo: W3
|
Vector3 invV{ -v };
|
||||||
throw std::runtime_error("Not Implemented Yet");
|
Vector3 h{ ((invV + l) / (invV + l).Magnitude()) };
|
||||||
return {};
|
|
||||||
|
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:
|
private:
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//External includes
|
//External includes
|
||||||
|
#include <iostream>
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
#include "SDL_surface.h"
|
#include "SDL_surface.h"
|
||||||
|
|
||||||
@@ -19,6 +20,11 @@ Renderer::Renderer(SDL_Window *pWindow) :
|
|||||||
SDL_GetWindowSize(pWindow, &m_Width, &m_Height);
|
SDL_GetWindowSize(pWindow, &m_Width, &m_Height);
|
||||||
m_pBufferPixels = static_cast<uint32_t *>(m_pBuffer->pixels);
|
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 {
|
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 apsectRatio = static_cast<float>(m_Width) / m_Height;
|
||||||
float fov = tan((camera.fovAngle * (PI / 180.f)) / 2);
|
float fov = tan((camera.fovAngle * (PI / 180.f)) / 2);
|
||||||
for (int px{}; px < m_Width; ++px) {
|
for (int px{}; px < m_Width; px += 1) {
|
||||||
for (int py{}; py < m_Height; ++py) {
|
for (int py{}; py < m_Height; py += 1) {
|
||||||
float NDCx = ((2 * ((px + 0.5) / m_Width) - 1) * apsectRatio) * fov;
|
|
||||||
|
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;
|
float NDCy = (1 - 2 * ((py + 0.5) / m_Height)) * fov;
|
||||||
|
|
||||||
|
|
||||||
@@ -49,31 +61,95 @@ void Renderer::Render(Scene *pScene) const {
|
|||||||
HitRecord closestHit{};
|
HitRecord closestHit{};
|
||||||
pScene->GetClosestHit(ray, closestHit);
|
pScene->GetClosestHit(ray, closestHit);
|
||||||
|
|
||||||
|
|
||||||
if (closestHit.didHit) {
|
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{
|
if (m_CurrentLightingMode == LightingMode::Radiance) {
|
||||||
closestHit.origin + closestHit.normal * 0.01f,
|
if (!m_ShadowsEnabled or (m_ShadowsEnabled and !doesLightHit)) {
|
||||||
lightDirection, 0.0001f, lightDistance
|
auto radiance = LightUtils::GetRadiance(light, closestHit.origin);
|
||||||
};
|
finalColor += radiance;
|
||||||
|
}
|
||||||
|
|
||||||
if(pScene->DoesHit(lightRay))
|
|
||||||
{
|
} else if (m_CurrentLightingMode == LightingMode::ObservedArea) {
|
||||||
finalColor *= 0.5;
|
if (!m_ShadowsEnabled or (m_ShadowsEnabled and !doesLightHit)) {
|
||||||
break;
|
// 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();
|
finalColor.MaxToOne();
|
||||||
|
|
||||||
m_pBufferPixels[px + (py * m_Width)] = SDL_MapRGB(m_pBuffer->format,
|
m_pBufferPixels[actualPx + (py * m_Width)] = SDL_MapRGB(m_pBuffer->format,
|
||||||
static_cast<uint8_t>(finalColor.r * 255),
|
static_cast<uint8_t>(finalColor.r * 255),
|
||||||
static_cast<uint8_t>(finalColor.g * 255),
|
static_cast<uint8_t>(finalColor.g * 255),
|
||||||
static_cast<uint8_t>(finalColor.b * 255));
|
static_cast<uint8_t>(finalColor.b * 255));
|
||||||
@@ -81,11 +157,112 @@ void Renderer::Render(Scene *pScene) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
//@END
|
||||||
//Update SDL Surface
|
//Update SDL Surface
|
||||||
SDL_UpdateWindowSurface(m_pWindow);
|
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 {
|
bool Renderer::SaveBufferToImage() const {
|
||||||
return SDL_SaveBMP(m_pBuffer, "RayTracing_Buffer.bmp");
|
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 <cstdint>
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
|
#include "DataTypes.h"
|
||||||
|
|
||||||
struct SDL_Window;
|
struct SDL_Window;
|
||||||
struct SDL_Surface;
|
struct SDL_Surface;
|
||||||
@@ -24,12 +25,27 @@ namespace dae
|
|||||||
void Render(Scene* pScene) const;
|
void Render(Scene* pScene) const;
|
||||||
bool SaveBufferToImage() const;
|
bool SaveBufferToImage() const;
|
||||||
|
|
||||||
|
void CycleLightingMode();
|
||||||
|
void ToggleShadows() { m_ShadowsEnabled = !m_ShadowsEnabled; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
enum class LightingMode {
|
||||||
|
ObservedArea,
|
||||||
|
Radiance,
|
||||||
|
BRDF,
|
||||||
|
Combined
|
||||||
|
};
|
||||||
|
LightingMode m_CurrentLightingMode{ LightingMode::Combined };
|
||||||
|
bool m_ShadowsEnabled{ true };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SDL_Window* m_pWindow{};
|
SDL_Window* m_pWindow{};
|
||||||
|
|
||||||
SDL_Surface* m_pBuffer{};
|
SDL_Surface* m_pBuffer{};
|
||||||
uint32_t* m_pBufferPixels{};
|
uint32_t* m_pBufferPixels{};
|
||||||
|
|
||||||
|
|
||||||
int m_Width{};
|
int m_Width{};
|
||||||
int m_Height{};
|
int m_Height{};
|
||||||
|
|
||||||
@@ -37,5 +53,9 @@ namespace dae
|
|||||||
|
|
||||||
Camera m_Camera{};
|
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);
|
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;
|
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,9 +119,18 @@ namespace dae
|
|||||||
|
|
||||||
inline ColorRGB GetRadiance(const Light& light, const Vector3& target)
|
inline ColorRGB GetRadiance(const Light& light, const Vector3& target)
|
||||||
{
|
{
|
||||||
//todo W3
|
switch(light.type)
|
||||||
throw std::runtime_error("Not Implemented Yet");
|
{
|
||||||
return {};
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ int main(int argc, char* args[])
|
|||||||
const auto pTimer = new Timer();
|
const auto pTimer = new Timer();
|
||||||
const auto pRenderer = new Renderer(pWindow);
|
const auto pRenderer = new Renderer(pWindow);
|
||||||
|
|
||||||
const auto pScene = new Scene_W2();
|
const auto pScene = new Scene_W3();
|
||||||
pScene->Initialize();
|
pScene->Initialize();
|
||||||
|
|
||||||
//Start loop
|
//Start loop
|
||||||
@@ -59,6 +59,7 @@ int main(int argc, char* args[])
|
|||||||
float printTimer = 0.f;
|
float printTimer = 0.f;
|
||||||
bool isLooping = true;
|
bool isLooping = true;
|
||||||
bool takeScreenshot = false;
|
bool takeScreenshot = false;
|
||||||
|
bool mouseLocked = false;
|
||||||
while (isLooping)
|
while (isLooping)
|
||||||
{
|
{
|
||||||
//--------- Get input events ---------
|
//--------- Get input events ---------
|
||||||
@@ -74,6 +75,33 @@ int main(int argc, char* args[])
|
|||||||
if (e.key.keysym.scancode == SDL_SCANCODE_X)
|
if (e.key.keysym.scancode == SDL_SCANCODE_X)
|
||||||
takeScreenshot = true;
|
takeScreenshot = true;
|
||||||
break;
|
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