Add camera and shadows (week2)
This commit is contained in:
@@ -33,9 +33,16 @@ namespace dae
|
|||||||
|
|
||||||
Matrix CalculateCameraToWorld()
|
Matrix CalculateCameraToWorld()
|
||||||
{
|
{
|
||||||
//todo: W2
|
right = Vector3::Cross(Vector3::UnitY, forward).Normalized();
|
||||||
// throw std::runtime_error("Not Implemented Yet");
|
up = Vector3::Cross(forward, right).Normalized();
|
||||||
return {};
|
|
||||||
|
Matrix matrix {
|
||||||
|
Vector4{right, 0},
|
||||||
|
Vector4{up, 0},
|
||||||
|
Vector4{forward, 0},
|
||||||
|
Vector4{origin, 0},
|
||||||
|
};
|
||||||
|
return matrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Update(Timer* pTimer)
|
void Update(Timer* pTimer)
|
||||||
@@ -44,14 +51,59 @@ namespace dae
|
|||||||
|
|
||||||
//Keyboard Input
|
//Keyboard Input
|
||||||
const uint8_t* pKeyboardState = SDL_GetKeyboardState(nullptr);
|
const uint8_t* pKeyboardState = SDL_GetKeyboardState(nullptr);
|
||||||
|
{
|
||||||
|
float speed{10.f};
|
||||||
|
|
||||||
|
if (pKeyboardState[SDL_SCANCODE_W]) {
|
||||||
|
origin += forward * deltaTime * speed;
|
||||||
|
}
|
||||||
|
if (pKeyboardState[SDL_SCANCODE_S]) {
|
||||||
|
origin -= forward * deltaTime * speed;
|
||||||
|
}
|
||||||
|
if (pKeyboardState[SDL_SCANCODE_D]) {
|
||||||
|
origin += right * deltaTime * speed;
|
||||||
|
}
|
||||||
|
if (pKeyboardState[SDL_SCANCODE_A]) {
|
||||||
|
origin -= right * deltaTime * speed;
|
||||||
|
}
|
||||||
|
|
||||||
//Mouse Input
|
if (pKeyboardState[SDL_SCANCODE_Q]) {
|
||||||
|
origin -= Vector3::UnitY * deltaTime * speed;
|
||||||
|
}
|
||||||
|
if (pKeyboardState[SDL_SCANCODE_E]) {
|
||||||
|
origin += Vector3::UnitY * deltaTime * speed;
|
||||||
|
}
|
||||||
|
}
|
||||||
int mouseX{}, mouseY{};
|
int mouseX{}, mouseY{};
|
||||||
const uint32_t mouseState = SDL_GetRelativeMouseState(&mouseX, &mouseY);
|
const uint32_t mouseState = SDL_GetRelativeMouseState(&mouseX, &mouseY);
|
||||||
|
|
||||||
//todo: W2
|
bool dirty = false;
|
||||||
//throw std::runtime_error("Not Implemented Yet");
|
|
||||||
|
float speed{ 0.15f };
|
||||||
|
|
||||||
|
if(mouseX)
|
||||||
|
{
|
||||||
|
totalYaw += mouseX * speed;
|
||||||
|
totalPitch = std::fmod(totalPitch, 180.f);
|
||||||
|
dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mouseY)
|
||||||
|
{
|
||||||
|
totalPitch += mouseY * speed;
|
||||||
|
totalPitch = std::clamp(totalPitch, -85.f, 85.f);
|
||||||
|
dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dirty)
|
||||||
|
{
|
||||||
|
Matrix rotMat{
|
||||||
|
Matrix::CreateRotationX(TO_RADIANS * totalPitch) * Matrix::CreateRotationY(TO_RADIANS * totalYaw)
|
||||||
|
};
|
||||||
|
|
||||||
|
forward = rotMat.TransformVector(Vector3::UnitZ);
|
||||||
|
right = rotMat.TransformVector(Vector3::UnitX);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ void Renderer::Render(Scene *pScene) const {
|
|||||||
auto &materials = pScene->GetMaterials();
|
auto &materials = pScene->GetMaterials();
|
||||||
auto &lights = pScene->GetLights();
|
auto &lights = pScene->GetLights();
|
||||||
|
|
||||||
|
Matrix CameraToWorld = camera.CalculateCameraToWorld();
|
||||||
|
|
||||||
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) {
|
||||||
@@ -35,20 +37,38 @@ void Renderer::Render(Scene *pScene) const {
|
|||||||
|
|
||||||
|
|
||||||
Vector3 rayDir = Vector3{NDCx, NDCy, 1};
|
Vector3 rayDir = Vector3{NDCx, NDCy, 1};
|
||||||
|
rayDir = CameraToWorld.TransformVector((rayDir));
|
||||||
rayDir.Normalize();
|
rayDir.Normalize();
|
||||||
|
|
||||||
Ray ray{camera.origin, rayDir};
|
Ray ray{camera.origin, rayDir};
|
||||||
|
|
||||||
|
|
||||||
//set the color based on the ray direction
|
//set the color based on the ray direction
|
||||||
ColorRGB finalColor{0.f, 0.f, 0.f};
|
ColorRGB finalColor{0.f, 0.f, 0.f};
|
||||||
|
|
||||||
HitRecord closestHit{};
|
HitRecord closestHit{};
|
||||||
Plane testPlane{{0.f, -50.f, 0.f}, {0.f, 1.f, 0.f}, 0};
|
|
||||||
// GeometryUtils::HitTest_Plane(testPlane, ray, closestHit);
|
|
||||||
pScene->GetClosestHit(ray, closestHit);
|
pScene->GetClosestHit(ray, closestHit);
|
||||||
|
|
||||||
if (closestHit.didHit) {
|
if (closestHit.didHit) {
|
||||||
finalColor = materials[closestHit.materialIndex]->Shade();
|
finalColor = materials[closestHit.materialIndex]->Shade();
|
||||||
|
|
||||||
|
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;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
finalColor.MaxToOne();
|
finalColor.MaxToOne();
|
||||||
|
|||||||
@@ -46,9 +46,22 @@ namespace dae {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Scene::DoesHit(const Ray &ray) const {
|
bool Scene::DoesHit(const Ray& ray) const
|
||||||
//todo W2
|
{
|
||||||
throw std::runtime_error("Not Implemented Yet");
|
HitRecord hit;
|
||||||
|
|
||||||
|
for(const Sphere& sphere : m_SphereGeometries)
|
||||||
|
{
|
||||||
|
if(GeometryUtils::HitTest_Sphere(sphere, ray, hit, true))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(const Plane& plane : m_PlaneGeometries)
|
||||||
|
{
|
||||||
|
if(GeometryUtils::HitTest_Plane(plane, ray, hit, true))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,27 +17,26 @@ namespace dae
|
|||||||
|
|
||||||
if(tInSphere < 0) return false; //Looking away from sphere
|
if(tInSphere < 0) return false; //Looking away from sphere
|
||||||
|
|
||||||
const float od2 = std::pow(Vector3::Reject(CameraToOrigin, ray.direction).Magnitude(),2);
|
float originToInsideDist2 = CameraToOrigin.SqrMagnitude() - tInSphere * tInSphere;
|
||||||
const float thc = std::sqrt(radius2 - od2);
|
if(originToInsideDist2 > radius2)
|
||||||
|
return false; // 'inside' point is outside of sphere
|
||||||
|
|
||||||
float t0 = tInSphere - thc;
|
float tDiff = std::sqrt(radius2 - originToInsideDist2);
|
||||||
float t1 = tInSphere + thc;
|
float t = tInSphere - tDiff;
|
||||||
|
|
||||||
if(t0 < 0 && t1 < 0) return false; //Both intersections are behind the camera
|
const bool hit = t > ray.min && t < ray.max;
|
||||||
|
|
||||||
if(t0 < 0) t0 = t1; //If t0 is behind the camera, use t1
|
|
||||||
|
|
||||||
if (!ignoreHitRecord && t0 < hitRecord.t){
|
if (!ignoreHitRecord && hit){
|
||||||
hitRecord.t = t0;
|
hitRecord.t = t;
|
||||||
hitRecord.origin = ray.origin + ray.direction * t0;
|
hitRecord.origin = ray.origin + ray.direction * t;
|
||||||
hitRecord.normal = (hitRecord.origin - sphere.origin).Normalized();
|
hitRecord.normal = (hitRecord.origin - sphere.origin).Normalized();
|
||||||
hitRecord.materialIndex = sphere.materialIndex;
|
hitRecord.materialIndex = sphere.materialIndex;
|
||||||
hitRecord.didHit = true;
|
hitRecord.didHit = true;
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return hit;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,8 +53,10 @@ namespace dae
|
|||||||
float dot = Vector3::Dot(plane.normal, ray.direction);
|
float dot = Vector3::Dot(plane.normal, ray.direction);
|
||||||
if(dot < 0) {
|
if(dot < 0) {
|
||||||
// float t = Vector3::Dot(plane.origin - ray.origin, plane.normal) / dot;
|
// float t = Vector3::Dot(plane.origin - ray.origin, plane.normal) / dot;
|
||||||
float t = Vector3::Dot(plane.origin - ray.origin, plane.normal) / Vector3::Dot(ray.direction, plane.normal);
|
float t = Vector3::Dot(plane.origin - ray.origin, plane.normal);
|
||||||
bool hit = t >= 0;
|
t /= dot;
|
||||||
|
|
||||||
|
const bool hit = t > ray.min && t < ray.max;
|
||||||
|
|
||||||
if(hit && !ignoreHitRecord){
|
if(hit && !ignoreHitRecord){
|
||||||
hitRecord.t = t;
|
hitRecord.t = t;
|
||||||
@@ -113,9 +114,7 @@ namespace dae
|
|||||||
//Direction from target to light
|
//Direction from target to light
|
||||||
inline Vector3 GetDirectionToLight(const Light& light, const Vector3 origin)
|
inline Vector3 GetDirectionToLight(const Light& light, const Vector3 origin)
|
||||||
{
|
{
|
||||||
//todo W3
|
return { light.origin - origin };
|
||||||
throw std::runtime_error("Not Implemented Yet");
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ColorRGB GetRadiance(const Light& light, const Vector3& target)
|
inline ColorRGB GetRadiance(const Light& light, const Vector3& target)
|
||||||
|
|||||||
Reference in New Issue
Block a user