Browse Source

Reverted back to 4 sample shadow mapping on OpenGL ES, but limited directional light cascades to 2.

Lasse Öörni 13 years ago
parent
commit
d18baaff87

+ 22 - 10
Bin/CoreData/Shaders/GLSL/Lighting.frag

@@ -63,12 +63,14 @@ float GetShadow(vec4 shadowPos)
     #else
         vec3 projShadowPos = shadowPos.xyz / shadowPos.w;
         #ifndef LQSHADOW
-            // Take two samples and average them
-            vec2 inLight = vec2(
+            // Take four samples and average them
+            vec4 inLight = vec4(
                 texture2D(sShadowMap, projShadowPos.xy).r > projShadowPos.z,
-                texture2D(sShadowMap, vec2(projShadowPos.x + cShadowMapInvSize.x, projShadowPos.y)).r > projShadowPos.z
+                texture2D(sShadowMap, vec2(projShadowPos.x + cShadowMapInvSize.x, projShadowPos.y)).r > projShadowPos.z,
+                texture2D(sShadowMap, vec2(projShadowPos.x, projShadowPos.y + cShadowMapInvSize.y)).r > projShadowPos.z,
+                texture2D(sShadowMap, projShadowPos.xy + cShadowMapInvSize).r > projShadowPos.z
             );
-            return dot(inLight, vec2(0.5));
+            return dot(inLight, vec4(0.25));
         #else
             // Take one sample
             return texture2D(sShadowMap, projShadowPos.xy).r > projShadowPos.z ? 1.0 : 0.0;
@@ -100,21 +102,22 @@ float GetPointShadow(vec3 lightVec)
 
 #ifdef DIRLIGHT
 float GetDirShadow(vec4 shadowPos, float depth)
-{
-    return min(GetShadow(shadowPos) + clamp((depth - cShadowDepthFade.z) * cShadowDepthFade.w, 0.0, 1.0), 1.0);
+{
+    return min(GetShadow(shadowPos) + max((depth - cShadowDepthFade.z) * cShadowDepthFade.w, 0.0), 1.0);
 }
-
+
+#ifndef GL_ES
 vec4 GetDirShadowPos(const vec4 shadowPos[4], float depth)
-{
+{
     if (depth < cShadowSplits.x)
-        return shadowPos[0];
+        return shadowPos[0];   
     else if (depth < cShadowSplits.y)
         return shadowPos[1];
     else if (depth < cShadowSplits.z)
         return shadowPos[2];
     else
         return shadowPos[3];
-}
+}
 
 vec4 GetDirShadowPosDeferred(const mat4 shadowMatrix[4], vec4 projWorldPos, float depth)
 {
@@ -127,6 +130,15 @@ vec4 GetDirShadowPosDeferred(const mat4 shadowMatrix[4], vec4 projWorldPos, floa
     else
         return shadowMatrix[3] * projWorldPos;
 }
+#else
+vec4 GetDirShadowPos(const vec4 shadowPos[2], float depth)
+{
+    if (depth < cShadowSplits.x)
+        return shadowPos[0];   
+    else
+        return shadowPos[1];
+}
+#endif
 #endif
 #endif
 

+ 4 - 2
Bin/CoreData/Shaders/GLSL/LitSolid.frag

@@ -13,8 +13,10 @@ varying vec2 vTexCoord;
         varying vec3 vNormal;
     #endif
     #ifdef SHADOW
-        #if defined(DIRLIGHT)
-            varying vec4 vShadowPos[4];
+        #if defined(DIRLIGHT) && !defined(GL_ES)
+	    varying vec4 vShadowPos[4];
+        #elif defined(DIRLIGHT) && defined(GL_ES)
+	    varying vec4 vShadowPos[2];
         #elif defined(SPOTLIGHT)
             varying vec4 vShadowPos;
         #else

+ 9 - 5
Bin/CoreData/Shaders/GLSL/LitSolid.vert

@@ -13,8 +13,10 @@ varying vec2 vTexCoord;
         varying vec3 vNormal;
     #endif
     #ifdef SHADOW
-        #if defined(DIRLIGHT)
-            varying vec4 vShadowPos[4];
+        #if defined(DIRLIGHT) && !defined(GL_ES)
+	    varying vec4 vShadowPos[4];
+        #elif defined(DIRLIGHT) && defined(GL_ES)
+	    varying vec4 vShadowPos[2];
         #elif defined(SPOTLIGHT)
             varying vec4 vShadowPos;
         #else
@@ -65,9 +67,11 @@ void main()
             // Shadow projection: transform from world space to shadow space
             #if defined(DIRLIGHT)
                 vShadowPos[0] = cLightMatrices[0] * projWorldPos;
-                vShadowPos[1] = cLightMatrices[1] * projWorldPos;
-                vShadowPos[2] = cLightMatrices[2] * projWorldPos;
-                vShadowPos[3] = cLightMatrices[3] * projWorldPos;
+                vShadowPos[1] = cLightMatrices[1] * projWorldPos;
+                #ifndef GL_ES
+                    vShadowPos[2] = cLightMatrices[2] * projWorldPos;
+                    vShadowPos[3] = cLightMatrices[3] * projWorldPos;
+                #endif
             #elif defined(SPOTLIGHT)
                 vShadowPos = cLightMatrices[1] * projWorldPos;
             #else

+ 1 - 1
Bin/CoreData/Shaders/GLSL/Samplers.frag

@@ -17,7 +17,7 @@ uniform sampler2DShadow sShadowMap;
 uniform samplerCube sFaceSelectCubeMap;
 uniform samplerCube sIndirectionCubeMap;
 #else
-uniform mediump sampler2D sShadowMap;
+uniform sampler2D sShadowMap;
 #endif
 
 vec3 DecodeNormal(vec4 normalInput)

+ 1 - 1
Bin/CoreData/Shaders/GLSL/Uniforms.frag

@@ -1,5 +1,5 @@
 #ifdef GL_ES
-precision mediump float;
+    precision mediump float;
 #endif
 
 uniform vec3 cAmbientColor;

+ 6 - 2
Bin/CoreData/Shaders/GLSL/Uniforms.vert

@@ -13,7 +13,11 @@ uniform vec4 cUOffset;
 uniform vec4 cVOffset;
 uniform vec3 cViewRightVector;
 uniform vec3 cViewUpVector;
-uniform mat4 cZone;
-uniform mat4 cLightMatrices[4];
+uniform mat4 cZone;
+#ifndef GL_ES
+    uniform mat4 cLightMatrices[4];
+#else
+    uniform mat4 cLightMatrices[2];
+#endif
 uniform vec4 cSkinMatrices[64*3];
 uniform vec4 cVertexLights[4*3];

+ 1 - 1
Docs/Reference.dox

@@ -548,7 +548,7 @@ OpenGL ES 2.0 has further limitations:
 
 - To reduce fillrate, the stencil buffer is not reserved and the stencil test is not available. As a consequence, the light stencil masking optimization is not used.
 
-- For improved performance, shadow quality is reduced: there is no smooth PCF filtering, maximum 2 shadow map samples are used in high quality mode, and shadow intensity is not configurable but always maximum.
+- For improved performance, shadow mapping quality is reduced: there is no smooth PCF filtering, directional lights can have a maximum of 2 cascades, and shadow intensity is always at maximum.
 
 \page Materials Materials
 

+ 1 - 8
Engine/Graphics/Batch.cpp

@@ -130,10 +130,7 @@ void CalculateShadowMatrix(Matrix4& dest, LightBatchQueue* queue, unsigned split
     if (renderer->GetShadowQuality() & SHADOWQUALITY_HIGH_16BIT)
     {
         offset.x_ -= 0.5f / width;
-        // Use only 2 samples offset in X direction on OpenGL ES for better performance
-        #ifndef GL_ES_VERSION_2_0
         offset.y_ -= 0.5f / height;
-        #endif
     }
     texAdjust.SetTranslation(Vector3(offset.x_, offset.y_, 0.5f));
     texAdjust.SetScale(Vector3(scale.x_, scale.y_, 0.5f));
@@ -562,12 +559,8 @@ void Batch::Prepare(Graphics* graphics, Renderer* renderer, bool setModelTransfo
                 if (fadeStart > 0.0f && fadeEnd > 0.0f && fadeEnd > fadeStart)
                     intensity = Lerp(intensity, 1.0f, Clamp((light->GetDistance() - fadeStart) / (fadeEnd - fadeStart), 0.0f, 1.0f));
                 float pcfValues = (1.0f - intensity);
-                // Use only 2 samples offset in X direction on OpenGL ES for better performance
-                #ifndef GL_ES_VERSION_2_0
                 float samples = renderer->GetShadowQuality() >= SHADOWQUALITY_HIGH_16BIT ? 4.0f : 1.0f;
-                #else
-                float samples = renderer->GetShadowQuality() >= SHADOWQUALITY_HIGH_16BIT ? 2.0f : 1.0f;
-                #endif
+
                 graphics->SetShaderParameter(PSP_SHADOWINTENSITY, Vector4(pcfValues / samples, intensity, 0.0f, 0.0f));
             }
             

+ 4 - 0
Engine/Graphics/Light.h

@@ -44,7 +44,11 @@ enum LightType
 static const float SHADOW_MIN_QUANTIZE = 0.1f;
 static const float SHADOW_MIN_VIEW = 1.0f;
 static const int MAX_LIGHT_SPLITS = 6;
+#if !defined(ANDROID) && !defined(IOS)
 static const int MAX_CASCADE_SPLITS = 4;
+#else
+static const int MAX_CASCADE_SPLITS = 2;
+#endif
 
 /// Shadow depth bias parameters.
 struct BiasParameters

+ 1 - 1
Engine/Graphics/Renderer.cpp

@@ -874,8 +874,8 @@ Texture2D* Renderer::GetShadowMap(Light* light, Camera* camera, unsigned viewWid
         {
             #ifndef GL_ES_VERSION_2_0
             newShadowMap->SetFilterMode(FILTER_BILINEAR);
-            #endif
             newShadowMap->SetShadowCompare(true);
+            #endif
             break;
         }
     }