使用gl函数读取位置访问冲突_使用PCF进行阴影边缘的反走样

本文是OpenGL 4.0 Shading Language Cookbook的学习笔记。

百分比渐近过滤(PCF)是一个简单,常见的进行阴影边缘反走的技术。它通过在片段周围进行采样,然后计算样本比片段的更接近光源的比例,使用这个比例对散射光和镜面光成分进行缩放,然后对片段进行着色。使用这一技术后,阴影边缘看上去进行了模糊一样。

这一技术的最基础形式由Reeves et al在1987年发表(SIGGRAPH Proceedings, Volume 21, Number 4, July 1987)。它将片段的坐标坐标变换到阴影空间,然后在一定范围内采取若干样本,计算比片段的深度值更接近Shadowmap的比例,利用这个比例来对着色进行衰减。随着采样的区域扩大,阴影边缘产生模糊效果。

一个常见的PCF算法变体只在Shadowmap的纹理附近进行固定数量的采样。使用采样的纹理中更接近光源比例来进行着色衰减。这一方法会在阴影边缘产生模糊效果。尽管这样做在物理上并不准确,但对于人眼而言,它看上去效果还不错。

下面右图的阴影使用了PCF,左图没有。我们在右图中可以看到模糊的边缘,以及走样现象的减少。

e23f507d48cf26df1b6ae3aee399fc19.png

在本文,我们使用上面描述的第二种方法,在片段在Shadowmap中对应位置的周围采样固定数量的纹理。我们使用比较结果的平均数来对散射光和环境光成分进行缩放。

我们会充分利用OpenGL对PCF的内建支持。我们使用线性过滤来访问深度纹理。线性过滤下,OpenGL会自动在纹理周围采样四次(执行四次深度比较),然后使用四次结果的平均值作为结果(这些细节依赖于OpenGL的具体实现)。所以,线性过滤开启后,textureProj函数的返回会在0.0和1.0之间。

我们使用OpenGL的内建函数textureProjOffset来实现对纹理的偏移访问。

实现

使用PCF技术进行阴影的反走样,需要我们对之前的专栏文章《使用Shadowmap渲染阴影》中的代码做下面这些修改:

1. 创建用于渲染Shadowmap的帧缓冲对象时,设置深度纹理使用线性过滤。

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

2. 使用下面的代码作为片段着色器中shadeWithShadow函数的代码:

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);
}

原理

第一步,我们开启了Shadowmap纹理的线性过滤。开启后,OpenGL就会自动进行4次采样,然后返回四次采样结果的平均值作为纹理采样结果。

在片段着色器中,我们使用textureProjOffset函数进行4次采样(沿对角线)。该函数的第3个参数时坐标偏移,在采样发生前,这个偏移值会被添加到采样坐标上。

线性过滤开启后,每次纹理访问进行4次采样,也就是说一次textureProjOffset函数调用,采样了16个样本。采样的结果求平均值后被我们保存在了变量shadow。

我们通过变量shadow来进行散射光和镜面光成分的衰减。

优化

皮克斯的Fabio Pellacini发表了一篇非常优秀的关于PCF技术的纵览,可以在GPU Gems, edited by Randima Fernando, Addison-Wesley Professional, 2004的第11章找到。如果想要更详细地了解PCF,强烈推荐阅读这篇短小精悍地文章。

PCF技术因为它地简单高效而成为最常用地进行阴影反走样地技术。除此之外,它生成地阴影边缘地模糊效果也常常被用来模拟软阴影,但随着它地模糊边缘地增大,它需要进行地采样个数也需要增加,这限制了它在这方面的应用。在下一篇文章,我们将介绍使用随机采样的方法生成软阴影。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值