This commit is contained in:
2024-10-16 10:15:16 +02:00
parent b7106c2af8
commit 1269b8dce7
10 changed files with 437 additions and 132 deletions

View File

@@ -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 {};
} }
} }

View File

@@ -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);

View File

@@ -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 };
} }

View File

@@ -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:

View File

@@ -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;
}
}

View File

@@ -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;
}; };
} }

View File

@@ -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 });
}
} }

View File

@@ -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;
};
} }

View File

@@ -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);
} }
} }

View File

@@ -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;
} }
} }