TheKaiser

06-08-2014, 06:30 AM

I've been banging my head against the wall when dealing with point light shadow mapping, and a recent idea is that I might've been comparing two depth values from different spaces and I'd like some confirmation if thats the case.

The shadow pass draws all the geometry from the 6 different angles originating from the point light using its own view and projection matrices, while the directional vector ("positionDiff") used in sampling the shadowmap and which is also converted to the comparison depth value (func "VectorToDepthValue") is in world space. Is this a potential error?

const std::string gShadingFragmentShader =

"#version 420

layout(std140) uniform UnifPointLight

{

mat4 mWVPMatrix;

vec4 mLightColor;

vec4 mLightPos;

vec4 mGamma;

vec2 mScreenSize;

float mLightIntensity;

float mMaxDistance;

} UnifPointLightPass;

layout (binding = 2) uniform sampler2D unifPositionTexture;

layout (binding = 3) uniform sampler2D unifNormalTexture;

layout (binding = 4) uniform sampler2D unifDiffuseTexture;

layout (binding = 7) uniform samplerCube unifShadowmap;

out vec4 fragColor;

float VectorToDepthValue(vec3 Vec)

{

vec3 AbsVec = abs(Vec);

float LocalZcomp = max(AbsVec.x, max(AbsVec.y, AbsVec.z));

const float f = 100.0;

const float n = 0.1;

float NormZComp = (f + n) / (f - n) - (2 * f * n) / (f - n) / LocalZcomp;

return (NormZComp + 1.0) * 0.5;

}

void main()

{

vec2 texcoord = gl_FragCoord.xy / UnifPointLightPass.mScreenSize;

vec3 worldPos = texture(unifPositionTexture, texcoord).xyz;

vec3 normal = texture(unifNormalTexture, texcoord).xyz;

vec3 diffuse = texture(unifDiffuseTexture, texcoord).xyz;

normal = normalize(normal);

vec3 positionDiff = (UnifPointLightPass.mLightPos.xyz - worldPos);

float storedDepth = texture(unifShadowmap, positionDiff);

float visibility = 0.0;

if (storedDepth + 0.0001 > VectorToDepthValue(positionDiff))

visibility = 1.0;

float dist = length(positionDiff);

float attenuation = clamp(1.0 - dist*dist * (1 / (UnifPointLightPass.mMaxDistance * UnifPointLightPass.mMaxDistance)), 0.0, 1.0);

attenuation *= attenuation;

vec3 lightDir = normalize(positionDiff);

float angleNormal = clamp(dot(normalize(normal), lightDir), 0, 1);

fragColor = vec4(diffuse, 1.0) * visibility * (angleNormal * attenuation *

UnifPointLightPass.mLightIntensity * UnifPointLightPass.mLightColor);

}

EDIT: also, is it "Lightposition - worldPosition" or is it "worldPosition - LightPosition"? The more I think about it, it feels like the latter.

The shadow pass draws all the geometry from the 6 different angles originating from the point light using its own view and projection matrices, while the directional vector ("positionDiff") used in sampling the shadowmap and which is also converted to the comparison depth value (func "VectorToDepthValue") is in world space. Is this a potential error?

const std::string gShadingFragmentShader =

"#version 420

layout(std140) uniform UnifPointLight

{

mat4 mWVPMatrix;

vec4 mLightColor;

vec4 mLightPos;

vec4 mGamma;

vec2 mScreenSize;

float mLightIntensity;

float mMaxDistance;

} UnifPointLightPass;

layout (binding = 2) uniform sampler2D unifPositionTexture;

layout (binding = 3) uniform sampler2D unifNormalTexture;

layout (binding = 4) uniform sampler2D unifDiffuseTexture;

layout (binding = 7) uniform samplerCube unifShadowmap;

out vec4 fragColor;

float VectorToDepthValue(vec3 Vec)

{

vec3 AbsVec = abs(Vec);

float LocalZcomp = max(AbsVec.x, max(AbsVec.y, AbsVec.z));

const float f = 100.0;

const float n = 0.1;

float NormZComp = (f + n) / (f - n) - (2 * f * n) / (f - n) / LocalZcomp;

return (NormZComp + 1.0) * 0.5;

}

void main()

{

vec2 texcoord = gl_FragCoord.xy / UnifPointLightPass.mScreenSize;

vec3 worldPos = texture(unifPositionTexture, texcoord).xyz;

vec3 normal = texture(unifNormalTexture, texcoord).xyz;

vec3 diffuse = texture(unifDiffuseTexture, texcoord).xyz;

normal = normalize(normal);

vec3 positionDiff = (UnifPointLightPass.mLightPos.xyz - worldPos);

float storedDepth = texture(unifShadowmap, positionDiff);

float visibility = 0.0;

if (storedDepth + 0.0001 > VectorToDepthValue(positionDiff))

visibility = 1.0;

float dist = length(positionDiff);

float attenuation = clamp(1.0 - dist*dist * (1 / (UnifPointLightPass.mMaxDistance * UnifPointLightPass.mMaxDistance)), 0.0, 1.0);

attenuation *= attenuation;

vec3 lightDir = normalize(positionDiff);

float angleNormal = clamp(dot(normalize(normal), lightDir), 0, 1);

fragColor = vec4(diffuse, 1.0) * visibility * (angleNormal * attenuation *

UnifPointLightPass.mLightIntensity * UnifPointLightPass.mLightColor);

}

EDIT: also, is it "Lightposition - worldPosition" or is it "worldPosition - LightPosition"? The more I think about it, it feels like the latter.