mirror of
https://github.com/antopilo/Nuake.git
synced 2026-01-03 14:09:46 +03:00
Added spotlight shadows with dynamic FOV shadowmaps
This commit is contained in:
@@ -366,7 +366,7 @@ void GizmoDrawer::DrawGizmos(Ref<Scene> scene, bool occluded)
|
||||
Matrix4 gizmoPosition = Matrix4(1.0f);
|
||||
gizmoPosition = glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3]));
|
||||
gizmoPosition = gizmoPosition * rotationMatrix;
|
||||
gizmoPosition = glm::translate(gizmoPosition, { 0, -cylinderLength / 2.0, 0 });
|
||||
gizmoPosition = glm::translate(gizmoPosition, { 0, cylinderLength / 2.0, 0 });
|
||||
|
||||
m_LineShader->Bind();
|
||||
m_LineShader->SetUniform1f("u_Opacity", 1.0f);
|
||||
|
||||
@@ -325,7 +325,23 @@ namespace Nuake
|
||||
{
|
||||
int shadowMapTextureSlot = 22 + spotShadowMapCount;
|
||||
deferredShader->SetUniform1f(uniformAccessor + "ShadowMapID", shadowMapTextureSlot);
|
||||
deferredShader->SetUniformMat4f(uniformAccessor + "Transform", light.GetProjection() * transform.GetGlobalTransform());
|
||||
|
||||
Matrix4 spotLightTransform = Matrix4(1.0f);
|
||||
Vector3 pos = transform.GetGlobalPosition();
|
||||
pos.y *= -1.0f;
|
||||
pos.x *= -1.0f;
|
||||
pos.z *= -1.0f;
|
||||
spotLightTransform = glm::translate(spotLightTransform, pos);
|
||||
|
||||
Vector3 direction = transform.GetGlobalRotation() * Vector3(0, 0, 1);
|
||||
auto lookatAt = lookAt(Vector3(), direction, Vector3(0, 1, 0));
|
||||
Quat offset = QuatFromEuler(0, -90.0f, 0);
|
||||
Quat offset2 = QuatFromEuler(180.0f, 0.0f, 0);
|
||||
|
||||
const Quat& globalRotation = glm::normalize(transform.GetGlobalRotation());
|
||||
const Matrix4& rotationMatrix = glm::mat4_cast(globalRotation);
|
||||
|
||||
deferredShader->SetUniformMat4f(uniformAccessor + "Transform", light.GetProjection() * lookatAt * spotLightTransform);
|
||||
|
||||
if (ImGui::Begin("DebugShadowMap"))
|
||||
{
|
||||
|
||||
@@ -496,6 +496,8 @@ namespace Nuake
|
||||
auto meshView = scene.m_Registry.view<TransformComponent, ModelComponent, VisibilityComponent>();
|
||||
auto quakeView = scene.m_Registry.view<TransformComponent, BSPBrushComponent, VisibilityComponent>();
|
||||
auto view = scene.m_Registry.view<TransformComponent, LightComponent, VisibilityComponent>();
|
||||
LightComponent lightDebug;
|
||||
|
||||
for (auto l : view)
|
||||
{
|
||||
auto [lightTransform, light, visibility] = view.get<TransformComponent, LightComponent, VisibilityComponent>(l);
|
||||
@@ -586,13 +588,27 @@ namespace Nuake
|
||||
}
|
||||
else if (light.Type == LightType::Spot)
|
||||
{
|
||||
glCullFace(GL_FRONT);
|
||||
RenderCommand::Disable(RendererEnum::FACE_CULL);
|
||||
|
||||
light.m_Framebuffers[0]->Bind();
|
||||
light.m_Framebuffers[0]->Clear();
|
||||
{
|
||||
Matrix4 spotLightTransform = lightTransform.GetGlobalTransform();
|
||||
spotLightTransform = glm::rotate(spotLightTransform, glm::radians(180.0f), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
shader->SetUniformMat4f("u_LightTransform", light.GetProjection() * spotLightTransform);
|
||||
Matrix4 spotLightTransform = Matrix4(1.0f);
|
||||
Vector3 pos = lightTransform.GetGlobalPosition();
|
||||
pos.y *= -1.0f;
|
||||
pos.x *= -1.0f;
|
||||
pos.z *= -1.0f;
|
||||
spotLightTransform = glm::translate(spotLightTransform, pos);
|
||||
|
||||
Vector3 direction = lightTransform.GetGlobalRotation() * Vector3(0, 0, 1);
|
||||
auto lookatAt = lookAt(Vector3(), direction, Vector3(0, 1, 0));
|
||||
Quat offset = QuatFromEuler(0, -90.0f, 0);
|
||||
Quat offset2 = QuatFromEuler(180.0f, 0.0f, 0);
|
||||
|
||||
const Quat& globalRotation = glm::normalize(lightTransform.GetGlobalRotation());
|
||||
const Matrix4& rotationMatrix = glm::mat4_cast(globalRotation);
|
||||
|
||||
shader->SetUniformMat4f("u_LightTransform", light.GetProjection() * lookatAt * spotLightTransform);
|
||||
for (auto e : meshView)
|
||||
{
|
||||
auto [transform, mesh, visibility] = meshView.get<TransformComponent, ModelComponent, VisibilityComponent>(e);
|
||||
@@ -661,6 +677,11 @@ namespace Nuake
|
||||
|
||||
Renderer::Flush(shader, true);
|
||||
}
|
||||
|
||||
|
||||
lightDebug = light;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -700,6 +721,30 @@ namespace Nuake
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lightDebug.m_Framebuffers[0])
|
||||
{
|
||||
mDisplayDepthBuffer->QueueResize(lightDebug.m_Framebuffers[0]->GetTexture(GL_DEPTH_ATTACHMENT)->GetSize());
|
||||
|
||||
mDisplayDepthBuffer->Bind();
|
||||
mDisplayDepthBuffer->Clear();
|
||||
Shader* displayDepthShader = ShaderManager::GetShader("Resources/Shaders/display_depth.shader");
|
||||
displayDepthShader->Bind();
|
||||
|
||||
lightDebug.m_Framebuffers[0]->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(5);
|
||||
displayDepthShader->SetUniform1i("u_Source", 5);
|
||||
|
||||
RenderCommand::Disable(RendererEnum::DEPTH_TEST);
|
||||
Renderer::DrawQuad(Matrix4(1.0f));
|
||||
RenderCommand::Enable(RendererEnum::DEPTH_TEST);
|
||||
mDisplayDepthBuffer->Unbind();
|
||||
|
||||
ImGui::SetNextWindowSize({ 800, 800 });
|
||||
ImGui::Begin("Debug ShadowMap");
|
||||
ImGui::Image((void*)mDisplayDepthBuffer->GetTexture()->GetID(), ImGui::GetContentRegionAvail(), { 0, 1 }, { 1, 0 });
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SceneRenderer::GBufferPass(Scene& scene)
|
||||
@@ -791,6 +836,7 @@ namespace Nuake
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
finalQuadTransform = glm::inverse(mView);
|
||||
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ namespace Nuake
|
||||
LoadEmbeddedShader(Resources_Shaders_volumetric_shader);
|
||||
LoadEmbeddedShader(Resources_Shaders_debugLine_shader);
|
||||
LoadEmbeddedShader(Resources_Shaders_add_shader);
|
||||
LoadEmbeddedShader(Resources_Shaders_display_depth_shader);
|
||||
}
|
||||
|
||||
Shader* ShaderManager::GetShader(const std::string& path)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -117,6 +117,9 @@ extern unsigned char Resources_Images_speaker_png[];
|
||||
extern const std::string Resources_Images_wrench_png_path;
|
||||
extern unsigned int Resources_Images_wrench_png_len;
|
||||
extern unsigned char Resources_Images_wrench_png[];
|
||||
extern const std::string Resources_resources_aps_path;
|
||||
extern unsigned int Resources_resources_aps_len;
|
||||
extern unsigned char Resources_resources_aps[];
|
||||
extern const std::string Resources_resources_rc_path;
|
||||
extern unsigned int Resources_resources_rc_len;
|
||||
extern unsigned char Resources_resources_rc[];
|
||||
@@ -174,6 +177,9 @@ extern unsigned char Resources_Shaders_deferred_shader[];
|
||||
extern const std::string Resources_Shaders_depth_aware_blur_shader_path;
|
||||
extern unsigned int Resources_Shaders_depth_aware_blur_shader_len;
|
||||
extern unsigned char Resources_Shaders_depth_aware_blur_shader[];
|
||||
extern const std::string Resources_Shaders_display_depth_shader_path;
|
||||
extern unsigned int Resources_Shaders_display_depth_shader_len;
|
||||
extern unsigned char Resources_Shaders_display_depth_shader[];
|
||||
extern const std::string Resources_Shaders_dither_shader_path;
|
||||
extern unsigned int Resources_Shaders_dither_shader_len;
|
||||
extern unsigned char Resources_Shaders_dither_shader[];
|
||||
|
||||
@@ -49,8 +49,7 @@ namespace Nuake
|
||||
}
|
||||
else if(Type == LightType::Spot)
|
||||
{
|
||||
return glm::perspective(glm::radians(90.0f), 1.0f, 0.01f, 1.5f);
|
||||
return glm::ortho(-25.0f, 25.0f, -25.0f, 25.0f, -25.0f, 25.0f);
|
||||
return glm::perspectiveFov(glm::radians(OuterCutoff * 2.0f), 1.0f, 1.0f, 0.01f, 100.5f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -239,11 +239,10 @@ float ShadowCalculationSpot(vec3 FragPos, vec3 normal, Light light)
|
||||
float currentDepth = projCoords.z;
|
||||
// check whether current frag pos is in shadow
|
||||
float shadow = 0.0;
|
||||
float bias = max(0.00005 * (1.0 - dot(normal, -light.Direction)), 0.00005);
|
||||
float bias = max(0.0005 * (1.0 - dot(normal, light.Direction)), 0.0005);
|
||||
//float pcfDepth = texture(ShadowMaps[shadowmap], vec3(projCoords.xy, currentDepth), bias);
|
||||
|
||||
return SampleShadowMap(SpotShadowMaps[light.ShadowMapID], projCoords.xy, currentDepth);
|
||||
return texture(SpotShadowMaps[light.ShadowMapID], projCoords.xy).r;
|
||||
return SampleShadowMap(SpotShadowMaps[light.ShadowMapID], projCoords.xy, currentDepth - bias);
|
||||
}
|
||||
|
||||
void main()
|
||||
@@ -310,7 +309,7 @@ void main()
|
||||
|
||||
if(u_DirectionalLight.Shadow > 0.1f)
|
||||
{
|
||||
shadow += ShadowCalculation(worldPos, N);
|
||||
shadow = ShadowCalculation(worldPos, N);
|
||||
}
|
||||
|
||||
vec3 radiance = u_DirectionalLight.Color * attenuation * shadow;
|
||||
@@ -334,6 +333,8 @@ void main()
|
||||
Lo += (kD * albedo / PI + specular) * radiance * NdotL;
|
||||
}
|
||||
|
||||
shadow = 0.0f;
|
||||
|
||||
for (int i = 0; i < LightCount; i++)
|
||||
{
|
||||
Light light = Lights[i];
|
||||
@@ -375,7 +376,7 @@ void main()
|
||||
|
||||
// scale light by NdotL
|
||||
float NdotL = max(dot(N, L), 0.0);
|
||||
Lo += (kD * albedo / PI + specular) * radiance * NdotL;// note that we already multiplied the BRDF by the Fresnel (kS) so we won't multiply by kS again
|
||||
Lo += (kD * albedo / PI + specular) * radiance * NdotL * shadow;// note that we already multiplied the BRDF by the Fresnel (kS) so we won't multiply by kS again
|
||||
}
|
||||
|
||||
/// ambient lighting (we now use IBL as the ambient term)
|
||||
|
||||
@@ -17,11 +17,11 @@ void main()
|
||||
|
||||
uniform sampler2D u_Source;
|
||||
|
||||
float u_NearPlane = 0.1f;
|
||||
float u_NearPlane = 0.01f;
|
||||
float u_FarPlane = 25.5f;
|
||||
in vec2 UV;
|
||||
|
||||
out float3 FragColor;
|
||||
out vec4 FragColor;
|
||||
|
||||
float LinearizeDepth(float depth)
|
||||
{
|
||||
@@ -34,5 +34,5 @@ void main()
|
||||
float depthValue = texture(u_Source, UV).r;
|
||||
float linearDepth = LinearizeDepth(depthValue) / u_FarPlane; // Normalize to [0, 1] range
|
||||
vec3 color = vec3(linearDepth);
|
||||
gl_FragColor = vec4(color, 1.0);
|
||||
FragColor = vec4(color, 1.0);
|
||||
}
|
||||
Reference in New Issue
Block a user