mirror of
https://github.com/barkeser2002/flower.git
synced 2026-09-25 19:36:20 +03:00
223 lines
6.0 KiB
C++
223 lines
6.0 KiB
C++
#pragma once
|
|
#include "Pch.h"
|
|
|
|
namespace Flower
|
|
{
|
|
class CameraInterface
|
|
{
|
|
friend class cereal::access;
|
|
|
|
protected:
|
|
// world space position.
|
|
glm::vec3 m_position = { 0.0f, 10.0f, 0.0f};
|
|
|
|
// fov y.
|
|
float m_fovy = glm::radians(45.0f);
|
|
|
|
// z near.
|
|
float m_zNear = 0.1f;
|
|
|
|
// z far.
|
|
float m_zFar = 10'000.0f;
|
|
|
|
// render width.
|
|
size_t m_width = GMinRenderDim;
|
|
|
|
// render height.
|
|
size_t m_height = GMinRenderDim;
|
|
|
|
// camera front direction.
|
|
glm::vec3 m_front = { 0.0f, 0.0f, 1.0f };
|
|
|
|
// camera up direction.
|
|
glm::vec3 m_up;
|
|
|
|
// camera right direction;
|
|
glm::vec3 m_right;
|
|
|
|
public:
|
|
float atmosphereHeightOffset = 0.5f; // km.
|
|
|
|
float atmosphereMoveScale = 1.0f; //
|
|
|
|
float aperture = 10.0f; // Size of the lens diaphragm (mm). Controls depth of field and chromatic aberration.
|
|
float shutterSpeed = 12.0f; // Length of time for which the camera shutter is open (sec). Also controls the amount of motion blur.
|
|
float iso = 800.0f; // Sensitivity to light.
|
|
float exposureCompensation = 0.0f;
|
|
|
|
// Reference: https://google.github.io/filament/Filament.md.html#lighting/units/lightunitsvalidation
|
|
float getEv100() const
|
|
{
|
|
return std::log2((aperture * aperture) / shutterSpeed * 100.0f / iso);
|
|
}
|
|
|
|
// Frostbite: https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf
|
|
// https://docs.unrealengine.com/4.27/en-US/RenderingAndGraphics/PostProcessEffects/AutomaticExposure/
|
|
float getExposure() const
|
|
{
|
|
return 1.0f / (std::pow(2.0f, getEv100() + exposureCompensation));
|
|
}
|
|
|
|
struct Frustum
|
|
{
|
|
std::array<glm::vec4, 6> planes;
|
|
|
|
enum side
|
|
{
|
|
LEFT = 0,
|
|
DOWN = 1,
|
|
RIGHT = 2,
|
|
TOP = 3,
|
|
FRONT = 4,
|
|
BACK = 5
|
|
};
|
|
|
|
static Frustum get(glm::mat4 matrix)
|
|
{
|
|
Frustum res{};
|
|
|
|
res.planes[LEFT].x = matrix[0].w + matrix[0].x;
|
|
res.planes[LEFT].y = matrix[1].w + matrix[1].x;
|
|
res.planes[LEFT].z = matrix[2].w + matrix[2].x;
|
|
res.planes[LEFT].w = matrix[3].w + matrix[3].x;
|
|
|
|
res.planes[RIGHT].x = matrix[0].w - matrix[0].x;
|
|
res.planes[RIGHT].y = matrix[1].w - matrix[1].x;
|
|
res.planes[RIGHT].z = matrix[2].w - matrix[2].x;
|
|
res.planes[RIGHT].w = matrix[3].w - matrix[3].x;
|
|
|
|
res.planes[TOP].x = matrix[0].w - matrix[0].y;
|
|
res.planes[TOP].y = matrix[1].w - matrix[1].y;
|
|
res.planes[TOP].z = matrix[2].w - matrix[2].y;
|
|
res.planes[TOP].w = matrix[3].w - matrix[3].y;
|
|
|
|
res.planes[DOWN].x = matrix[0].w + matrix[0].y;
|
|
res.planes[DOWN].y = matrix[1].w + matrix[1].y;
|
|
res.planes[DOWN].z = matrix[2].w + matrix[2].y;
|
|
res.planes[DOWN].w = matrix[3].w + matrix[3].y;
|
|
|
|
res.planes[BACK].x = matrix[0].w + matrix[0].z;
|
|
res.planes[BACK].y = matrix[1].w + matrix[1].z;
|
|
res.planes[BACK].z = matrix[2].w + matrix[2].z;
|
|
res.planes[BACK].w = matrix[3].w + matrix[3].z;
|
|
|
|
res.planes[FRONT].x = matrix[0].w - matrix[0].z;
|
|
res.planes[FRONT].y = matrix[1].w - matrix[1].z;
|
|
res.planes[FRONT].z = matrix[2].w - matrix[2].z;
|
|
res.planes[FRONT].w = matrix[3].w - matrix[3].z;
|
|
|
|
for (auto i = 0; i < res.planes.size(); i++)
|
|
{
|
|
float length = sqrtf(res.planes[i].x * res.planes[i].x + res.planes[i].y * res.planes[i].y + res.planes[i].z * res.planes[i].z);
|
|
res.planes[i] /= length;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
};
|
|
|
|
Frustum getWorldFrustum() const
|
|
{
|
|
const glm::vec3 forwardVector = glm::normalize(m_front);
|
|
const glm::vec3 camWorldPos = m_position;
|
|
|
|
const glm::vec3 nearC = camWorldPos + forwardVector * m_zNear;
|
|
const glm::vec3 farC = camWorldPos + forwardVector * m_zFar;
|
|
|
|
const float tanFovyHalf = glm::tan(getFovY() * 0.5f);
|
|
const float aspect = getAspect();
|
|
|
|
const float yNearHalf = m_zNear * tanFovyHalf;
|
|
const float yFarHalf = m_zFar * tanFovyHalf;
|
|
|
|
const glm::vec3 yNearHalfV = yNearHalf * m_up;
|
|
const glm::vec3 xNearHalfV = yNearHalf * aspect * m_right;
|
|
|
|
const glm::vec3 yFarHalfV = yFarHalf * m_up;
|
|
const glm::vec3 xFarHalfV = yFarHalf * aspect * m_right;
|
|
|
|
const glm::vec3 NRT = nearC + xNearHalfV + yNearHalfV;
|
|
const glm::vec3 NRD = nearC + xNearHalfV - yNearHalfV;
|
|
const glm::vec3 NLT = nearC - xNearHalfV + yNearHalfV;
|
|
const glm::vec3 NLD = nearC - xNearHalfV - yNearHalfV;
|
|
|
|
const glm::vec3 FRT = farC + xFarHalfV + yFarHalfV;
|
|
const glm::vec3 FRD = farC + xFarHalfV - yFarHalfV;
|
|
const glm::vec3 FLT = farC - xFarHalfV + yFarHalfV;
|
|
const glm::vec3 FLD = farC - xFarHalfV - yFarHalfV;
|
|
|
|
Frustum ret{};
|
|
|
|
// p1 X p2, center is pC.
|
|
auto getNormal = [](const glm::vec3& pC, const glm::vec3& p1, const glm::vec3& p2)
|
|
{
|
|
const glm::vec3 dir0 = p1 - pC;
|
|
const glm::vec3 dir1 = p2 - pC;
|
|
const glm::vec3 crossDir = glm::cross(dir0, dir1);
|
|
return glm::normalize(crossDir);
|
|
};
|
|
|
|
// left
|
|
const glm::vec3 leftN = getNormal(FLD, FLT, NLD);
|
|
ret.planes[0] = glm::vec4(leftN, -glm::dot(leftN, FLD));
|
|
|
|
// down
|
|
const glm::vec3 downN = getNormal(FRD, FLD, NRD);
|
|
ret.planes[1] = glm::vec4(downN, -glm::dot(downN, FRD));
|
|
|
|
// right
|
|
const glm::vec3 rightN = getNormal(FRT, FRD, NRT);
|
|
ret.planes[2] = glm::vec4(rightN, -glm::dot(rightN, FRT));
|
|
|
|
// top
|
|
const glm::vec3 topN = getNormal(FLT, FRT, NLT);
|
|
ret.planes[3] = glm::vec4(topN, -glm::dot(topN, FLT));
|
|
|
|
// front
|
|
const glm::vec3 frontN = getNormal(NRT, NRD, NLT);
|
|
ret.planes[4] = glm::vec4(frontN, -glm::dot(frontN, NRT));
|
|
|
|
// back
|
|
const glm::vec3 backN = getNormal(FRT, FLT, FRD);
|
|
ret.planes[5] = glm::vec4(backN, -glm::dot(backN, FRT));
|
|
|
|
return ret;
|
|
}
|
|
|
|
// return camera worldspcae position.
|
|
glm::vec3 getPosition() const
|
|
{
|
|
return m_position;
|
|
}
|
|
|
|
// return camera view matrix.
|
|
virtual glm::mat4 getViewMatrix() const = 0;
|
|
|
|
// return camera project matrix.
|
|
virtual glm::mat4 getProjectMatrix() const = 0;
|
|
|
|
// return camera aspect.
|
|
float getAspect() const
|
|
{
|
|
return (float)m_width / (float)m_height;
|
|
}
|
|
|
|
// return camera fov y.
|
|
float getFovY() const
|
|
{
|
|
return m_fovy;
|
|
}
|
|
|
|
// return camera z near plane.
|
|
float getZNear() const
|
|
{
|
|
return m_zNear;
|
|
}
|
|
|
|
// return camera z far plane.
|
|
float getZFar() const
|
|
{
|
|
return m_zFar;
|
|
}
|
|
};
|
|
} |