Compare commits

...

2 Commits

7 changed files with 271 additions and 67 deletions

View File

@@ -1,8 +1,10 @@
#pragma once
#include <iostream>
#include <SDL_keyboard.h>
#include <SDL_mouse.h>
#include "Maths.h"
#include "SDL_events.h"
#include "Timer.h"
namespace dae
@@ -20,6 +22,10 @@ namespace dae
Vector3 origin{};
float fovAngle{ 90.f };
float previousfovAngle{ fovAngle };
float FOV{ tan((fovAngle * (PI / 180)) / 2) };
float rotSpeed{10};
float movSpeed{ 11 };
Vector3 forward{ Vector3::UnitZ };
Vector3 up{ Vector3::UnitY };
@@ -33,25 +39,111 @@ namespace dae
Matrix CalculateCameraToWorld()
{
//todo: W2
throw std::runtime_error("Not Implemented Yet");
return {};
right = Vector3::Cross(Vector3::UnitY, Camera::forward);
up = Vector3::Cross(Camera::forward, right);
return Matrix(right, up, Camera::forward, Camera::origin);
}
void Update(Timer* pTimer)
{
SDL_SetRelativeMouseMode(SDL_TRUE);
if (fovAngle != previousfovAngle)
{
FOV = tan ((fovAngle * (PI / 180)) / 2);
previousfovAngle = fovAngle;
}
SDL_Event event;
const float deltaTime = pTimer->GetElapsed();
//Keyboard Input
const uint8_t* pKeyboardState = SDL_GetKeyboardState(nullptr);
//Mouse Input
int mouseX{}, mouseY{};
const uint32_t mouseState = SDL_GetRelativeMouseState(&mouseX, &mouseY);
//todo: W2
//throw std::runtime_error("Not Implemented Yet");
// Process mouse movements (relative to the last frame)
if (mouseState & SDL_BUTTON(SDL_BUTTON_RIGHT))
{
if (mouseX != 0 || mouseY != 0)
{
totalPitch = mouseY / rotSpeed * deltaTime;
totalYaw = mouseX / rotSpeed * deltaTime;
if (forward.z < 0)
{
forward = Matrix::CreateRotation(-totalPitch, totalYaw, 0).TransformVector(forward).Normalized();
}
else
{
forward = Matrix::CreateRotation(totalPitch, totalYaw, 0).TransformVector(forward).Normalized();
}
}
}
Vector3 forwardVec = forward.Normalized() * movSpeed * deltaTime;
Vector3 rightVector = Vector3{}.Cross(up , forward).Normalized() * movSpeed * deltaTime;
Vector3 upVector = Vector3{}.Cross(forward,right).Normalized() * movSpeed * deltaTime;
if (pKeyboardState[SDL_SCANCODE_W])
{
origin += forwardVec;
}
if (pKeyboardState[SDL_SCANCODE_S])
{
origin -= forwardVec;
}
if (pKeyboardState[SDL_SCANCODE_D])
{
origin += rightVector;
}
if (pKeyboardState[SDL_SCANCODE_A])
{
origin -= rightVector;
}
if (pKeyboardState[SDL_SCANCODE_SPACE])
{
if (forward.z < 0)
{
origin -= upVector;
}
else
{
origin += upVector;
}
}
if (pKeyboardState[SDL_SCANCODE_LSHIFT])
{
if (forward.z < 0)
{
origin += upVector;
}
else
{
origin -= upVector;
}
}
}
};
}

View File

@@ -103,9 +103,14 @@ namespace dae {
Matrix Matrix::CreateTranslation(float x, float y, float z)
{
//todo W2
throw std::runtime_error("Not Implemented Yet");
return {};
Matrix tMatrix{ Vector4{1,0,0,0},
Vector4{0,1,0,0},
Vector4{0,0,1,0},
Vector4{x,y,z,1} };
return tMatrix;
}
Matrix Matrix::CreateTranslation(const Vector3& t)
@@ -115,30 +120,47 @@ namespace dae {
Matrix Matrix::CreateRotationX(float pitch)
{
//todo W2
throw std::runtime_error("Not Implemented Yet");
return {};
Matrix rMatrix{ Vector4{1,0,0,0},
Vector4{0,cos(pitch),sin(pitch),0},
Vector4{0,-sin(pitch),cos(pitch),0},
Vector4{0,0,0,1}};
return rMatrix;
}
Matrix Matrix::CreateRotationY(float yaw)
{
//todo W2
throw std::runtime_error("Not Implemented Yet");
return {};
Matrix rMatrix{ Vector4{cos(yaw),0,-sin(yaw),0},
Vector4{0,1,0,0},
Vector4{sin(yaw),0,cos(yaw),0},
Vector4{0,0,0,1} };
return rMatrix;
}
Matrix Matrix::CreateRotationZ(float roll)
{
//todo W2
throw std::runtime_error("Not Implemented Yet");
return {};
Matrix rMatrix{ Vector4{cos(roll),sin(roll),0,0},
Vector4{-sin(roll),cos(roll),0,0},
Vector4{0,0,1,0},
Vector4{0,0,0,1} };
return rMatrix;
}
Matrix Matrix::CreateRotation(const Vector3& r)
{
//todo W2
throw std::runtime_error("Not Implemented Yet");
return {};
Matrix rMatrix{ CreateRotationX(r.x) * CreateRotationY(r.y) * CreateRotationZ(r.z)};
return rMatrix;
}
Matrix Matrix::CreateRotation(float pitch, float yaw, float roll)
@@ -148,9 +170,14 @@ namespace dae {
Matrix Matrix::CreateScale(float sx, float sy, float sz)
{
//todo W2
throw std::runtime_error("Not Implemented Yet");
return {};
Matrix sMatrix{ Vector4{sx,0,0,0},
Vector4{0,sy,0,0},
Vector4{0,0,sz,0},
Vector4{0,0,0,1} };
return sMatrix;
}
Matrix Matrix::CreateScale(const Vector3& s)

View File

@@ -23,6 +23,8 @@ Renderer::Renderer(SDL_Window * pWindow) :
SDL_GetWindowSize(pWindow, &m_Width, &m_Height);
m_AspectRatio = (m_Width / float(m_Height)) ;
m_pBufferPixels = static_cast<uint32_t*>(m_pBuffer->pixels);
}
void Renderer::Render(Scene* pScene) const
@@ -31,38 +33,44 @@ void Renderer::Render(Scene* pScene) const
auto& materials = pScene->GetMaterials();
auto& lights = pScene->GetLights();
const Matrix cameraToWorld = camera.CalculateCameraToWorld();
for (int px{}; px < m_Width; ++px)
{
for (int py{}; py < m_Height; ++py)
{
//float gradient = px / static_cast<float>(m_Width);
//gradient += py / static_cast<float>(m_Width);
//gradient /= 2.0f;
//creates a vector that holds a coordinate in 3D space dependent on which pixel the loop is on
Vector3 rayDirection{ float((2 * ((px + 0.5) / m_Width) - 1) * m_AspectRatio),float(1 - 2 * ((py + 0.5) / m_Height)),1};
rayDirection.Normalize();
//Creates a Ray from origin to the point where the current pixel in loop is
Ray viewRay{ {0,0,0},rayDirection};
//Sets screen to black
ColorRGB finalColor{ };
//creates a vector that holds a coordinate in 3D space dependent on which pixel the loop is on
Vector3 rayDirection{ float((2 * ((px + 0.5) / m_Width) - 1) * m_AspectRatio * camera.FOV),float((1 - 2 * ((py + 0.5) / m_Height)) * camera.FOV),1};
rayDirection.Normalize();
rayDirection = cameraToWorld.TransformVector(rayDirection);
//Creates a Ray from origin to the point where the current pixel in loop is
Ray viewRay{ camera.origin,rayDirection };
HitRecord closestHit{};
pScene->GetClosestHit(viewRay, closestHit);
////Makes a tempSphere
//Sphere testSphere{ {0.f,0.f,100.f},50.f,0 };
////Perform Sphere HitTest
//GeometryUtils::HitTest_Sphere(testSphere, 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());
if (pScene->DoesHit(shadowRay))
{
finalColor *= 0.5;
}
}
//const float scaled_t = (closestHit.t - 50.f) / 40.f; //shades spheres based on proximity
//finalColor = { scaled_t,scaled_t,scaled_t };

View File

@@ -28,16 +28,18 @@ namespace dae {
void dae::Scene::GetClosestHit(const Ray& ray, HitRecord& closestHit) const
{
HitRecord tempHit {};
//Checks through all the sphere
for (int idx{0};m_SphereGeometries.size() > idx;idx++)
{
HitRecord tempHit;
if (GeometryUtils::HitTest_Sphere(m_SphereGeometries[idx], ray, tempHit)) // Check if there's a hit from spheres
{
if (tempHit.t < closestHit.t)
{
closestHit = tempHit;
closestHit = tempHit;
}
}
@@ -46,8 +48,6 @@ namespace dae {
//Checks through all the planes
for (int idx{ 0 }; m_PlaneGeometries.size() > idx; idx++)
{
HitRecord tempHit;
if (GeometryUtils::HitTest_Plane(m_PlaneGeometries[idx],ray,tempHit)) // Check if there's a hit from planes
{
if (tempHit.t < closestHit.t)
@@ -56,12 +56,31 @@ namespace dae {
}
}
}
tempHit = closestHit;
}
bool Scene::DoesHit(const Ray& ray) const
{
//todo W2
throw std::runtime_error("Not Implemented Yet");
//Checks through all the sphere
for (int idx{ 0 }; m_SphereGeometries.size() > idx; idx++)
{
if (GeometryUtils::HitTest_Sphere(m_SphereGeometries[idx], ray)) // Check if there's a hit from spheres
{
return true;
}
}
for (int idx{ 0 }; idx < m_PlaneGeometries.size(); ++idx)
{
if (GeometryUtils::HitTest_Plane(m_PlaneGeometries[idx], ray))
{
return true;
}
}
return false;
}
@@ -153,4 +172,44 @@ namespace dae {
AddPlane({ 0.f, 0.f, 125.f }, { 0.f, 0.f,-1.f }, matId_Solid_Magenta);
}
#pragma endregion
void Scene_W2::Initialize()
{
m_Camera.origin = { 0.f,3.f,-9.f };
m_Camera.fovAngle = 45.f;
//default: Material id0 >> SolidColorMaterial (RED)
constexpr unsigned char matId_Solid_Red = 0;
const unsigned char matId_Solid_Blue = AddMaterial(new Material_SolidColor{ colors::Blue });
const unsigned char matId_Solid_Yellow = AddMaterial(new Material_SolidColor{ colors::Yellow });
const unsigned char matId_Solid_Green = AddMaterial(new Material_SolidColor{ colors::Green });
const unsigned char matId_Solid_Magenta = AddMaterial(new Material_SolidColor{ colors::Magenta });
const unsigned char matId_Solid_Porple = AddMaterial(new Material_SolidColor{ ColorRGB(207, 159, 255)});
//Plane
AddPlane({ -5.f,0.f,0.f }, { 1.f,0.f,0.f }, matId_Solid_Green);
AddPlane({ 5.f,0.f,0.f }, { -1.f,0.f,0.f }, matId_Solid_Green);
AddPlane({ 0.f,0.f,0.f }, { 0.f,1.f,0.f }, matId_Solid_Yellow);
AddPlane({ 0.f,10.f,0.f }, { 0.f,-1.f,0.f }, matId_Solid_Yellow);
AddPlane({ 0.f,0.f,10.f }, { 0.f,0.f,-1.f }, matId_Solid_Magenta);
//Spheres
AddSphere({-1.75f,1.f,0.f}, .75f, matId_Solid_Red);
AddSphere({0.f,1.f,0.f}, .75f, matId_Solid_Blue);
AddSphere({ 1.75f,1.f,0.f }, .75f, matId_Solid_Red);
AddSphere({ -1.75f,3.f,0.f }, .75f, matId_Solid_Blue);
AddSphere({ 0.f,3.f,0.f }, .75f, matId_Solid_Red);
AddSphere({ 1.75f,3.f,0.f }, .75f, matId_Solid_Blue);
/*AddSphere({ 0.f,5.f,0.f }, .75f, matId_Solid_Porple);*/
//Light
AddPointLight({ 0.f,5.f,-5.f }, 70.f, colors::White);
}
}

View File

@@ -53,6 +53,7 @@ namespace dae
Camera m_Camera{};
Sphere* AddSphere(const Vector3& origin, float radius, unsigned char materialIndex = 0);
Plane* AddPlane(const Vector3& origin, const Vector3& normal, unsigned char materialIndex = 0);
TriangleMesh* AddTriangleMesh(TriangleCullMode cullMode, unsigned char materialIndex = 0);
@@ -77,4 +78,21 @@ namespace dae
void Initialize() override;
};
//WEEK 2 Test Scene
class Scene_W2 final : public Scene
{
public:
Scene_W2() = default;
~Scene_W2() override = default;
Scene_W2(const Scene_W2&) = delete;
Scene_W2(Scene_W2&&) noexcept = delete;
Scene_W2& operator=(const Scene_W2&) = delete;
Scene_W2& operator=(Scene_W2&&) noexcept = delete;
void Initialize() override;
};
}

View File

@@ -28,26 +28,25 @@ namespace dae
float thc{ float(sqrt(sphere.radius*sphere.radius - od)) };
float t0 = tca - thc;
float t1 = tca + thc;
Vector3 point{ ray.origin + t0 * ray.direction };
Vector3 point2{ ray.origin + t1 * ray.direction };
if (Vector3(ray.direction,point).SqrMagnitude() > Vector3(ray.direction, point2).SqrMagnitude())
float t = tca - thc;
if (t > ray.min and t < ray.max);
else
{
hitRecord.origin = Vector3(ray.direction, point2);
hitRecord.normal = Vector3(sphere.origin, Vector3(ray.direction, point2)).Normalized();
hitRecord.t = t1;
return true;
t = tca + thc;
if (t > ray.min and t < ray.max);
else return false;
}
hitRecord.origin = Vector3(ray.direction, point);
hitRecord.normal = Vector3(sphere.origin, Vector3(ray.direction, point)).Normalized();
hitRecord.t = t0;
if (!ignoreHitRecord)
{
hitRecord.t = t;
hitRecord.didHit = true;
hitRecord.origin = ray.origin + hitRecord.t * ray.direction;
hitRecord.normal = (hitRecord.origin - sphere.origin).Normalized();
hitRecord.materialIndex = sphere.materialIndex;
}
return true;
}
@@ -56,6 +55,7 @@ namespace dae
HitRecord temp{};
return HitTest_Sphere(sphere, ray, temp, true);
}
#pragma endregion
#pragma region Plane HitTest
//PLANE HIT-TESTS
@@ -63,7 +63,7 @@ namespace dae
{
float t = Vector3::Dot(plane.origin - ray.origin, plane.normal) / Vector3::Dot(ray.direction ,plane.normal);
if (t >= 0)
if (t >= ray.min && t < ray.max)
{
hitRecord.didHit = true;
hitRecord.t = t;
@@ -122,9 +122,8 @@ namespace dae
//Direction from target to light
inline Vector3 GetDirectionToLight(const Light& light, const Vector3 origin)
{
//todo W3
throw std::runtime_error("Not Implemented Yet");
return {};
Vector3 lightVec(origin, light.origin);
return lightVec;
}
inline ColorRGB GetRadiance(const Light& light, const Vector3& target)

View File

@@ -47,9 +47,10 @@ int main(int argc, char* args[])
const auto pTimer = new Timer();
const auto pRenderer = new Renderer(pWindow);
const auto pScene = new Scene_W1();
const auto pScene = new Scene_W2();
pScene->Initialize();
//Start loop
pTimer->Start();