cascade shadow wip
This commit is contained in:
@@ -9,11 +9,18 @@
|
||||
#include "ShadowPassState.h"
|
||||
#include "imgui/imgui.h"
|
||||
|
||||
#define MAX_SPLITS 5
|
||||
|
||||
//#include "ShadowPassState.h" // not created yet
|
||||
|
||||
enum NearFar { Near = 0, Far = 1 };
|
||||
enum LRBT { Left = 0, Right = 1, Bottom = 2, Top = 3 };
|
||||
|
||||
struct ShadowCamera{
|
||||
Camera* camera;
|
||||
std::array<glm::vec3, 8> frustumCorners;
|
||||
};
|
||||
|
||||
class ShadowPass
|
||||
{
|
||||
public:
|
||||
@@ -37,7 +44,10 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
|
||||
void CalculateFrustum(RenderScene & scene, std::shared_ptr<DirectionalLightJob> directionalLightJob);
|
||||
glm::vec3 LightDirectionToPoint(glm::vec4 direction);
|
||||
std::array<glm::vec3, 8> UpdateFrustumPoints(Camera* cam, glm::vec3 center, glm::vec3 view_dir);
|
||||
void UpdateSplitDist(std::array<ShadowCamera, MAX_SPLITS> shadow_cams, float far_distance, float near_distance);
|
||||
|
||||
EventBroker* m_EventBroker;
|
||||
|
||||
@@ -52,7 +62,8 @@ private:
|
||||
GLuint m_DepthFBO;
|
||||
|
||||
GLfloat m_NearFarPlane[2] = { -34.f, 27.f };
|
||||
GLfloat m_LRBT[4] = { -77.f, 75.f, -89.f, 89.f };
|
||||
//GLfloat m_LRBT[4] = { -77.f, 75.f, -89.f, 89.f };
|
||||
GLfloat m_LRBT[4] = { -10.f, 10.f, -10.f, 10.f };
|
||||
|
||||
glm::mat4 m_LightProjection;
|
||||
glm::mat4 m_LightView;
|
||||
@@ -62,6 +73,11 @@ private:
|
||||
GLuint resolutionSizeHeigth = 1024 * 8;
|
||||
|
||||
bool m_ShadowOn = true;
|
||||
|
||||
int m_CurrentNrOfSplits = 3;
|
||||
float m_SplitWeight = 0.75f;
|
||||
|
||||
std::array<ShadowCamera, MAX_SPLITS> shadCams;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -228,8 +228,10 @@ void main()
|
||||
totalLighting.Specular += light_result.Specular;
|
||||
}
|
||||
|
||||
totalLighting.Diffuse *= (1.5 + vec4(AmbientColor.rgb, 1.0)) - vec4(vec3(shadowFactor), 0.0);
|
||||
totalLighting.Specular *= (1.5 + vec4(AmbientColor.rgb, 1.0)) - vec4(vec3(shadowFactor), 0.0);
|
||||
//totalLighting.Diffuse *= (1.5 + vec4(AmbientColor.rgb, 1.0)) - vec4(vec3(shadowFactor), 0.0);
|
||||
//totalLighting.Specular *= (1.5 + vec4(AmbientColor.rgb, 1.0)) - vec4(vec3(shadowFactor), 0.0);
|
||||
totalLighting.Diffuse *= (1.0 + vec4(AmbientColor.rgb, 1.0)) + vec4(vec3(shadowFactor, shadowFactor, 0.0), 0.0);
|
||||
totalLighting.Specular *= (1.0 + vec4(AmbientColor.rgb, 1.0)) + vec4(vec3(shadowFactor, shadowFactor, 0.0), 0.0);
|
||||
|
||||
//LightResult getInformation;
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ EditorRenderSystem::EditorRenderSystem(World* m_World, EventBroker* eventBroker,
|
||||
{
|
||||
EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &EditorRenderSystem::OnSetCamera);
|
||||
auto resolution = Rectangle::Rectangle(1280, 720);
|
||||
m_EditorCamera = new Camera((float)resolution.Width / resolution.Height, glm::radians(45.f), 0.01f, 5000.f);
|
||||
m_EditorCamera = new Camera((float)resolution.Width / resolution.Height, glm::radians(45.f), 0.01f, 500.f);
|
||||
}
|
||||
|
||||
void EditorRenderSystem::Update(double dt)
|
||||
|
||||
@@ -10,7 +10,7 @@ RenderSystem::RenderSystem(World* world, EventBroker* eventBroker, const IRender
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &RenderSystem::OnInputCommand);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &RenderSystem::OnPlayerSpawned);
|
||||
|
||||
m_Camera = new Camera((float)m_Renderer->Resolution().Width / m_Renderer->Resolution().Height, glm::radians(45.f), 0.01f, 5000.f);
|
||||
m_Camera = new Camera((float)m_Renderer->Resolution().Width / m_Renderer->Resolution().Height, glm::radians(45.f), 0.01f, 300.f);
|
||||
}
|
||||
|
||||
RenderSystem::~RenderSystem()
|
||||
|
||||
@@ -14,6 +14,86 @@ ShadowPass::~ShadowPass()
|
||||
|
||||
}
|
||||
|
||||
// Compute the 8 corner points of the current view frustum
|
||||
std::array<glm::vec3, 8> ShadowPass::UpdateFrustumPoints(Camera* cam, glm::vec3 center, glm::vec3 view_dir)
|
||||
{
|
||||
glm::vec3 up = glm::vec3(0.f, 1.f, 0.f);
|
||||
glm::vec3 right = glm::normalize(glm::cross(view_dir, up));
|
||||
|
||||
glm::vec3 farCenter = center + view_dir * cam->FarClip();
|
||||
glm::vec3 nearCenter = center + view_dir * cam->NearClip();
|
||||
|
||||
up = glm::normalize(glm::cross(right, view_dir));
|
||||
|
||||
float near_height = tan(cam->FOV() / 2.0f) * cam->NearClip();
|
||||
float near_width = near_height * cam->AspectRatio();
|
||||
float far_height = tan(cam->FOV() / 2.0f) * cam->FarClip();
|
||||
float far_width = far_height * cam->AspectRatio();
|
||||
|
||||
std::array<glm::vec3, 8> frustumPoints;
|
||||
frustumPoints[0] = nearCenter - up*near_height - right*near_width;
|
||||
frustumPoints[1] = nearCenter + up*near_height - right*near_width;
|
||||
frustumPoints[2] = nearCenter + up*near_height + right*near_width;
|
||||
frustumPoints[3] = nearCenter - up*near_height + right*near_width;
|
||||
|
||||
frustumPoints[4] = farCenter - up*far_height - right*far_width;
|
||||
frustumPoints[5] = farCenter + up*far_height - right*far_width;
|
||||
frustumPoints[6] = farCenter + up*far_height + right*far_width;
|
||||
frustumPoints[7] = farCenter - up*far_height + right*far_width;
|
||||
|
||||
return frustumPoints;
|
||||
}
|
||||
|
||||
// UpdateSplitDist computes the near and far distances for every frustum slice
|
||||
// in camera eye space - that is, at what distance does a slice start and end
|
||||
void ShadowPass::UpdateSplitDist(std::array<ShadowCamera, MAX_SPLITS> shadow_cams, float far_distance, float near_distance)
|
||||
{
|
||||
float lambda = m_SplitWeight;
|
||||
float ratio = far_distance / near_distance;
|
||||
|
||||
shadow_cams[0].camera->SetNearClip(near_distance);
|
||||
|
||||
for (int i = 1; i < m_CurrentNrOfSplits; i++) {
|
||||
float si = i / static_cast<float>(m_CurrentNrOfSplits);
|
||||
|
||||
shadow_cams[i].camera->SetNearClip(lambda * (near_distance * powf(ratio, si)) + (1 - lambda) * (near_distance + (far_distance - near_distance) * si));
|
||||
shadow_cams[i - 1].camera->SetFarClip(shadow_cams[i].camera->NearClip() * 1.005f);
|
||||
}
|
||||
|
||||
shadow_cams[m_CurrentNrOfSplits - 1].camera->SetFarClip(far_distance);
|
||||
}
|
||||
|
||||
float applyCropMatrix()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// GLM wants a point for glm::lookAt, brute out a point that is on the light direction's tangent.
|
||||
glm::vec3 ShadowPass::LightDirectionToPoint(glm::vec4 direction)
|
||||
{
|
||||
return -glm::normalize(glm::vec3(direction));
|
||||
}
|
||||
|
||||
void ShadowPass::CalculateFrustum(RenderScene & scene, std::shared_ptr<DirectionalLightJob> directionalLightJob)
|
||||
{
|
||||
//m_LightView = glm::lookAt(LightDirectionToPoint(directionalLightJob->Direction), glm::vec3(0.f, 0.f, 0.f), glm::vec3(0.f, 1.f, 0.f));
|
||||
|
||||
m_LightProjection = glm::ortho(m_LRBT[Left], m_LRBT[Right], m_LRBT[Bottom], m_LRBT[Top], m_NearFarPlane[Near], m_NearFarPlane[Far]);
|
||||
|
||||
glm::vec3 LightPoint = LightDirectionToPoint(directionalLightJob->Direction);
|
||||
|
||||
float CameraDistance = scene.Camera->FarClip() - scene.Camera->NearClip();
|
||||
float CameraPercentiles[3] = { 0.f, CameraDistance * 0.2f, CameraDistance * 0.65f };
|
||||
|
||||
|
||||
glm::vec3 point = scene.Camera->Position() + (scene.Camera->Forward() * 30.f);
|
||||
|
||||
m_LightView = glm::lookAt(LightPoint + point, point, glm::vec3(0.f, 1.f, 0.f));
|
||||
|
||||
m_LightSpaceMatrix = m_LightProjection * m_LightView;
|
||||
|
||||
//scene.Camera->
|
||||
}
|
||||
|
||||
void ShadowPass::InitializeFrameBuffers()
|
||||
{
|
||||
@@ -29,9 +109,10 @@ void ShadowPass::InitializeFrameBuffers()
|
||||
//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height, 0, GL_RGB, GL_FLOAT, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
|
||||
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, glm::vec4(1.f).data);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
|
||||
|
||||
@@ -84,11 +165,7 @@ void ShadowPass::Draw(RenderScene & scene)
|
||||
auto directionalLightJob = std::dynamic_pointer_cast<DirectionalLightJob>(job);
|
||||
|
||||
if(directionalLightJob) {
|
||||
//m_LightProjection = glm::ortho(m_LRBT[Left], m_LRBT[Right], m_LRBT[Bottom], m_LRBT[Top], m_NearFarPlane[Near], m_NearFarPlane[Far]);
|
||||
m_LightProjection = glm::ortho(m_LRBT[Left], m_LRBT[Right], m_LRBT[Bottom], m_LRBT[Top], m_NearFarPlane[Near], m_NearFarPlane[Far]);
|
||||
m_LightView = glm::lookAt(-glm::normalize(glm::vec3(directionalLightJob->Direction)), glm::vec3(0.f,0.f,0.f), glm::vec3(0.f,1.f,0.f));
|
||||
//m_LightView = glm::lookAt(glm::vec3(-20.0f, 20.0f, -20.0f), glm::vec3(0.0f), glm::vec3(1.0));
|
||||
m_LightSpaceMatrix = m_LightProjection * m_LightView;
|
||||
CalculateFrustum(scene, directionalLightJob);
|
||||
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_LightProjection));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_LightView));
|
||||
|
||||
Reference in New Issue
Block a user