shadow refactor, optimization
This commit is contained in:
@@ -112,6 +112,10 @@ struct ShaderEntity
|
||||
inline float GetWidth() { return texMulAdd.y; }
|
||||
inline float GetHeight() { return texMulAdd.z; }
|
||||
|
||||
// Load cubemap depth remap props:
|
||||
inline float GetCubemapDepthRemapNear() { return texMulAdd.w; }
|
||||
inline float GetCubemapDepthRemapFar() { return coneAngleCos; }
|
||||
|
||||
// Load decal props:
|
||||
inline float GetEmissive() { return energy; }
|
||||
};
|
||||
|
||||
@@ -45,9 +45,9 @@ inline LightingPart CombineLighting(in Surface surface, in Lighting lighting)
|
||||
|
||||
|
||||
|
||||
inline float3 shadowCascade(float3 shadowPos, float2 ShTex, float shadowKernel, float bias, float slice)
|
||||
inline float3 shadowCascade(in ShaderEntity light, in float3 shadowPos, in float2 shadowUV, in uint cascade)
|
||||
{
|
||||
const float realDistance = shadowPos.z + bias;
|
||||
const float realDistance = shadowPos.z + light.shadowBias;
|
||||
float3 shadow = 0;
|
||||
#ifndef DISABLE_SHADOWMAPS
|
||||
#ifndef DISABLE_SOFT_SHADOWS
|
||||
@@ -58,13 +58,13 @@ inline float3 shadowCascade(float3 shadowPos, float2 ShTex, float shadowKernel,
|
||||
[loop]
|
||||
for (float x = -range; x <= range; x += 1.0f)
|
||||
{
|
||||
shadow.x += texture_shadowarray_2d.SampleCmpLevelZero(sampler_cmp_depth, float3(ShTex + float2(x, y) * shadowKernel, slice), realDistance).r;
|
||||
shadow.x += texture_shadowarray_2d.SampleCmpLevelZero(sampler_cmp_depth, float3(shadowUV + float2(x, y) * light.shadowKernel, light.GetShadowMapIndex() + cascade), realDistance).r;
|
||||
shadow.y++;
|
||||
}
|
||||
}
|
||||
shadow = shadow.x / shadow.y;
|
||||
#else
|
||||
shadow = texture_shadowarray_2d.SampleCmpLevelZero(sampler_cmp_depth, float3(ShTex, slice), realDistance).r;
|
||||
shadow = texture_shadowarray_2d.SampleCmpLevelZero(sampler_cmp_depth, float3(shadowUV, light.GetShadowMapIndex() + cascade), realDistance).r;
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_TRANSPARENT_SHADOWMAP
|
||||
@@ -73,7 +73,7 @@ inline float3 shadowCascade(float3 shadowPos, float2 ShTex, float shadowKernel,
|
||||
// unfortunately transparents will not receive transparent shadow map
|
||||
// because we cannot distinguish without using secondary depth buffer for transparents
|
||||
// but I don't wanna do that, not overly important for now
|
||||
float4 transparent_shadowmap = texture_shadowarray_transparent.SampleLevel(sampler_linear_clamp, float3(ShTex, slice), 0).rgba;
|
||||
float4 transparent_shadowmap = texture_shadowarray_transparent.SampleLevel(sampler_linear_clamp, float3(shadowUV, light.GetShadowMapIndex() + cascade), 0).rgba;
|
||||
// Tint the shadow:
|
||||
shadow *= transparent_shadowmap.rgb;
|
||||
// Reduce shadow by caustics (caustics can also increase total light above maximum):
|
||||
@@ -87,17 +87,10 @@ inline float3 shadowCascade(float3 shadowPos, float2 ShTex, float shadowKernel,
|
||||
return shadow;
|
||||
}
|
||||
|
||||
inline float shadowCube(float3 Lunnormalized, float range, float bias, uint slice)
|
||||
inline float shadowCube(in ShaderEntity light, float3 Lunnormalized)
|
||||
{
|
||||
float projectedDistance = max(max(abs(Lunnormalized.x), abs(Lunnormalized.y)), abs(Lunnormalized.z));
|
||||
float FarZ = 0.1f; // watch out: reversed depth buffer! Also, light near plane is constant for simplicity, this should match on cpu side!
|
||||
float NearZ = max(1, range); // watch out: reversed depth buffer!
|
||||
float fRange = FarZ / (FarZ - NearZ);
|
||||
float a = fRange;
|
||||
float b = -fRange * NearZ;
|
||||
float z = projectedDistance * a + b;
|
||||
float dbDistance = z / projectedDistance;
|
||||
return texture_shadowarray_cube.SampleCmpLevelZero(sampler_cmp_depth, float4(-Lunnormalized, slice), dbDistance + bias).r;
|
||||
const float remappedDistance = light.GetCubemapDepthRemapNear() + light.GetCubemapDepthRemapFar() / max(max(abs(Lunnormalized.x), abs(Lunnormalized.y)), abs(Lunnormalized.z));
|
||||
return texture_shadowarray_cube.SampleCmpLevelZero(sampler_cmp_depth, float4(-Lunnormalized, light.GetShadowMapIndex()), remappedDistance + light.shadowBias).r;
|
||||
}
|
||||
|
||||
|
||||
@@ -127,7 +120,7 @@ inline void DirectionalLight(in ShaderEntity light, in Surface surface, inout Li
|
||||
[branch]
|
||||
if (is_saturated(ShTex))
|
||||
{
|
||||
const float3 shadow_main = shadowCascade(ShPos, ShTex.xy, light.shadowKernel, light.shadowBias, light.GetShadowMapIndex() + cascade);
|
||||
const float3 shadow_main = shadowCascade(light, ShPos, ShTex.xy, cascade);
|
||||
const float3 cascade_edgefactor = saturate(saturate(abs(ShPos)) - 0.8f) * 5.0f; // fade will be on edge and inwards 20%
|
||||
const float cascade_fade = max(cascade_edgefactor.x, max(cascade_edgefactor.y, cascade_edgefactor.z));
|
||||
|
||||
@@ -139,7 +132,7 @@ inline void DirectionalLight(in ShaderEntity light, in Surface surface, inout Li
|
||||
cascade += 1;
|
||||
ShPos = mul(MatrixArray[light.GetShadowMatrixIndex() + cascade], float4(surface.P, 1)).xyz;
|
||||
ShTex = ShPos * float3(0.5f, -0.5f, 0.5f) + 0.5f;
|
||||
const float3 shadow_fallback = shadowCascade(ShPos, ShTex.xy, light.shadowKernel, light.shadowBias, light.GetShadowMapIndex() + cascade);
|
||||
const float3 shadow_fallback = shadowCascade(light, ShPos, ShTex.xy, cascade);
|
||||
|
||||
sh *= lerp(shadow_main, shadow_fallback, cascade_fade);
|
||||
}
|
||||
@@ -186,7 +179,7 @@ inline void PointLight(in ShaderEntity light, in Surface surface, inout Lighting
|
||||
#ifndef DISABLE_SHADOWMAPS
|
||||
[branch]
|
||||
if (light.IsCastingShadow()) {
|
||||
sh *= shadowCube(Lunnormalized, light.range, light.shadowBias, light.GetShadowMapIndex());
|
||||
sh *= shadowCube(light, Lunnormalized);
|
||||
}
|
||||
#endif // DISABLE_SHADOWMAPS
|
||||
|
||||
@@ -240,7 +233,7 @@ inline void SpotLight(in ShaderEntity light, in Surface surface, inout Lighting
|
||||
[branch]
|
||||
if (is_saturated(ShTex))
|
||||
{
|
||||
sh *= shadowCascade(ShPos.xyz, ShTex.xy, light.shadowKernel, light.shadowBias, light.GetShadowMapIndex());
|
||||
sh *= shadowCascade(light, ShPos.xyz, ShTex.xy, 0);
|
||||
}
|
||||
}
|
||||
#endif // DISABLE_SHADOWMAPS
|
||||
@@ -439,7 +432,7 @@ inline void SphereLight(in ShaderEntity light, in Surface surface, inout Lightin
|
||||
#ifndef DISABLE_SHADOWMAPS
|
||||
[branch]
|
||||
if (light.IsCastingShadow()) {
|
||||
fLight = shadowCube(Lunnormalized, light.range, light.shadowBias, light.GetShadowMapIndex());
|
||||
fLight = shadowCube(light, Lunnormalized);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -488,7 +481,7 @@ inline void DiscLight(in ShaderEntity light, in Surface surface, inout Lighting
|
||||
#ifndef DISABLE_SHADOWMAPS
|
||||
[branch]
|
||||
if (light.IsCastingShadow()) {
|
||||
fLight = shadowCube(Lunnormalized, light.range, light.shadowBias, light.GetShadowMapIndex());
|
||||
fLight = shadowCube(light, Lunnormalized);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -544,7 +537,7 @@ inline void RectangleLight(in ShaderEntity light, in Surface surface, inout Ligh
|
||||
#ifndef DISABLE_SHADOWMAPS
|
||||
[branch]
|
||||
if (light.IsCastingShadow()) {
|
||||
fLight = shadowCube(Lunnormalized, light.range, light.shadowBias, light.GetShadowMapIndex());
|
||||
fLight = shadowCube(light, Lunnormalized);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -659,7 +652,7 @@ inline void TubeLight(in ShaderEntity light, in Surface surface, inout Lighting
|
||||
#ifndef DISABLE_SHADOWMAPS
|
||||
[branch]
|
||||
if (light.IsCastingShadow()) {
|
||||
fLight = shadowCube(Lunnormalized, light.range, light.shadowBias, light.GetShadowMapIndex());
|
||||
fLight = shadowCube(light, Lunnormalized);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ void main(PSInput input)
|
||||
|
||||
[branch]if ((saturate(ShTex.x) == ShTex.x) && (saturate(ShTex.y) == ShTex.y) && (saturate(ShTex.z) == ShTex.z))
|
||||
{
|
||||
lightColor *= shadowCascade(ShPos, ShTex.xy, light.shadowKernel, light.shadowBias, light.GetShadowMapIndex() + cascade);
|
||||
lightColor *= shadowCascade(light, ShPos, ShTex.xy, cascade);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ void main(PSInput input)
|
||||
|
||||
[branch]
|
||||
if (light.IsCastingShadow() >= 0) {
|
||||
lightColor *= shadowCube(Lunnormalized, light.range, light.shadowBias, light.GetShadowMapIndex());
|
||||
lightColor *= shadowCube(light, Lunnormalized);
|
||||
}
|
||||
|
||||
lighting.direct.diffuse += lightColor;
|
||||
@@ -166,7 +166,7 @@ void main(PSInput input)
|
||||
[branch]
|
||||
if ((saturate(ShTex.x) == ShTex.x) && (saturate(ShTex.y) == ShTex.y))
|
||||
{
|
||||
lightColor *= shadowCascade(ShPos.xyz, ShTex.xy, light.shadowKernel, light.shadowBias, light.GetShadowMapIndex());
|
||||
lightColor *= shadowCascade(light, ShPos.xyz, ShTex.xy, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ float4 main(VertexToPixel input) : SV_TARGET
|
||||
|
||||
[branch]if (is_saturated(ShTex))
|
||||
{
|
||||
float3 attenuation = shadowCascade(ShPos, ShTex.xy, light.shadowKernel, light.shadowBias, light.GetShadowMapIndex() + cascade);
|
||||
float3 attenuation = shadowCascade(light, ShPos, ShTex.xy, cascade);
|
||||
|
||||
attenuation *= GetFog(cameraDistance - marchedDistance);
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ float4 main(VertexToPixel input) : SV_TARGET
|
||||
|
||||
[branch]
|
||||
if (light.IsCastingShadow()) {
|
||||
attenuation *= shadowCube(Lunnormalized, light.range, light.shadowBias, light.GetShadowMapIndex());
|
||||
attenuation *= shadowCube(light, Lunnormalized);
|
||||
}
|
||||
|
||||
attenuation *= GetFog(cameraDistance - marchedDistance);
|
||||
|
||||
@@ -50,7 +50,7 @@ float4 main(VertexToPixel input) : SV_TARGET
|
||||
[branch]
|
||||
if ((saturate(ShTex.x) == ShTex.x) && (saturate(ShTex.y) == ShTex.y))
|
||||
{
|
||||
attenuation *= shadowCascade(ShPos.xyz, ShTex.xy, light.shadowKernel, light.shadowBias, light.GetShadowMapIndex());
|
||||
attenuation *= shadowCascade(light, ShPos.xyz, ShTex.xy, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3995,6 +3995,25 @@ void UpdateRenderData(CommandList cmd)
|
||||
break;
|
||||
}
|
||||
|
||||
switch (light.GetType())
|
||||
{
|
||||
case LightComponent::POINT:
|
||||
case LightComponent::SPHERE:
|
||||
case LightComponent::DISC:
|
||||
case LightComponent::RECTANGLE:
|
||||
case LightComponent::TUBE:
|
||||
{
|
||||
const float FarZ = 0.1f; // watch out: reversed depth buffer! Also, light near plane is constant for simplicity, this should match on cpu side!
|
||||
const float NearZ = std::max(1.0f, entityArray[entityCounter].range); // watch out: reversed depth buffer!
|
||||
const float fRange = FarZ / (FarZ - NearZ);
|
||||
const float cubemapDepthRemapNear = fRange;
|
||||
const float cubemapDepthRemapFar = -fRange * NearZ;
|
||||
entityArray[entityCounter].texMulAdd.w = cubemapDepthRemapNear;
|
||||
entityArray[entityCounter].coneAngleCos = cubemapDepthRemapFar;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (light.IsStatic())
|
||||
{
|
||||
entityArray[entityCounter].SetFlags(ENTITY_FLAG_LIGHT_STATIC);
|
||||
@@ -5155,7 +5174,7 @@ void DrawShadowmaps(const CameraComponent& camera, CommandList cmd, uint32_t lay
|
||||
if (!renderQueue.empty())
|
||||
{
|
||||
MiscCB miscCb;
|
||||
miscCb.g_xColor = float4(light.position.x, light.position.y, light.position.z, 1.0f / light.GetRange()); // reciprocal range, to avoid division in shader
|
||||
miscCb.g_xColor = float4(light.position.x, light.position.y, light.position.z, 0);
|
||||
device->UpdateBuffer(&constantBuffers[CBTYPE_MISC], &miscCb, cmd);
|
||||
device->BindConstantBuffer(VS, &constantBuffers[CBTYPE_MISC], CB_GETBINDSLOT(MiscCB), cmd);
|
||||
device->BindConstantBuffer(PS, &constantBuffers[CBTYPE_MISC], CB_GETBINDSLOT(MiscCB), cmd);
|
||||
|
||||
@@ -493,15 +493,18 @@ namespace wiScene
|
||||
}
|
||||
}
|
||||
|
||||
if (archive.GetVersion() < 33 &&
|
||||
(GetType() == POINT ||
|
||||
GetType() == SPHERE ||
|
||||
GetType() == DISC ||
|
||||
GetType() == RECTANGLE ||
|
||||
GetType() == TUBE)
|
||||
)
|
||||
if (archive.GetVersion() < 33)
|
||||
{
|
||||
shadowBias = 0.0001f;
|
||||
switch (GetType())
|
||||
{
|
||||
case LightComponent::POINT:
|
||||
case LightComponent::SPHERE:
|
||||
case LightComponent::DISC:
|
||||
case LightComponent::RECTANGLE:
|
||||
case LightComponent::TUBE:
|
||||
shadowBias = 0.0001f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace wiVersion
|
||||
// minor features, major updates
|
||||
const int minor = 36;
|
||||
// minor bug fixes, alterations, refactors, updates
|
||||
const int revision = 9;
|
||||
const int revision = 10;
|
||||
|
||||
|
||||
long GetVersion()
|
||||
|
||||
Reference in New Issue
Block a user