How does sampler2DArrayShadow in glsl works

I am not able understand how to use sampler2DAprrayShadows and how it works. Got some part of it that we need to use depth texture values (GL_DEPTH_COMPONENT) to get the compare result with ref depth. But then how to use the return float value to get the texel.

Got reference from : http://www.khronos.org/opengles/sdk/docs/manglsl/xhtml/texture.xml

I have written a small code to test it as below: My fragment shader as:


in highp vec2 texcoord;
in highp vec4 basecolor;
out highp vec4 myFragColor;

uniform highp sampler2DArrayShadow basetexture;

void main(void)
{
    highp vec3 coords = (vec3(texcoord, 0.0) + vec3(1.0, 1.0, 1.0)) / 2.0;
    highp float depth = texture(basetexture, vec4(coords.x, coords.y, coords.z, -0.5));
    myFragColor = vec4(depth * basecolor);

}

Texture Creation:


glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE,  GL_COMPARE_REF_TO_TEXTURE);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT16, TEX_SIZE, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, texdata);


[QUOTE=debonair;1246981]I am not able understand how to use sampler2DAprrayShadows and how it works. Got some part of it that we need to use depth texture values (GL_DEPTH_COMPONENT) to get the compare result with ref depth. But then how to use the return float value to get the texel.
[/QUOTE]

The sampler*Shadow samplers are used when you want hardware depth comparisons to occur. To get them to work you need to:

[ol]
[li]create a depth texture (DEPTH_COMPONENT or DEPTH_STENCIL type),[/li][li]enable depth comparisons (TEXTURE_COMPARE_MODE == COMPARE_R_TO_TEXTURE), and[/li][li]bind this texture to a sampler*Shadow uniform in the shader,[/li][/ol]

Hardware depth comparisons happen internal to your texture lookup (i.e. texture() call). What you get back is not a filtered texture value, but rather a filtered depth comparison result (where the depth value you pass into the texturre call is compared against one or more texels). This gives you a filtered 0…1 visibility value, which is usually what you want anyway.

A few problems or questions I notice with your code:

Your MIN_FILTER of LINEAR_MIPMAP_LINEAR on your depth texture looks fishy. You probably want LINEAR here. BTW, LINEAR enables PCF shadow map depth comparisons. This sometimes helps soften your shadow edges, which often looks better. To disable PCF, just set NEAREST for MIN/MAG instead.

Also, the texture coordinate format GLSL requires for lookup into a sampler2DArrayShadow is a little strange. Basically, if “pos” is your light clip-space position with the standard *0.5+0.5 bias transform applied and “slice” is the desired texture array slice, then what you want is this:


vec4 texcoord;
texcoord.xyw = pos.xyz;
texcoord.z = slice;
float visibility = texture( shadow_map, texcoord );

This format probably came from the fact that the texcoord format for a sampler2DArray is x,y,slice. And then if you do depth comparisons, the z was just tacked on as the last component (.w) rather then bumping the slice index down to .w.

Note that because all 4 components of the vec4 texcoord are full, there are no projective texture lookups for 2D array textures with shadow map depth comparisons enabled. This is fine for directional light source shadows (where your resulting pos.w value == 1). But for point-light source shadows you need to do your own divide-by-w.

Finally, I can’t make much sense of your existing texcoord math.