Graphics/Shadow: Implement PCF for spot lights
Former-commit-id: 0045af26b612a5c41268fcf3e3d03893e01c0448
This commit is contained in:
parent
fabe42dc3a
commit
5cad63c21b
|
|
@ -94,21 +94,30 @@ float VectorToDepthValue(vec3 vec, float zNear, float zFar)
|
||||||
return (normZ + 1.0) * 0.5;
|
return (normZ + 1.0) * 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TestShadowDirectional(int lightIndex)
|
float CalculateDirectionalShadowFactor(int lightIndex)
|
||||||
{
|
{
|
||||||
vec4 lightSpacePos = vLightSpacePos[lightIndex];
|
vec4 lightSpacePos = vLightSpacePos[lightIndex];
|
||||||
return texture(DirectionalSpotLightShadowMap[lightIndex], lightSpacePos.xy).x >= (lightSpacePos.z - 0.0005);
|
return (texture(DirectionalSpotLightShadowMap[lightIndex], lightSpacePos.xy).x >= (lightSpacePos.z - 0.0005)) ? 1.0 : 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TestShadowPoint(int lightIndex, vec3 lightToWorld, float zNear, float zFar)
|
float CalculatePointShadowFactor(int lightIndex, vec3 lightToWorld, float zNear, float zFar)
|
||||||
{
|
{
|
||||||
return texture(PointLightShadowMap[lightIndex], vec3(lightToWorld.x, -lightToWorld.y, -lightToWorld.z)).x >= VectorToDepthValue(lightToWorld, zNear, zFar);
|
return (texture(PointLightShadowMap[lightIndex], vec3(lightToWorld.x, -lightToWorld.y, -lightToWorld.z)).x >= VectorToDepthValue(lightToWorld, zNear, zFar)) ? 1.0 : 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TestShadowSpot(int lightIndex)
|
float CalculateSpotShadowFactor(int lightIndex)
|
||||||
{
|
{
|
||||||
vec4 lightSpacePos = vLightSpacePos[lightIndex];
|
vec4 lightSpacePos = vLightSpacePos[lightIndex];
|
||||||
return textureProj(DirectionalSpotLightShadowMap[lightIndex], lightSpacePos.xyw).x >= (lightSpacePos.z - 0.0005)/lightSpacePos.w;
|
|
||||||
|
float visibility = 1.0;
|
||||||
|
float x,y;
|
||||||
|
for (y = -3.5; y <= 3.5; y+= 1.0)
|
||||||
|
for (x = -3.5; x <= 3.5; x+= 1.0)
|
||||||
|
visibility += textureProj(DirectionalSpotLightShadowMap[lightIndex], lightSpacePos + vec4(x/1024.0 * lightSpacePos.w, y/1024.0 * lightSpacePos.w, 0.05, 0.0));
|
||||||
|
|
||||||
|
visibility /= 64.0;
|
||||||
|
|
||||||
|
return visibility;
|
||||||
}
|
}
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
|
|
@ -211,22 +220,30 @@ void main()
|
||||||
// Ambient
|
// Ambient
|
||||||
lightAmbient += lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb);
|
lightAmbient += lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb);
|
||||||
|
|
||||||
|
float att = 1.0;
|
||||||
|
|
||||||
#if SHADOW_MAPPING
|
#if SHADOW_MAPPING
|
||||||
if (Lights[i].shadowMapping && !TestShadowDirectional(i))
|
if (Lights[i].shadowMapping)
|
||||||
|
{
|
||||||
|
float shadowFactor = CalculateDirectionalShadowFactor(i);
|
||||||
|
if (shadowFactor == 0.0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
att *= shadowFactor;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Diffuse
|
// Diffuse
|
||||||
float lambert = max(dot(normal, lightDir), 0.0);
|
float lambert = max(dot(normal, lightDir), 0.0);
|
||||||
|
|
||||||
lightDiffuse += lambert * lightColor.rgb * lightDiffuseFactor;
|
lightDiffuse += att * lambert * lightColor.rgb * lightDiffuseFactor;
|
||||||
|
|
||||||
// Specular
|
// Specular
|
||||||
vec3 reflection = reflect(-lightDir, normal);
|
vec3 reflection = reflect(-lightDir, normal);
|
||||||
float specularFactor = max(dot(reflection, eyeVec), 0.0);
|
float specularFactor = max(dot(reflection, eyeVec), 0.0);
|
||||||
specularFactor = pow(specularFactor, MaterialShininess);
|
specularFactor = pow(specularFactor, MaterialShininess);
|
||||||
|
|
||||||
lightSpecular += specularFactor * lightColor.rgb;
|
lightSpecular += att * specularFactor * lightColor.rgb;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -246,8 +263,14 @@ void main()
|
||||||
lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb);
|
lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb);
|
||||||
|
|
||||||
#if SHADOW_MAPPING
|
#if SHADOW_MAPPING
|
||||||
if (Lights[i].shadowMapping && !TestShadowPoint(i, vWorldPos - lightPos, 0.1, 50.0))
|
if (Lights[i].shadowMapping)
|
||||||
|
{
|
||||||
|
float shadowFactor = CalculatePointShadowFactor(i, vWorldPos - lightPos, 0.1, 50.0);
|
||||||
|
if (shadowFactor == 0.0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
att *= shadowFactor;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Diffuse
|
// Diffuse
|
||||||
|
|
@ -283,8 +306,14 @@ void main()
|
||||||
lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb);
|
lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb);
|
||||||
|
|
||||||
#if SHADOW_MAPPING
|
#if SHADOW_MAPPING
|
||||||
if (Lights[i].shadowMapping && !TestShadowSpot(i))
|
if (Lights[i].shadowMapping)
|
||||||
|
{
|
||||||
|
float shadowFactor = CalculateSpotShadowFactor(i);
|
||||||
|
if (shadowFactor == 0.0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
att *= shadowFactor;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Modification de l'atténuation pour gérer le spot
|
// Modification de l'atténuation pour gérer le spot
|
||||||
|
|
@ -328,10 +357,23 @@ void main()
|
||||||
// Ambient
|
// Ambient
|
||||||
lightAmbient += lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb);
|
lightAmbient += lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb);
|
||||||
|
|
||||||
|
float att = 1.0;
|
||||||
|
|
||||||
|
#if SHADOW_MAPPING
|
||||||
|
if (Lights[i].shadowMapping)
|
||||||
|
{
|
||||||
|
float shadowFactor = CalculateDirectionalShadowFactor(i);
|
||||||
|
if (shadowFactor == 0.0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
att *= shadowFactor;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Diffuse
|
// Diffuse
|
||||||
float lambert = max(dot(normal, lightDir), 0.0);
|
float lambert = max(dot(normal, lightDir), 0.0);
|
||||||
|
|
||||||
lightDiffuse += lambert * lightColor.rgb * lightDiffuseFactor;
|
lightDiffuse += att * lambert * lightColor.rgb * lightDiffuseFactor;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -351,8 +393,14 @@ void main()
|
||||||
lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb);
|
lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb);
|
||||||
|
|
||||||
#if SHADOW_MAPPING
|
#if SHADOW_MAPPING
|
||||||
if (Lights[i].shadowMapping && !TestShadowPoint(i, vWorldPos - lightPos, 0.1, 1.0 / lightInvRadius))
|
if (Lights[i].shadowMapping)
|
||||||
|
{
|
||||||
|
float shadowFactor = CalculatePointShadowFactor(i, vWorldPos - lightPos, 0.1, 50.0);
|
||||||
|
if (shadowFactor == 0.0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
att *= shadowFactor;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Diffuse
|
// Diffuse
|
||||||
|
|
@ -381,8 +429,14 @@ void main()
|
||||||
lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb);
|
lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb);
|
||||||
|
|
||||||
#if SHADOW_MAPPING
|
#if SHADOW_MAPPING
|
||||||
if (Lights[i].shadowMapping && !TestShadowSpot(i))
|
if (Lights[i].shadowMapping)
|
||||||
|
{
|
||||||
|
float shadowFactor = CalculateSpotShadowFactor(i);
|
||||||
|
if (shadowFactor == 0.0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
att *= shadowFactor;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Modification de l'atténuation pour gérer le spot
|
// Modification de l'atténuation pour gérer le spot
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue