现在的位置: 首页 > 综合 > 正文

阴影贴图(PCF)

2018年05月27日 ⁄ 综合 ⁄ 共 1847字 ⁄ 字号 评论关闭

In this recipe, we'll use the latter technique, and sample a constant number of texels around
the fragment's position in the shadow map. We'll calculate an average of the resulting
comparisons and use that result to scale the diffuse and specular components.
We'll make use of OpenGL's built in support for PCF, by using linear filtering on the depth
texture. When linear filtering is used with this kind of texture, the hardware can automatically
sample four nearby texels (execute four depth comparisons) and average the results (the
details of this are implementation dependent). Therefore, when linear filtering is enabled, the
result of the textureProj function can be somewhere between 0.0 and 1.0.
We'll also make use of the built-in functions for texture accesses with offsets. OpenGL
provides the texture access function textureProjOffset, which has a third parameter

that is added to the texel coordinates before the lookup/comparison.

To add the PCF technique to the shadow mapping algorithm, we'll just make a few changes to
the shaders from the recipe Rendering shadows with shadow maps:
1. When setting up the FBO for the shadow map, make sure to use linear filtering on the
depth texture. Replace the corresponding lines with the following code:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR);
2. Use the following code for the shadeWithShadow function within the
fragment shader:
subroutine (RenderPassType)
void shadeWithShadow()
{
vec3 ambient = Light.Intensity * Material.Ka;
vec3 diffAndSpec = phongModelDiffAndSpec();
// The sum of the comparisons with nearby texels
float sum = 0;
// Sum contributions from texels around ShadowCoord
sum += textureProjOffset(ShadowMap, ShadowCoord,
ivec2(-1,-1));
sum += textureProjOffset(ShadowMap, ShadowCoord,
ivec2(-1,1));
sum += textureProjOffset(ShadowMap, ShadowCoord,
ivec2(1,1));
sum += textureProjOffset(ShadowMap, ShadowCoord,
ivec2(1,-1));
float shadow = sum * 0.25;
FragColor = vec4(ambient + diffAndSpec * shadow,1.0);
}

相比之前的版本改了两处:

1.texturefilter liner

2.临近点加权求和,采用textureProjOffset函数

抱歉!评论已关闭.