Working reference and bunny scene
This commit is contained in:
945137
project/resources/Warlock.obj
Normal file
945137
project/resources/Warlock.obj
Normal file
File diff suppressed because it is too large
Load Diff
@@ -12,16 +12,12 @@ namespace dae
|
||||
*/
|
||||
static ColorRGB Lambert(float kd, const ColorRGB& cd)
|
||||
{
|
||||
//todo: W3
|
||||
throw std::runtime_error("Not Implemented Yet");
|
||||
return {};
|
||||
return (kd * cd) / PI;
|
||||
}
|
||||
|
||||
static ColorRGB Lambert(const ColorRGB& kd, const ColorRGB& cd)
|
||||
{
|
||||
//todo: W3
|
||||
throw std::runtime_error("Not Implemented Yet");
|
||||
return {};
|
||||
return (kd * cd) / PI;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -35,9 +31,13 @@ namespace dae
|
||||
*/
|
||||
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 {};
|
||||
Vector3 reflect = l - 2 * n * Vector3::Dot(n, l);
|
||||
|
||||
float cosa{ std::max(Vector3::Dot(reflect, v), 0.f) };
|
||||
|
||||
float PhongSpecReflec = ks * (std::pow(cosa, exp));
|
||||
|
||||
return ColorRGB(PhongSpecReflec, PhongSpecReflec, PhongSpecReflec);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,9 +49,7 @@ namespace dae
|
||||
*/
|
||||
static ColorRGB FresnelFunction_Schlick(const Vector3& h, const Vector3& v, const ColorRGB& f0)
|
||||
{
|
||||
//todo: W3
|
||||
throw std::runtime_error("Not Implemented Yet");
|
||||
return {};
|
||||
return ColorRGB{ f0 + (ColorRGB{1,1,1} - f0) * std::pow((1 - (Vector3::Dot(h, v))) , 5) };
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,9 +61,10 @@ namespace dae
|
||||
*/
|
||||
static float NormalDistribution_GGX(const Vector3& n, const Vector3& h, float roughness)
|
||||
{
|
||||
//todo: W3
|
||||
throw std::runtime_error("Not Implemented Yet");
|
||||
return {};
|
||||
float nhdot = Vector3::Dot(n, h);
|
||||
float roughnessQuartic = std::pow(roughness,4);
|
||||
float denominator = (nhdot * nhdot) * (roughnessQuartic - 1) + 1;
|
||||
return ((roughnessQuartic)/ (PI * (denominator * denominator)));
|
||||
}
|
||||
|
||||
|
||||
@@ -78,9 +77,10 @@ namespace dae
|
||||
*/
|
||||
static float GeometryFunction_SchlickGGX(const Vector3& n, const Vector3& v, float roughness)
|
||||
{
|
||||
//todo: W3
|
||||
throw std::runtime_error("Not Implemented Yet");
|
||||
return {};
|
||||
float roughnessSqr = roughness * roughness;
|
||||
float nvdot = Vector3::Dot(n, v);
|
||||
float kdirect = ((roughnessSqr + 1) * (roughnessSqr + 1)) / 8;
|
||||
return (nvdot / ((nvdot) * (1 - kdirect) + kdirect));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,9 +93,7 @@ namespace dae
|
||||
*/
|
||||
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 {};
|
||||
return GeometryFunction_SchlickGGX(n, v, roughness) * GeometryFunction_SchlickGGX(n, l, roughness);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace dae
|
||||
|
||||
|
||||
Vector3 origin{};
|
||||
float fovAngle{ 90.f };
|
||||
float fovAngle{ 45.f };
|
||||
float previousfovAngle{ fovAngle };
|
||||
float FOV{ tan((fovAngle * (PI / 180)) / 2) };
|
||||
float rotSpeed{10};
|
||||
@@ -39,10 +39,10 @@ namespace dae
|
||||
|
||||
Matrix CalculateCameraToWorld()
|
||||
{
|
||||
right = Vector3::Cross(Vector3::UnitY, Camera::forward);
|
||||
up = Vector3::Cross(Camera::forward, right);
|
||||
right = Vector3::Cross(Vector3::UnitY,forward).Normalized();
|
||||
up = Vector3::Cross(forward, right).Normalized();
|
||||
|
||||
return Matrix(right, up, Camera::forward, Camera::origin);
|
||||
return Matrix(right, up, forward, origin);
|
||||
}
|
||||
|
||||
void Update(Timer* pTimer)
|
||||
|
||||
@@ -124,20 +124,46 @@ namespace dae
|
||||
|
||||
void CalculateNormals()
|
||||
{
|
||||
throw std::runtime_error("Not Implemented Yet");
|
||||
normals.clear();
|
||||
|
||||
normals.reserve(indices.size() / 3);
|
||||
|
||||
for (int idx{0};idx < indices.size();idx += 3)
|
||||
{
|
||||
int i0 = indices[idx];
|
||||
int i1 = indices[idx+1];
|
||||
int i2 = indices[idx+2];
|
||||
|
||||
Vector3 a {positions[i0],positions[i1]};
|
||||
Vector3 b {positions[i0],positions[i2]};
|
||||
|
||||
normals.push_back(Vector3::Cross(a, b).Normalized());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void UpdateTransforms()
|
||||
{
|
||||
throw std::runtime_error("Not Implemented Yet");
|
||||
//Calculate Final Transform
|
||||
//const auto finalTransform = ...
|
||||
transformedPositions.clear();
|
||||
transformedNormals.clear();
|
||||
|
||||
//Transform Positions (positions > transformedPositions)
|
||||
//...
|
||||
transformedPositions.reserve(positions.size());
|
||||
transformedNormals.reserve(normals.size());
|
||||
|
||||
Matrix FullTransformMatrix = scaleTransform * rotationTransform * translationTransform ;
|
||||
|
||||
//Transform Normals (normals > transformedNormals)
|
||||
//...
|
||||
for (int idx{0};idx < positions.size();++idx)
|
||||
{
|
||||
transformedPositions.push_back(FullTransformMatrix.TransformPoint(positions[idx]));
|
||||
}
|
||||
|
||||
for (int idx{ 0 }; idx < normals.size(); ++idx)
|
||||
{
|
||||
transformedNormals.push_back(FullTransformMatrix.TransformVector(normals[idx]));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
#pragma endregion
|
||||
|
||||
@@ -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,9 +82,8 @@ 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);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -109,9 +106,48 @@ 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 h = (-v+l).Normalized();
|
||||
ColorRGB f0{};
|
||||
ColorRGB kd{};
|
||||
|
||||
if (m_Metalness == 0)
|
||||
{
|
||||
f0 = ColorRGB( 0.04f,0.04f, 0.04f );
|
||||
|
||||
kd = ColorRGB(1,1,1) - BRDF::FresnelFunction_Schlick(h, -v,f0);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
f0 = m_Albedo;
|
||||
|
||||
kd = ColorRGB(0,0,0);
|
||||
}
|
||||
|
||||
//NORMAL DISTRIBUTION
|
||||
//float normaldistribution = BRDF::NormalDistribution_GGX(hitRecord.normal, h, m_Roughness);
|
||||
//return ColorRGB(normaldistribution, normaldistribution, normaldistribution);
|
||||
|
||||
//GEOMETRIC FUNCTION SMITH
|
||||
//float geoFuncSmith = BRDF::GeometryFunction_Smith(hitRecord.normal, -v, l, m_Roughness);
|
||||
//return ColorRGB(geoFuncSmith, geoFuncSmith, geoFuncSmith);
|
||||
|
||||
//FRESNEL FUNCTION SCHLICK
|
||||
//return BRDF::FresnelFunction_Schlick(h, -v, f0);
|
||||
|
||||
//COOK TORRANCE SPECULAR
|
||||
ColorRGB fcolor (BRDF::NormalDistribution_GGX(hitRecord.normal,h,m_Roughness) * BRDF::FresnelFunction_Schlick(h, -v, f0) * BRDF::GeometryFunction_Smith(hitRecord.normal, -v, l, m_Roughness));
|
||||
|
||||
fcolor = fcolor / (4 * Vector3::Dot(-v, hitRecord.normal) * Vector3::Dot(l, hitRecord.normal));
|
||||
|
||||
//return fcolor;
|
||||
|
||||
//COOK TORRANCE DIFFUSE
|
||||
//return BRDF::Lambert(kd, m_Albedo);
|
||||
|
||||
//FINAL COOK
|
||||
return BRDF::Lambert(kd, m_Albedo) + fcolor;
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -54,22 +54,53 @@ void Renderer::Render(Scene* pScene) const
|
||||
HitRecord closestHit{};
|
||||
pScene->GetClosestHit(viewRay, closestHit);
|
||||
|
||||
|
||||
if (closestHit.didHit)
|
||||
{
|
||||
finalColor = materials[closestHit.materialIndex]->Shade();
|
||||
|
||||
|
||||
|
||||
for (int idx{ 0 }; idx < lights.size(); idx++)
|
||||
{
|
||||
Vector3 lightVec = LightUtils::GetDirectionToLight(lights[idx],closestHit.origin);
|
||||
Ray shadowRay(closestHit.origin + closestHit.normal * 0.0001f, lightVec.Normalized(), 0.0001, lightVec.Magnitude());
|
||||
Vector3 lightVec = LightUtils::GetDirectionToLight(lights[idx], closestHit.origin);
|
||||
float maxRayLenght = lightVec.Normalize();
|
||||
Ray shadowRay(closestHit.origin + closestHit.normal * 0.0001f, lightVec, 0.0001f, maxRayLenght);
|
||||
bool shadowDoesHit = pScene->DoesHit(shadowRay);
|
||||
float observedArea = Vector3::Dot(closestHit.normal, lightVec);
|
||||
|
||||
if (pScene->DoesHit(shadowRay))
|
||||
if (observedArea > 0.f)
|
||||
{
|
||||
finalColor *= 0.5;
|
||||
|
||||
if (!m_ShadowsEnabled or (m_ShadowsEnabled && !shadowDoesHit))
|
||||
{
|
||||
if (m_CurrentLightingMode == LightingMode::ObservedArea)
|
||||
{
|
||||
finalColor += ColorRGB{ observedArea,observedArea,observedArea };
|
||||
}
|
||||
|
||||
if (m_CurrentLightingMode == LightingMode::Radiance)
|
||||
{
|
||||
finalColor += LightUtils::GetRadiance(lights[idx], closestHit.origin);
|
||||
}
|
||||
|
||||
if (m_CurrentLightingMode == LightingMode::BRDF)
|
||||
{
|
||||
finalColor += materials[closestHit.materialIndex]->Shade(closestHit, lightVec, viewRay.direction);
|
||||
}
|
||||
|
||||
if (m_CurrentLightingMode == LightingMode::Combined)
|
||||
{
|
||||
ColorRGB ObservedArea = ColorRGB{ observedArea, observedArea,observedArea};
|
||||
|
||||
ColorRGB Radiance = LightUtils::GetRadiance(lights[idx], closestHit.origin);
|
||||
|
||||
ColorRGB BRDF = materials[closestHit.materialIndex]->Shade(closestHit, lightVec, viewRay.direction);
|
||||
|
||||
finalColor += Radiance * BRDF * ObservedArea;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//const float scaled_t = (closestHit.t - 50.f) / 40.f; //shades spheres based on proximity
|
||||
//finalColor = { scaled_t,scaled_t,scaled_t };
|
||||
|
||||
@@ -22,8 +22,36 @@ namespace dae
|
||||
|
||||
void Render(Scene* pScene) const;
|
||||
bool SaveBufferToImage() const;
|
||||
void CycleLightingMode()
|
||||
{
|
||||
// Cast the current mode to int to check if it's the last mode
|
||||
if (static_cast<int>(m_CurrentLightingMode) == 3)
|
||||
{
|
||||
// Set the mode back to the first one
|
||||
m_CurrentLightingMode = LightingMode::ObservedArea;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// Move to the next mode by incrementing the current one
|
||||
m_CurrentLightingMode = static_cast<LightingMode>(static_cast<int>(m_CurrentLightingMode) + 1);
|
||||
}
|
||||
|
||||
};
|
||||
void ToggleShadows() { m_ShadowsEnabled = !m_ShadowsEnabled; }
|
||||
|
||||
private:
|
||||
|
||||
enum class LightingMode
|
||||
{
|
||||
ObservedArea,
|
||||
Radiance,
|
||||
BRDF,
|
||||
Combined //ObservedArea * Radiance * BRDF
|
||||
};
|
||||
|
||||
LightingMode m_CurrentLightingMode{LightingMode::Combined};
|
||||
bool m_ShadowsEnabled{true};
|
||||
SDL_Window* m_pWindow{};
|
||||
|
||||
SDL_Surface* m_pBuffer{};
|
||||
|
||||
@@ -57,13 +57,38 @@ namespace dae {
|
||||
}
|
||||
}
|
||||
|
||||
//Checks through all the Triangles
|
||||
for (int idx{ 0 }; m_Triangles.size() > idx; idx++)
|
||||
{
|
||||
if (GeometryUtils::HitTest_Triangle(m_Triangles[idx], ray, tempHit)) // Check if there's a hit from planes
|
||||
{
|
||||
if (tempHit.t < closestHit.t)
|
||||
{
|
||||
closestHit = tempHit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Checks through all the Triangles Meshes
|
||||
for (int idx{ 0 }; m_TriangleMeshGeometries.size() > idx; idx++)
|
||||
{
|
||||
if (GeometryUtils::HitTest_TriangleMesh(m_TriangleMeshGeometries[idx], ray, tempHit)) // Check if there's a hit from planes
|
||||
{
|
||||
if (tempHit.t < closestHit.t)
|
||||
{
|
||||
closestHit = tempHit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tempHit = closestHit;
|
||||
}
|
||||
|
||||
bool Scene::DoesHit(const Ray& ray) const
|
||||
{
|
||||
//Checks through all the sphere
|
||||
for (int idx{ 0 }; m_SphereGeometries.size() > idx; idx++)
|
||||
for (int idx{ 0 }; idx < m_SphereGeometries.size() ; ++idx)
|
||||
{
|
||||
if (GeometryUtils::HitTest_Sphere(m_SphereGeometries[idx], ray)) // Check if there's a hit from spheres
|
||||
{
|
||||
@@ -74,12 +99,30 @@ namespace dae {
|
||||
|
||||
for (int idx{ 0 }; idx < m_PlaneGeometries.size(); ++idx)
|
||||
{
|
||||
if (GeometryUtils::HitTest_Plane(m_PlaneGeometries[idx], ray))
|
||||
if (GeometryUtils::HitTest_Plane(m_PlaneGeometries[idx], ray)) // Check if there's a hit from planes
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Checks through all the Triangles
|
||||
for (int idx{ 0 }; idx < m_Triangles.size(); ++idx)
|
||||
{
|
||||
if (GeometryUtils::HitTest_Triangle(m_Triangles[idx], ray))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//Checks through all the Triangles Meshes
|
||||
for (int idx{ 0 };idx < m_TriangleMeshGeometries.size(); idx++)
|
||||
{
|
||||
if (GeometryUtils::HitTest_TriangleMesh(m_TriangleMeshGeometries[idx], ray)) // Check if there's a hit from planes
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -212,4 +255,218 @@ namespace dae {
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Scene_W3::Initialize()
|
||||
{
|
||||
|
||||
m_Camera.origin = { 0.f,3.f,-9.f };
|
||||
m_Camera.fovAngle = 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 },0.f, 1.f));
|
||||
const auto matCT_GrayMediumPlastic = AddMaterial(new Material_CookTorrence({ .75f,.75f,.75f },0.f, .6f));
|
||||
const auto matCT_GraySmoothPlastic = AddMaterial(new Material_CookTorrence({ .75f,.75f,.75f },0.f, .1f));
|
||||
|
||||
const auto matLambert_GrayBlue = AddMaterial(new Material_Lambert({ .49f,.57f,.57f }, 1.f));
|
||||
|
||||
//Plane
|
||||
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
|
||||
|
||||
//Temporary Lambert-Phong Spheres & Materials
|
||||
//const auto matLambertPhong1 = AddMaterial(new Material_LambertPhong(colors::Blue, 0.5, 0.5, 3.f));
|
||||
//const auto matLambertPhong2 = AddMaterial(new Material_LambertPhong(colors::Blue, 0.5, 0.5, 15.f));
|
||||
//const auto matLambertPhong3 = AddMaterial(new Material_LambertPhong(colors::Blue, 0.5, 0.5, 50.f));
|
||||
|
||||
//AddSphere({ -1.75f,1.f,0.f }, .75f, matLambertPhong1);
|
||||
//AddSphere({ 0.f,1.f,0.f }, .75f, matLambertPhong2);
|
||||
//AddSphere({ 1.75f,1.f,0.f }, .75f, matLambertPhong3);
|
||||
|
||||
//Spheres
|
||||
AddSphere({ -1.75f,1.f,0.f },.75f, matCT_GrayRoughMetal);
|
||||
AddSphere({ 0.f,1.f,0.f }, .75f, matCT_GrayMediumMetal);
|
||||
AddSphere({ 1.75f,1.f,0.f }, .75f, matCT_GraySmoothMetal);
|
||||
AddSphere({ -1.75f,3.f,0.f },.75f, matCT_GrayRoughPlastic);
|
||||
AddSphere({ 0.f,3.f,0.f }, .75f, matCT_GrayMediumPlastic);
|
||||
AddSphere({ 1.75f,3.f,0.f }, .75f, matCT_GraySmoothPlastic);
|
||||
|
||||
//Light
|
||||
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 }); //Front Light Right
|
||||
|
||||
|
||||
|
||||
//PHONG TEST SCENE
|
||||
//m_Camera.origin = { 0.f,1.f,-5.f };
|
||||
//m_Camera.fovAngle = 45.f;
|
||||
|
||||
////Materials
|
||||
//const auto matLambert_Red = AddMaterial(new Material_Lambert(colors::Red,1.f));
|
||||
//const auto matLambert_Blue = AddMaterial(new Material_LambertPhong(colors::Blue,1.f,1.f,60.f));
|
||||
//const auto matLambert_Yellow = AddMaterial(new Material_Lambert(colors::Yellow, 1.f));
|
||||
|
||||
////Spheres
|
||||
//AddSphere({ -.75f,1.f,.0f }, 1.f, matLambert_Red);
|
||||
//AddSphere({ .75f,1.f,.0f }, 1.f, matLambert_Blue);
|
||||
|
||||
////Plane
|
||||
//AddPlane({ 0.f,0.f,0.f }, { 0.f,1.f,0.f }, matLambert_Yellow);
|
||||
|
||||
////Light
|
||||
//AddPointLight({ 0.f,5.f,5.f }, 25.f,colors::White);
|
||||
|
||||
//AddPointLight({ 0.f,2.5f,-5.f },25.f,colors::White);
|
||||
}
|
||||
|
||||
|
||||
void Scene_W4::Initialize()
|
||||
{
|
||||
m_Camera.origin = { 0.f, 1.f, -5.f };
|
||||
m_Camera.fovAngle = 45.f;
|
||||
|
||||
// Materials
|
||||
const auto matLambert_GrayBlue = AddMaterial(new Material_Lambert({ 0.49f, 0.57f, 0.57f }, 1.f));
|
||||
const auto matLambert_White = AddMaterial(new Material_Lambert(colors::White, 1.f));
|
||||
|
||||
// Planes
|
||||
AddPlane({ 0.f, 0.f, 10.f },{ 0.f, 0.f, -1.f }, matLambert_GrayBlue); // BACK
|
||||
AddPlane({ 0.f, 0.f, 0.f }, { 0.f, 1.f, 0.f }, matLambert_GrayBlue); // BOTTOM
|
||||
AddPlane({ 0.f, 10.f, 0.f },{ 0.f, -1.f, 0.f }, matLambert_GrayBlue); // TOP
|
||||
AddPlane({ 5.f, 0.f, 0.f }, { -1.f, 0.f, 0.f }, matLambert_GrayBlue); // RIGHT
|
||||
AddPlane({ -5.f, 0.f, 0.f },{ 1.f, 0.f, 0.f }, matLambert_GrayBlue); // LEFT
|
||||
|
||||
// Triangle (Temp)
|
||||
//auto triangle = Triangle{ { -.75f, .5f, 0.f }, { -.75f, 2.f, 0.f }, { .75f, .5f, 0.f } };
|
||||
//triangle.cullMode = TriangleCullMode::FrontFaceCulling;
|
||||
//triangle.materialIndex = matLambert_White;
|
||||
|
||||
//m_Triangles.emplace_back(triangle);
|
||||
|
||||
//const auto triangleMesh = AddTriangleMesh(TriangleCullMode::NoCulling, matLambert_White);
|
||||
//triangleMesh->positions = { { -0.75f, -1.f, 0.f}, { -0.75f, 1.f, 0.f},
|
||||
// { 0.75f, 1.f, 1.f}, { 0.75f, -1.f, 0.f} };
|
||||
|
||||
//triangleMesh->indices = {
|
||||
// 0, 1, 2, // Triangle 1
|
||||
// 0, 2, 3 // Triangle 2
|
||||
//};
|
||||
|
||||
//triangleMesh->CalculateNormals();
|
||||
|
||||
//triangleMesh->Translate({ 0.f,1.5f,0.f });
|
||||
//triangleMesh->RotateY(45);
|
||||
|
||||
//triangleMesh->UpdateTransforms();
|
||||
|
||||
|
||||
pMesh = AddTriangleMesh(TriangleCullMode::BackFaceCulling, matLambert_White);
|
||||
Utils::ParseOBJ("Resources/Warlock.obj",
|
||||
pMesh->positions,
|
||||
pMesh->normals,
|
||||
pMesh->indices);
|
||||
//pMesh->positions = { { -0.75f, -1.f, 0.f}, //v0
|
||||
// { -0.75f, 1.f, 0.f}, //v1
|
||||
// { 0.75f, 1.f, 1.f}, //v2
|
||||
// { 0.75f, -1.f, 0.f} };//v3
|
||||
|
||||
//pMesh->indices = {
|
||||
// 0, 1, 2, // Triangle 1
|
||||
// 0, 2, 3 // Triangle 2
|
||||
//};
|
||||
|
||||
//pMesh->CalculateNormals();
|
||||
//pMesh->Translate({ 0.f,1.5f,0.f });
|
||||
pMesh->RotateY(90);
|
||||
pMesh->UpdateTransforms();
|
||||
|
||||
|
||||
|
||||
// Light
|
||||
AddPointLight({ 0.f, 5.f, 5.f }, 50.f, ColorRGB{ 1.f, .61f, .45f }); // Backlight
|
||||
//AddPointLight({ -2.5f, 5.f, -5.f }, 70.f, ColorRGB{ 1.f, .8f, .45f }); // Front Light Left
|
||||
//AddPointLight({ 2.5f, 5.f, -5.f }, 50.f, ColorRGB{ .34f, .47f, .68f }); // Front Light Right
|
||||
}
|
||||
|
||||
void Scene_W4::Update(dae::Timer* pTimer)
|
||||
{
|
||||
Scene::Update(pTimer);
|
||||
}
|
||||
|
||||
|
||||
void Scene_W4_ReferenceScene::Initialize()
|
||||
{
|
||||
sceneName = "Reference Scene";
|
||||
m_Camera.origin = { 0.f, 3.f, -9.f };
|
||||
m_Camera.fovAngle = 45.f;
|
||||
|
||||
// Materials
|
||||
const auto matCT_GrayRoughMetal = AddMaterial(new Material_CookTorrence({ 0.972f, 0.960f, 0.915f }, 1.f, 1.0f));
|
||||
const auto matCT_GrayMediumMetal = AddMaterial(new Material_CookTorrence({ 0.972f, 0.960f, 0.915f }, 1.f, 0.6f));
|
||||
const auto matCT_GraySmoothMetal = AddMaterial(new Material_CookTorrence({ 0.972f, 0.960f, 0.915f }, 1.f, 0.1f));
|
||||
const auto matCT_GrayRoughPlastic = AddMaterial(new Material_CookTorrence({ 0.75f , 0.75f , 0.75f }, 0.f, 1.0f));
|
||||
const auto matCT_GrayMediumPlastic = AddMaterial(new Material_CookTorrence({ 0.75f , 0.75f , 0.75f }, 0.f, 0.6f));
|
||||
const auto matCT_GraySmoothPlastic = AddMaterial(new Material_CookTorrence({ 0.75f , 0.75f , 0.75f }, 0.f, 0.1f));
|
||||
|
||||
const auto matLambert_GrayBlue = AddMaterial(new Material_Lambert({ 0.49f, 0.57f, 0.57f }, 1.f));
|
||||
const auto matLambert_White = AddMaterial(new Material_Lambert(colors::White, 1.f));
|
||||
|
||||
// Plane
|
||||
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
|
||||
|
||||
// Spheres
|
||||
AddSphere({ -1.75f, 1.f, 0.f, }, 0.75f, matCT_GrayRoughMetal);
|
||||
AddSphere({ 0.f , 1.f, 0.f, }, 0.75f, matCT_GrayMediumMetal);
|
||||
AddSphere({ 1.75f, 1.f, 0.f, }, 0.75f, matCT_GraySmoothMetal);
|
||||
AddSphere({ -1.75f, 3.f, 0.f, }, 0.75f, matCT_GrayRoughPlastic);
|
||||
AddSphere({ 0.f , 3.f, 0.f, }, 0.75f, matCT_GrayMediumPlastic);
|
||||
AddSphere({ 1.75f, 3.f, 0.f, }, 0.75f, matCT_GraySmoothPlastic);
|
||||
|
||||
// Triangle
|
||||
const Triangle baseTriangle = { Vector3(-0.75f, 1.5f, 0.f) //v0
|
||||
, Vector3(0.75f, 0.0f, 0.f) //v1
|
||||
, Vector3(-0.75f, 0.0f, 0.f) }; //v2
|
||||
|
||||
// Triangle Meshes
|
||||
m_Meshes[0] = AddTriangleMesh(TriangleCullMode::BackFaceCulling, matLambert_White);
|
||||
m_Meshes[0]->AppendTriangle(baseTriangle, true);
|
||||
m_Meshes[0]->Translate({ -1.75f, 4.5f, 0.f });
|
||||
m_Meshes[0]->UpdateTransforms();
|
||||
|
||||
m_Meshes[1] = AddTriangleMesh(TriangleCullMode::FrontFaceCulling, matLambert_White);
|
||||
m_Meshes[1]->AppendTriangle(baseTriangle, true);
|
||||
m_Meshes[1]->Translate({ 0.f, 4.5f, 0.f });
|
||||
m_Meshes[1]->UpdateTransforms();
|
||||
|
||||
m_Meshes[2] = AddTriangleMesh(TriangleCullMode::NoCulling, matLambert_White);
|
||||
m_Meshes[2]->AppendTriangle(baseTriangle, true);
|
||||
m_Meshes[2]->Translate({ 1.75f, 4.5f, 0.f });
|
||||
m_Meshes[2]->UpdateTransforms();
|
||||
|
||||
// Light
|
||||
AddPointLight({ 0.f , 5.f , 5.f }, 50.f, ColorRGB{ 1.f , 0.61f, 0.45f }); // BackLight
|
||||
AddPointLight({ -2.5f , 5.f , -5.f }, 70.f, ColorRGB{ 1.f , 0.8f , 0.45f }); // Front Light Left
|
||||
AddPointLight({ 2.5f , 2.5f, -5.f }, 50.f, ColorRGB{ 0.34f, 0.47f, 0.68f });
|
||||
}
|
||||
|
||||
void Scene_W4_ReferenceScene::Update(dae::Timer* pTimer)
|
||||
{
|
||||
Scene::Update(pTimer);
|
||||
|
||||
const auto yawAngle = (cos(pTimer->GetTotal()) + 1.f) / 2.f * PI_2;
|
||||
for (const auto m : m_Meshes)
|
||||
{
|
||||
m->RotateY(yawAngle);
|
||||
m->UpdateTransforms();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,9 @@ namespace dae
|
||||
std::vector<Light> m_Lights{};
|
||||
std::vector<Material*> m_Materials{};
|
||||
|
||||
//Temp (Individual Triangle Test)
|
||||
std::vector<Triangle> m_Triangles{};
|
||||
|
||||
Camera m_Camera{};
|
||||
|
||||
|
||||
@@ -94,5 +97,58 @@ namespace dae
|
||||
void Initialize() override;
|
||||
};
|
||||
|
||||
//WEEK 3 Test Scene
|
||||
class Scene_W3 final : public Scene
|
||||
{
|
||||
public:
|
||||
Scene_W3() = default;
|
||||
~Scene_W3() override = default;
|
||||
|
||||
Scene_W3(const Scene_W3&) = delete;
|
||||
Scene_W3(Scene_W3&&) noexcept = delete;
|
||||
Scene_W3& operator=(const Scene_W3&) = delete;
|
||||
Scene_W3& operator=(Scene_W3&&) noexcept = delete;
|
||||
|
||||
void Initialize() override;
|
||||
};
|
||||
|
||||
//WEEK 4 Test Scene
|
||||
class Scene_W4 final : public Scene
|
||||
{
|
||||
public:
|
||||
Scene_W4() = default;
|
||||
~Scene_W4() override = default;
|
||||
|
||||
Scene_W4(const Scene_W4&) = delete;
|
||||
Scene_W4(Scene_W4&&) noexcept = delete;
|
||||
Scene_W4& operator=(const Scene_W4&) = delete;
|
||||
Scene_W4& operator=(Scene_W4&&) noexcept = delete;
|
||||
|
||||
void Initialize() override;
|
||||
void Update(dae::Timer* pTimer) override;
|
||||
|
||||
private:
|
||||
TriangleMesh* pMesh{ nullptr };
|
||||
};
|
||||
|
||||
|
||||
//WEEK 4 Test Scene
|
||||
class Scene_W4_ReferenceScene final : public Scene
|
||||
{
|
||||
public:
|
||||
Scene_W4_ReferenceScene() = default;
|
||||
~Scene_W4_ReferenceScene() override = default;
|
||||
|
||||
Scene_W4_ReferenceScene(const Scene_W4_ReferenceScene&) = delete;
|
||||
Scene_W4_ReferenceScene(Scene_W4_ReferenceScene&&) noexcept = delete;
|
||||
Scene_W4_ReferenceScene& operator=(const Scene_W4_ReferenceScene&) = delete;
|
||||
Scene_W4_ReferenceScene& operator=(Scene_W4_ReferenceScene&&) noexcept = delete;
|
||||
|
||||
void Initialize() override;
|
||||
void Update(dae::Timer* pTimer) override;
|
||||
private:
|
||||
TriangleMesh* m_Meshes[3]{ };
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace dae
|
||||
|
||||
float tca = Vector3::Dot(lRay, ray.direction);
|
||||
|
||||
float od{ Vector3::Reject(lRay,ray.direction).SqrMagnitude() };
|
||||
float od{ Vector3::Reject(lRay,ray.direction).SqrMagnitude() };
|
||||
|
||||
if (od > sphere.radius * sphere.radius)
|
||||
{
|
||||
@@ -29,12 +29,11 @@ namespace dae
|
||||
float thc{ float(sqrt(sphere.radius*sphere.radius - od)) };
|
||||
|
||||
float t = tca - thc;
|
||||
if (t > ray.min and t < ray.max);
|
||||
else
|
||||
|
||||
if (t < ray.min || t > ray.max)
|
||||
{
|
||||
t = tca + thc;
|
||||
if (t > ray.min and t < ray.max);
|
||||
else return false;
|
||||
if (t < ray.min || t > ray.max) return false;
|
||||
}
|
||||
|
||||
if (!ignoreHitRecord)
|
||||
@@ -45,6 +44,7 @@ namespace dae
|
||||
hitRecord.normal = (hitRecord.origin - sphere.origin).Normalized();
|
||||
hitRecord.materialIndex = sphere.materialIndex;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
@@ -57,20 +57,22 @@ namespace dae
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Plane HitTest
|
||||
//PLANE HIT-TESTS
|
||||
inline bool HitTest_Plane(const Plane& plane, const Ray& ray, HitRecord& hitRecord, bool ignoreHitRecord = false)
|
||||
{
|
||||
float t = Vector3::Dot(plane.origin - ray.origin, plane.normal) / Vector3::Dot(ray.direction ,plane.normal);
|
||||
|
||||
if (t >= ray.min && t < ray.max)
|
||||
if (t >= ray.min && t <= ray.max)
|
||||
{
|
||||
Vector3 p{ ray.origin + t * ray.direction };
|
||||
hitRecord.didHit = true;
|
||||
hitRecord.t = t;
|
||||
hitRecord.materialIndex = plane.materialIndex;
|
||||
hitRecord.normal = plane.normal;
|
||||
|
||||
Vector3 p{ ray.origin + t * ray.direction };
|
||||
|
||||
hitRecord.origin = p;
|
||||
return true;
|
||||
}
|
||||
@@ -86,13 +88,117 @@ namespace dae
|
||||
return HitTest_Plane(plane, ray, temp, true);
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Triangle HitTest
|
||||
//TRIANGLE HIT-TESTS
|
||||
inline bool HitTest_Triangle(const Triangle& triangle, const Ray& ray, HitRecord& hitRecord, bool ignoreHitRecord = false)
|
||||
{
|
||||
//todo W5
|
||||
throw std::runtime_error("Not Implemented Yet");
|
||||
|
||||
float nv(Vector3::Dot(triangle.normal, ray.direction));
|
||||
|
||||
if ( nv < 0.001 && nv > -0.001)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector3 a(triangle.v0, triangle.v1);
|
||||
Vector3 b(triangle.v1, triangle.v2);
|
||||
Vector3 c(triangle.v2, triangle.v0);
|
||||
|
||||
float t = Vector3::Dot(triangle.v0 - ray.origin, triangle.normal) / Vector3::Dot(ray.direction, triangle.normal);
|
||||
|
||||
if (t >= ray.min && t <= ray.max)
|
||||
{
|
||||
|
||||
Vector3 P{ ray.origin + t * ray.direction };
|
||||
const Vector3* triangleV[3] = { &triangle.v0,&triangle.v1,&triangle.v2 };
|
||||
const Vector3* triangleEdges[3]{ &a,&b,&c };
|
||||
|
||||
for (int idx{ 0 }; idx < 3; idx++)
|
||||
{
|
||||
Vector3 p(*triangleV[idx], P);
|
||||
|
||||
if (Vector3::Dot(Vector3::Cross(*triangleEdges[idx], p), triangle.normal) < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (triangle.cullMode == TriangleCullMode::NoCulling)
|
||||
{
|
||||
if (ignoreHitRecord == false)
|
||||
{
|
||||
hitRecord.normal = triangle.normal;
|
||||
hitRecord.didHit = true;
|
||||
hitRecord.materialIndex = triangle.materialIndex;
|
||||
hitRecord.origin = P;
|
||||
hitRecord.t = t;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
else if (triangle.cullMode == TriangleCullMode::BackFaceCulling)
|
||||
{
|
||||
if (ignoreHitRecord == false)
|
||||
{
|
||||
if (nv > 0.001)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
hitRecord.normal = triangle.normal;
|
||||
hitRecord.didHit = true;
|
||||
hitRecord.materialIndex = triangle.materialIndex;
|
||||
hitRecord.origin = P;
|
||||
hitRecord.t = t;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (nv > 0.001)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
else if (triangle.cullMode == TriangleCullMode::FrontFaceCulling)
|
||||
{
|
||||
if (ignoreHitRecord == false)
|
||||
{
|
||||
if (nv < 0.001)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
hitRecord.normal = triangle.normal;
|
||||
hitRecord.didHit = true;
|
||||
hitRecord.materialIndex = triangle.materialIndex;
|
||||
hitRecord.origin = P;
|
||||
hitRecord.t = t;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (nv < 0.001)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
inline bool HitTest_Triangle(const Triangle& triangle, const Ray& ray)
|
||||
@@ -101,12 +207,36 @@ namespace dae
|
||||
return HitTest_Triangle(triangle, ray, temp, true);
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
#pragma region TriangeMesh HitTest
|
||||
inline bool HitTest_TriangleMesh(const TriangleMesh& mesh, const Ray& ray, HitRecord& hitRecord, bool ignoreHitRecord = false)
|
||||
{
|
||||
//todo W5
|
||||
throw std::runtime_error("Not Implemented Yet");
|
||||
return false;
|
||||
HitRecord tempHit = {};
|
||||
|
||||
for (int idx{ 0 }; idx < mesh.indices.size(); idx += 3)
|
||||
{
|
||||
int i0 = mesh.indices[idx];
|
||||
int i1 = mesh.indices[idx + 1];
|
||||
int i2 = mesh.indices[idx + 2];
|
||||
|
||||
Triangle triangle{ mesh.transformedPositions[i0],mesh.transformedPositions[i1],mesh.transformedPositions[i2],mesh.transformedNormals[idx / 3] };
|
||||
|
||||
triangle.materialIndex = mesh.materialIndex;
|
||||
triangle.cullMode = mesh.cullMode;
|
||||
|
||||
HitTest_Triangle(triangle, ray, tempHit);
|
||||
|
||||
if (tempHit.didHit)
|
||||
{
|
||||
if (tempHit.t < hitRecord.t)
|
||||
{
|
||||
hitRecord = tempHit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return hitRecord.didHit;
|
||||
}
|
||||
|
||||
inline bool HitTest_TriangleMesh(const TriangleMesh& mesh, const Ray& ray)
|
||||
@@ -128,9 +258,13 @@ namespace dae
|
||||
|
||||
inline ColorRGB GetRadiance(const Light& light, const Vector3& target)
|
||||
{
|
||||
//todo W3
|
||||
throw std::runtime_error("Not Implemented Yet");
|
||||
return {};
|
||||
if (light.type == LightType::Directional)
|
||||
{
|
||||
return ColorRGB { light.color * light.intensity };
|
||||
}
|
||||
|
||||
return ColorRGB{ light.color * (light.intensity / (Vector3(target,light.origin).SqrMagnitude()) ) };
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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_W4_ReferenceScene();
|
||||
pScene->Initialize();
|
||||
|
||||
|
||||
@@ -74,10 +74,22 @@ int main(int argc, char* args[])
|
||||
case SDL_KEYUP:
|
||||
if (e.key.keysym.scancode == SDL_SCANCODE_X)
|
||||
takeScreenshot = true;
|
||||
if (e.key.keysym.scancode == SDL_SCANCODE_F2)
|
||||
{
|
||||
pRenderer->ToggleShadows();
|
||||
}
|
||||
if (e.key.keysym.scancode == SDL_SCANCODE_F3)
|
||||
{
|
||||
pRenderer->CycleLightingMode();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------- Update ---------
|
||||
pScene->Update(pTimer);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user