So after hard work to make directional light shadow map work finally I can see a shadow map rendered on a quad but it is drawn only with depth GL_DEPTH_COMPONENT16
and type GL_UNSIGNED_SHORT
, or GL_DEPTH_COMPONENT32F
and type GL_FLOAT
but it is in red scale not gray scale
the problem is I used many methods to calculate the depth to draw the shadow but no shadow appears.
glCullFace(GL_FRONT);
glGenFramebuffers(1, &depthMapFBO);
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
glGenTextures(1, &depthMap);
glBindTexture(GL_TEXTURE_2D, depthMap);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
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_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthMap, 0);
glDrawBuffers(1, GL_NONE);
glReadBuffer(GL_NONE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glCullFace(GL_BACK);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
LOGI("framebuffer incomplete");
}
and the fragment is:
uniform mediump sampler2DShadow shadowMap;
......
float bias = 0.005;
float visibility = 1.0;
for (int i=0;i<4;i++){
int index = i;
visibility -= 0.2*(1.0-texture( shadowMap, vec3(FragPosLightSpace.xy + poissonDisk[index]/700.0, (FragPosLightSpace.z-bias)/FragPosLightSpace.w) ));
}
result =light.intensity* (visibility * (diffuse + specular));
A texture with an depth component format, such as
GL_DEPTH_COMPONENT16
orGL_DEPTH_COMPONENT32F
has only 1 color channel, the red color channel.If you read data from a texture sampler, where a depth component texture is bound to, then the green, blue and alpha channel are set automatically.
The Image Format specification of Khronos group says:
Because of that, the red color is set, the green and blue color is set to 0 and the alpha channel is 1. The causes the opaque red surface.
If you want to read a grayscale color from a depth component texture, then you have to read the red color channel and you have to apply the red color channel to the green and blue color, too.
You have to adapt the code like this:
or this: