2
0
Эх сурвалжийг харах

Optimized shadow mapping instruction count & performance on non-NVIDIA GPUs.

Lasse Öörni 14 жил өмнө
parent
commit
c880535788

+ 3 - 3
Engine/Graphics/Batch.cpp

@@ -261,9 +261,9 @@ void Batch::Prepare(Graphics* graphics, Renderer* renderer, const HashMap<String
             
             
             if (graphics->NeedParameterUpdate(PSP_SAMPLEOFFSETS, shadowMap))
             if (graphics->NeedParameterUpdate(PSP_SAMPLEOFFSETS, shadowMap))
             {
             {
-                float invWidth = 1.0f / (float)shadowMap->GetWidth();
-                float invHeight = 1.0f / (float)shadowMap->GetHeight();
-                graphics->SetShaderParameter(PSP_SAMPLEOFFSETS, Vector4(0.5f * invWidth, 0.5f * invHeight, 0.0f, 0.0f));
+                float xOffset = 0.5f / (float)shadowMap->GetWidth();
+                float yOffset = 0.5f / (float)shadowMap->GetHeight();
+                graphics->SetShaderParameter(PSP_SAMPLEOFFSETS, Vector4(xOffset, yOffset, xOffset, -yOffset));
             }
             }
             
             
             if (graphics->NeedParameterUpdate(PSP_SHADOWCUBEADJUST, light))
             if (graphics->NeedParameterUpdate(PSP_SHADOWCUBEADJUST, light))

+ 7 - 8
SourceAssets/GLSLShaders/Lighting.frag

@@ -32,19 +32,18 @@ float GetShadow(vec4 shadowPos)
     // Note: in case of sampling a point light cube shadow, we optimize out the w divide as it has already been performed
     // Note: in case of sampling a point light cube shadow, we optimize out the w divide as it has already been performed
     #ifndef LQSHADOW
     #ifndef LQSHADOW
         // Take four samples and average them
         // Take four samples and average them
-        vec4 pcfValues = vec4(cShadowIntensity.y);
         #ifndef POINTLIGHT
         #ifndef POINTLIGHT
-            vec2 offsets = cSampleOffsets * shadowPos.w;
+            float4 offsets = cSampleOffsets * shadowPos.w;
         #else
         #else
-            vec2 offsets = cSampleOffsets;
+            float4 offsets = cSampleOffsets;
         #endif
         #endif
         vec4 inLight = vec4(
         vec4 inLight = vec4(
-            shadow2DProj(sShadowMap, vec4(shadowPos.xy + vec2(offsets.x, offsets.y), shadowPos.zw)).r,
-            shadow2DProj(sShadowMap, vec4(shadowPos.xy + vec2(-offsets.x, offsets.y), shadowPos.zw)).r,
-            shadow2DProj(sShadowMap, vec4(shadowPos.xy + vec2(offsets.x, -offsets.y), shadowPos.zw)).r,
-            shadow2DProj(sShadowMap, vec4(shadowPos.xy + vec2(-offsets.x, -offsets.y), shadowPos.zw)).r
+            shadow2DProj(sShadowMap, vec4(shadowPos.xy + offsets.xy, shadowPos.zw)).r,
+            shadow2DProj(sShadowMap, vec4(shadowPos.xy + offsets.zw, shadowPos.zw)).r,
+            shadow2DProj(sShadowMap, vec4(shadowPos.xy - offsets.xy, shadowPos.zw)).r,
+            shadow2DProj(sShadowMap, vec4(shadowPos.xy - offsets.zw, shadowPos.zw)).r
         );
         );
-        return cShadowIntensity.z + dot(inLight, pcfValues);
+        return cShadowIntensity.z + dot(inLight, vec4(cShadowIntensity.y));
     #else
     #else
         // Take one sample
         // Take one sample
         float inLight = shadow2DProj(sShadowMap, shadowPos).r;
         float inLight = shadow2DProj(sShadowMap, shadowPos).r;

+ 1 - 1
SourceAssets/GLSLShaders/Uniforms.frag

@@ -5,7 +5,7 @@ uniform vec4 cLightColor;
 uniform vec4 cMatDiffColor;
 uniform vec4 cMatDiffColor;
 uniform vec3 cMatEmissiveColor;
 uniform vec3 cMatEmissiveColor;
 uniform vec2 cMatSpecProperties;
 uniform vec2 cMatSpecProperties;
-uniform vec2 cSampleOffsets;
+uniform vec4 cSampleOffsets;
 uniform vec4 cShadowCubeAdjust;
 uniform vec4 cShadowCubeAdjust;
 uniform vec2 cShadowCubeProj;
 uniform vec2 cShadowCubeProj;
 uniform vec4 cShadowIntensity;
 uniform vec4 cShadowIntensity;

+ 21 - 56
SourceAssets/HLSLShaders/Lighting.hlsl

@@ -31,74 +31,39 @@ float GetSpecular(float3 normal, float3 eyeVec, float3 lightDir, float specularP
 
 
 float GetShadow(float4 shadowPos)
 float GetShadow(float4 shadowPos)
 {
 {
-    // Note: in case of sampling a point light cube shadow, we optimize out the w divide as it has already been performed
     #ifndef FALLBACK
     #ifndef FALLBACK
         #ifndef LQSHADOW
         #ifndef LQSHADOW
             // Take four samples and average them
             // Take four samples and average them
-            float4 pcfValues = cShadowIntensity.y;
-            #ifdef SM3
-                #ifndef POINTLIGHT
-                    float4 projShadowPos = float4(shadowPos.xyz / shadowPos.w, 0.0);
-                #else
-                    float4 projShadowPos = float4(shadowPos.xyz, 0.0);
-                #endif
-                float4 inLight = float4(
-                    tex2Dlod(sShadowMap, float4(projShadowPos.xy + float2(cSampleOffsets.x, cSampleOffsets.y), projShadowPos.zw)).r,
-                    tex2Dlod(sShadowMap, float4(projShadowPos.xy + float2(-cSampleOffsets.x, cSampleOffsets.y), projShadowPos.zw)).r,
-                    tex2Dlod(sShadowMap, float4(projShadowPos.xy + float2(cSampleOffsets.x, -cSampleOffsets.y), projShadowPos.zw)).r,
-                    tex2Dlod(sShadowMap, float4(projShadowPos.xy + float2(-cSampleOffsets.x, -cSampleOffsets.y), projShadowPos.zw)).r
-                );
-                #ifdef HWSHADOW
-                    return cShadowIntensity.z + dot(inLight, pcfValues);
-                #else
-                    return cShadowIntensity.z + dot(inLight > projShadowPos.z, pcfValues);
-                #endif
+            #ifndef POINTLIGHT
+                float4 offsets = cSampleOffsets * shadowPos.w;
+            #else
+                float4 offsets = cSampleOffsets;
+            #endif
+            float4 inLight = float4(
+                tex2Dproj(sShadowMap, float4(shadowPos.xy + offsets.xy, shadowPos.zw)).r,
+                tex2Dproj(sShadowMap, float4(shadowPos.xy + offsets.zw, shadowPos.zw)).r,
+                tex2Dproj(sShadowMap, float4(shadowPos.xy - offsets.xy, shadowPos.zw)).r,
+                tex2Dproj(sShadowMap, float4(shadowPos.xy - offsets.zw, shadowPos.zw)).r
+            );
+            #ifdef HWSHADOW
+                return cShadowIntensity.z + dot(inLight, cShadowIntensity.y);
             #else
             #else
                 #ifndef POINTLIGHT
                 #ifndef POINTLIGHT
-                    float2 offsets = cSampleOffsets * shadowPos.w;
+                    return cShadowIntensity.z + dot(inLight * shadowPos.w > shadowPos.z, cShadowIntensity.y);
                 #else
                 #else
-                    float2 offsets = cSampleOffsets;
-                #endif
-                float4 inLight = float4(
-                    tex2Dproj(sShadowMap, float4(shadowPos.xy + float2(offsets.x, offsets.y), shadowPos.zw)).r,
-                    tex2Dproj(sShadowMap, float4(shadowPos.xy + float2(-offsets.x, offsets.y), shadowPos.zw)).r,
-                    tex2Dproj(sShadowMap, float4(shadowPos.xy + float2(offsets.x, -offsets.y), shadowPos.zw)).r,
-                    tex2Dproj(sShadowMap, float4(shadowPos.xy + float2(-offsets.x, -offsets.y), shadowPos.zw)).r
-                );
-                #ifdef HWSHADOW
-                    return cShadowIntensity.z + dot(inLight, pcfValues);
-                #else
-                    #ifndef POINTLIGHT
-                        return cShadowIntensity.z + dot(inLight * shadowPos.w > shadowPos.z, pcfValues);
-                    #else
-                        return cShadowIntensity.z + dot(inLight > shadowPos.z, pcfValues);
-                    #endif
+                    return cShadowIntensity.z + dot(inLight > shadowPos.z, cShadowIntensity.y);
                 #endif
                 #endif
             #endif
             #endif
         #else
         #else
             // Take one sample
             // Take one sample
-            #ifdef SM3
-                #ifndef POINTLIGHT
-                    float4 projShadowPos = float4(shadowPos.xyz / shadowPos.w, 0.0);
-                #else
-                    float4 projShadowPos = float4(shadowPos.xyz, 0.0);
-                #endif
-                float inLight = tex2Dlod(sShadowMap, float4(projShadowPos)).r;
-                #ifdef HWSHADOW
-                    return cShadowIntensity.z + cShadowIntensity.x * inLight;
-                #else
-                    return cShadowIntensity.z + cShadowIntensity.x * (inLight > projShadowPos.z);
-                #endif
+            float inLight = tex2Dproj(sShadowMap, shadowPos).r;
+            #ifdef HWSHADOW
+                return cShadowIntensity.z + cShadowIntensity.x * inLight;
             #else
             #else
-                float inLight = tex2Dproj(sShadowMap, shadowPos).r;
-                #ifdef HWSHADOW
-                    return cShadowIntensity.z + cShadowIntensity.x * inLight;
+                #ifndef POINTLIGHT
+                    return cShadowIntensity.z + cShadowIntensity.x * (inLight * shadowPos.w > shadowPos.z);
                 #else
                 #else
-                    #ifndef POINTLIGHT
-                        return cShadowIntensity.z + cShadowIntensity.x * (inLight * shadowPos.w > shadowPos.z);
-                    #else
-                        return cShadowIntensity.z + cShadowIntensity.x * (inLight > shadowPos.z);
-                    #endif
+                    return cShadowIntensity.z + cShadowIntensity.x * (inLight > shadowPos.z);
                 #endif
                 #endif
             #endif
             #endif
         #endif
         #endif

+ 1 - 1
SourceAssets/HLSLShaders/Uniforms.hlsl

@@ -24,7 +24,7 @@ uniform float4 cLightColor : register(C3);
 uniform float4 cMatDiffColor : register(C4);
 uniform float4 cMatDiffColor : register(C4);
 uniform float3 cMatEmissiveColor : register(C5);
 uniform float3 cMatEmissiveColor : register(C5);
 uniform float2 cMatSpecProperties : register(C6);
 uniform float2 cMatSpecProperties : register(C6);
-uniform float2 cSampleOffsets : register(C7);
+uniform float4 cSampleOffsets : register(C7);
 uniform float4 cShadowCubeAdjust : register(C8);
 uniform float4 cShadowCubeAdjust : register(C8);
 uniform float2 cShadowCubeProj : register(C9);
 uniform float2 cShadowCubeProj : register(C9);
 uniform float2 cShadowFade : register(C10);
 uniform float2 cShadowFade : register(C10);