Fixed multi spotlight shadows

This commit is contained in:
Antoine Pilote
2024-08-29 23:02:23 -04:00
parent cf7d236540
commit d42c2154cf
6 changed files with 600 additions and 574 deletions

View File

@@ -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);

View File

@@ -258,6 +258,21 @@ namespace Nuake
deferredShader->Bind();
deferredShader->SetUniform1i("LightCount", 0);
for (int i = 0; i < m_Lights.size(); i++)
{
const std::string uniformAccessor = "Lights[" + std::to_string(i) + "].";
deferredShader->SetUniform3f(uniformAccessor + "Position", 0, 0, 0);
deferredShader->SetUniform3f(uniformAccessor + "Color", 0, 0, 0);
deferredShader->SetUniform1i(uniformAccessor + "Type", -1);
deferredShader->SetUniform1i(uniformAccessor + "CastShadow", 0);
deferredShader->SetUniform1i(uniformAccessor + "ShadowMapID", -1);
}
for (int i = 0; i < 8; i++)
{
deferredShader->SetUniform1i("SpotShadowMaps[" + std::to_string(i) + "]", 0);
}
m_Lights.clear();
spotShadowMapCount = 0;
}
@@ -271,7 +286,7 @@ namespace Nuake
deferredShader->Bind();
Vector3 direction = light.GetDirection();
Vector3 pos = transform.GetGlobalPosition();
Vector3 pos = transform.GetGlobalTransform()[3];
Quat lightRotation = transform.GetGlobalRotation();
const int MaxSpotShadowMap = 8;
@@ -318,31 +333,16 @@ namespace Nuake
if (light.Type == Spot)
{
direction = transform.GetGlobalRotation() * Vector3(0, 0, -1);
deferredShader->SetUniform3f(uniformAccessor + "Direction", direction.x, direction.y, direction.z);
deferredShader->SetUniform1f(uniformAccessor + "OuterAngle", glm::cos(Rad(light.OuterCutoff)));
deferredShader->SetUniform1f(uniformAccessor + "InnerAngle", glm::cos(Rad(light.Cutoff)));
if (light.CastShadows && spotShadowMapCount < MaxSpotShadowMap)
{
int shadowMapTextureSlot = 22 + spotShadowMapCount;
deferredShader->SetUniform1f(uniformAccessor + "ShadowMapID", spotShadowMapCount);
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);
int shadowMapTextureSlot = 21 + spotShadowMapCount;
deferredShader->SetUniform1i(uniformAccessor + "ShadowMapID", spotShadowMapCount);
deferredShader->SetUniformMat4f(uniformAccessor + "Transform", light.GetProjection() * glm::inverse(transform.GetGlobalTransform()));
if (ImGui::Begin(("DebugShadowMap" + std::to_string(idx)).c_str()))
{
@@ -355,6 +355,13 @@ namespace Nuake
spotShadowMapCount++;
}
}
else
{
deferredShader->SetUniform3f(uniformAccessor + "Direction", 0, 0, 0);
deferredShader->SetUniform1f(uniformAccessor + "OuterAngle", glm::cos(Rad(light.OuterCutoff)));
deferredShader->SetUniform1f(uniformAccessor + "InnerAngle", glm::cos(Rad(light.Cutoff)));
deferredShader->SetUniform1f(uniformAccessor + "ShadowMapID", -1);
}
deferredShader->SetUniform1i("LightCount", static_cast<int>(idx));
}

View File

@@ -608,7 +608,7 @@ namespace Nuake
const Quat& globalRotation = glm::normalize(lightTransform.GetGlobalRotation());
const Matrix4& rotationMatrix = glm::mat4_cast(globalRotation);
shader->SetUniformMat4f("u_LightTransform", light.GetProjection() * lookatAt * spotLightTransform);
shader->SetUniformMat4f("u_LightTransform", light.GetProjection() * glm::inverse(lightTransform.GetGlobalTransform()));
for (auto e : meshView)
{
auto [transform, mesh, visibility] = meshView.get<TransformComponent, ModelComponent, VisibilityComponent>(e);

File diff suppressed because it is too large Load Diff

View File

@@ -49,7 +49,7 @@ namespace Nuake
}
else if(Type == LightType::Spot)
{
return glm::perspectiveFov(glm::radians(OuterCutoff * 2.0f), 1.0f, 1.0f, 0.01f, 100.5f);
return glm::perspectiveFov(glm::radians(OuterCutoff * 2.5f), 1.0f, 1.0f, 0.001f, 50.5f);
}
}

View File

@@ -155,7 +155,7 @@ int GetCSMDepth(float depth)
float SampleShadowMap(sampler2D shadowMap, vec2 coords, float compare)
{
return step(compare, texture(shadowMap, coords.xy).r);
return compare < texture(shadowMap, coords.xy).r ? 1.0f : 0.0f;
}
float SampleShadowMapLinear(sampler2D shadowMap, vec2 coords, float compare, vec2 texelSize)
@@ -242,7 +242,7 @@ float ShadowCalculationSpot(vec3 FragPos, vec3 normal, Light light)
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 - bias);
return SampleShadowMap(SpotShadowMaps[light.ShadowMapID], projCoords.xy, currentDepth - 0.000005);
}
void main()
@@ -292,7 +292,7 @@ void main()
vec3 Lo = vec3(0.0);
vec3 fog = vec3(0.0);
float shadow = 0.0f;
float shadow = 1.0f;
if (u_DirectionalLight.Shadow < 0.1f)
{
@@ -309,10 +309,10 @@ void main()
if(u_DirectionalLight.Shadow > 0.1f)
{
shadow += ShadowCalculation(worldPos, N);
shadow *= ShadowCalculation(worldPos, N);
}
vec3 radiance = u_DirectionalLight.Color * attenuation * shadow;
vec3 radiance = u_DirectionalLight.Color * attenuation;
vec3 H = normalize(V + L);
float NDF = DistributionGGX(N, H, roughness);
@@ -330,9 +330,10 @@ void main()
// scale light by NdotL
float NdotL = max(dot(N, L), 0.0);
Lo += (kD * albedo / PI + specular) * radiance * NdotL;
Lo += (kD * albedo / PI + specular) * radiance * NdotL * shadow;
}
shadow = 1.0f;
for (int i = 0; i < LightCount; i++)
{
Light light = Lights[i];
@@ -352,9 +353,13 @@ void main()
float epsilon = Lights[i].InnerAngle - Lights[i].OuterAngle;
float intensity = clamp((theta - Lights[i].OuterAngle) / epsilon, 0.0, 1.0);
shadow += ShadowCalculationSpot(worldPos, N, Lights[i]);
float shadow2 = 1.0f;
if(light.CastShadow > 0 && light.ShadowMapID >= 0)
{
shadow2 = ShadowCalculationSpot(worldPos, N, Lights[i]);
}
radiance = Lights[i].Color * intensity * shadow;
radiance = Lights[i].Color * intensity * shadow2;
}
// Cook-Torrance BRDF
@@ -385,7 +390,7 @@ void main()
kD *= 1.0 - metallic;
vec3 ambient = (albedo) * ao * ssao * u_AmbientTerm;
vec3 color = (ambient) + Lo;
vec3 color = (ambient) + Lo ;
// Display CSM splits..
/*float depth = length(worldPos - u_EyePosition);