Je tente d'implémenter la cartographie d'ombre en utilisant opengl, en utilisant une lumière directionnelle.L'échantillonnage à partir de la texture de la profondeur donne toujours 0
Je confirme que la texture de profondeur est rendu correctement, comme ceci:
Et pour effectuer une inspection visuelle, je également sortie les coordonnées spatiales du monde, transformées à la perspective lumière:
Encore une fois, ça semble aller.
Cependant, quand j'échantillon, la texture de profondeur, en utilisant:
vec3 coord = vec3(shadowCoords.xy,shadowCoords.z/shadowCoords.w);
float depth = texture(shadowMap, coord);
Je trouve que la comparaison échoue toujours. Si je change uniform sampler2DShadow shadowMap;
en uniform sampler2D shadowMap;
, et échantillonne la texture directement en utilisant texture(shadowMap, coord.xy).r
, je trouve que la valeur échantillonnée est toujours nulle, en produisant ce résultat à l'écran.
J'ai créé la texture de profondeur comme ceci:
glGenTextures(1, &m_DepthTexture);
glBindTexture(GL_TEXTURE_2D, m_DepthTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_DepthTexture, 0);
et mon code shader est la suivante (sommet):
#version 430
// Some drivers require the following
precision highp float;
layout (location = 0)in vec3 MSVertex;
layout (location = 4)in vec2 MSTexCoord;
out xferBlock
{
vec3 VSVertex;
vec2 VSTexCoord;
} outdata;
void main()
{
outdata.VSVertex = MSVertex;
outdata.VSTexCoord = MSTexCoord;
gl_Position = vec4(MSVertex,1.0);
}
et fragment shader:
#version 430 core
// Some drivers require the following
precision highp float;
layout (location = 0) uniform sampler2D positionMap;
layout (location = 1) uniform sampler2D normalMap;
layout (location = 2) uniform sampler2D colourMap;
layout (location = 3) uniform sampler2D specularMap;
layout (location = 4) uniform sampler2DShadow shadowMap;
struct DirLightData
{
vec4 colour;
float intensity;
vec4 direction;
};
uniform mat4 ShadowTransform;
uniform DirLightData dirLight;
out vec4 colour;
uniform vec3 WSCamPos;
in xferBlock
{
vec3 VSVertex;
vec2 VSTexCoord;
} indata;
vec3 computeLight(vec3 Ldirection, vec3 Vdirection, vec3 Lcolour, vec3 normal, float Lintensity, float specular)
{
vec3 diffCol = Lcolour * max(0.0,dot(normalize(normal),-Ldirection));
vec3 reflectVec = normalize(reflect(Ldirection,normal));
float specFactor = max(dot(reflectVec,Vdirection),0);
float specPow = pow(specFactor,specular*255.0);
vec3 specCol = Lcolour * specPow;
return (diffCol+specCol)*Lintensity;;
}
float computeOcclusion(vec4 shadowCoords)
{
float vis = 1.0;
vec3 coord = vec3(shadowCoords.xyz/shadowCoords.w);
float depth = texture(shadowMap, vec3(coord.xy,coord.z+0.05));
if ( depth < coord.z);
{
vis = 0.5;
}
return vis;
}
void main()
{
vec4 pcolour = texture(positionMap, indata.VSTexCoord).rgba;
vec4 ncolour = texture(normalMap, indata.VSTexCoord).rgba;
vec4 dcolour = texture(colourMap, indata.VSTexCoord).rgba;
vec4 scolour = texture(specularMap, indata.VSTexCoord).rgba;
vec4 shadowCoord = ShadowTransform * pcolour;
float visibility = computeOcclusion(shadowCoord);
//float depth = texture(shadowMap, shadowCoord.xy).z;
vec3 vToEye = WSCamPos - pcolour.xyz;
vToEye = normalize(vToEye);
vec3 outColour = vec3(0.0,0.0,0.0);
outColour = computeLight(dirLight.direction.xyz,vToEye,dirLight.colour.rgb,ncolour.rgb,dirLight.intensity,scolour.r);
colour = vec4(visibility*(dcolour.rgb*outColour),1.0);
}
Quelqu'un peut-il endroit où cela ne va pas?
A propos de 2: Si vous utilisez 'sampler2D' à la place de' sampler2DShadow', vous n'utiliserez plus PCF. – BDL
Deux choses ont fonctionné: supprimer l'instruction if et utiliser directement la profondeur échantillonnée, et appeler glCullFace (GL_FRONT) avant de rendre la carte de profondeur. Il semble que j'ai eu un problème d'acné d'ombre de grain très fin, qui n'était pas facile à voir. –
Même si la réponse n'était pas * exactement * juste, elle m'a donné matière à réflexion et m'a orienté dans la bonne direction, alors merci. –