GPU Gems1 - 17 环境遮挡

环境光遮蔽(Ambient Occlusion)“AO”为Amblent Occlusion的缩写,中文译为环境光遮蔽。在DirectX 10.1 API推出后,Amblent Occlusion升级为SSAO(Screen-Space Ambient Occlusion:屏幕空间环境光遮蔽);而在微软推出DirectX 11 API后,SSAO升级至HDAO(高解析度环境光遮蔽:High Definition Ambient Occlusion)。

我们有必要对AO(环境光遮蔽)的释义进行一个简单了解:AO是来描绘物体和物体相交或靠近的时候遮挡周围漫反射光线的效果,可以解决或改善漏光、飘和阴影不实等问题,解决或改善场景中缝隙、褶皱与墙角、角线以及细小物体等的表现不清晰问题,综合改善细节尤其是暗部阴影,增强空间的层次感、真实感,同时加强和改善画面明暗对比,增强画面的艺术性。可以说:

AO特效在直观上给我们玩家的感受主要体现在画面的明暗度上,未开启AO特效的画面光照稍亮一些;而开启AO特效之后,局部的细节画面尤其是暗部阴影会更加明显一些。

本章讲到了如何使用有效的实时环境光遮蔽技术,对物体遮蔽信息及环境进行预处理,综合这些因素给物体创建逼真的光照和阴影。本文大部分参考https://zhuanlan.zhihu.com/game-programming

1 概述

首先,本文中讲到,环境光遮蔽(Ambient Occlusion)一般而言有两种理解:

1)将环境光遮蔽视为“智能”的环境光项,其在模型表面的变化取决于在每点可见多少外部环境。

2)将环境光遮蔽视为一个漫反射项,其能有效地支持复杂分布的入射光线。

文中将考虑上述的第二种解释。

其基本思路是,假如预处理一个模型,计算它上面每个点可以看到多少外部环境,可以相反地计算有多少环境被模型的其他部分遮挡,然后在渲染时使用这个信息计算漫反射着色项的值。其结果是模型上的裂缝变暗,而模型的暴露部分会接收更多的光线,因此更明亮。这种效果实质上比使用标准的着色模型更逼真。

另外,这个方法可以扩展为使用环境光作为照明源,用代表各个方向入射光的环境贴图没来决定物体上每个点光的颜色。为了这个特性,除了记录在点上可以看到多少外部环境之外,也记录大部分可以光从哪个方向到达。这两个量有效地定义了从外面进入场景的未被遮挡的方向圆锥体,可以一起用来做为来自环境贴图的极端模糊的查询,模拟着色点上来自感兴趣的方向圆锥体的全部入射照度。

2 预处理步骤(The Preprocessing Step)

给定一个任意的着色模型,环境光遮蔽算法需要知道模型上每点的两个信息:

(1)该点的“可到达度(accessibility)”- 即该点上方半球的哪一部分未被模型的其他部分遮挡;

(2)未被遮挡的入射光的平均方向。

通过下图在平面上说明这两个概念。给定在表面上的点P,其法线为N,P点上半球的2/3被场景中其他几何体遮挡,半球另外的1/3不被遮挡。入射光的平均方向用B表示,其在法线N的右侧。大致来说,在P点的入射光的平均颜色,可以通过求围绕B矢量的未遮挡入射光的圆锥体的平均值得到。

下面贴出的伪代码显示了我们的基本方法。在每个三角形的中心,我们产生一组以表面法线为中心的半球形光线,跟踪每道光线进入场景,记录哪些光线与模型相交,标志不能从环境接收的光线,以及不被遮挡的光线。接着我们计算不被遮挡的光线的平均方向,这给出了入射光平均方向的近似值。(当然,我们计算的方向实际上可能会被遮挡,但我们选择忽略不计这个问题。)

Example 17-1 计算环境光遮蔽量的基本算法伪代码 (Basic Algorithm for Computing Ambient Occlusion Quantities)

For each triangle {

    Compute center of triangle

    Generate set of rays over the hemisphere there

    Vector avgUnoccluded = Vector(0, 0, 0);

    int numUnoccluded = 0;

    For each ray {

        If (ray doesn't intersect anything) {

            avgUnoccluded += ray.direction;

            ++numUnoccluded;

        }

    }

    avgUnoccluded = normalize(avgUnoccluded);

    accessibility = numUnoccluded / numRays;

}

生成这些光线的简单方法是使用拒绝采样法(rejection sampling):检测在x,y和z为-1到1区间的3D立方体中随机生成的光线,并拒绝不在单位半球中与法线相关的光线。

能通过这次检测的光线方向可视分布理想的光线方向。列表17-2的伪代码表示出了此方法的实现思路。

当然,也可以用更复杂的蒙特卡洛(Monte Carlo)采样法来得到更好的样本方向的分布。

Example 17-2 使用拒绝采样法计算随机方向的算法伪代码(Algorithm for Computing
Random Directions with Rejection Sampling)

while (true) {

    x = RandomFloat(-1, 1); // random float between -1 and 1

    y = RandomFloat(-1, 1);

    z = RandomFloat(-1, 1);

    if (x * x + y * y + z * z > 1) continue; // ignore ones outside unit

    // sphere

    if (dot(Vector(x, y, z), N) < 0) continue; // ignore "down" dirs

    return normalize(Vector(x, y, z)); // success!

}




另外,用图形硬件代替光线追踪软件,有可能加速遮挡信息的计算。

3 使用环境光遮蔽贴图进行渲染(Rendering with Ambient Occlusion Maps)

使用环境光遮蔽贴图进行着色的基本思想是:可以直接在着色点处使用之前已计算好的,有多少光线能到达表面的,优质的近似值信息。

影响这个数值的两个因素是:

(1)在此点上方半球的哪个部分不被点和环境贴图之间的几何体遮挡。

(2)沿着这些方向的入射光是什么。

下图显示了两种不同的情况。在左图中,只能看到着色点上面的一小部分,由方向矢量B和围绕它的方向圆锥体所表示,该点的可到达度非常低。而在右图中,沿着更大范围的方向有更多的光线到达给定点。

图 不同量的可见度的近似(左图:由于附近的几何体的遮挡比较严重,这点得到的照度较小;右图:沿着更宽方向的圆锥体,更大量的光能到达这点,照度较左图更大)

在预处理中计算的可访问性值告诉我们哪一部分半球可以看到环境贴图,而可见方向的平均值给出一个近似方向,围绕它计算入射光。虽然这个方向可能指向一个实际被遮挡的方向(例如,如果半球的两个独立区域未被遮挡,但其余的部分被遮挡,平均方向可能在这两者之间),但在实践中其通常运行良好。

有无使用环境光遮蔽贴图进行渲染的对比图

 

【核心要点总结】

 

给定一个任意的着色模型,环境光遮蔽算法需要知道模型上每点的两个信息:

1)该点的可到达度(accessibility)。

2)未被遮挡的入射光的平均方向。

文中提出的环境光遮蔽方法,总结起来有三个要点:

  • 采用了多种在实践中运行良好的近似方法。
  • 主要为预处理操作,将相对昂贵的计算事先准备好,且仅计算在渲染时进行快速着色所需的正确信息。
  • 预处理不依赖于光照环境贴图,因此可以轻松使用场景中的动态照明。

【本章配套源代码汇总表】

Example 17-1 计算环境光遮蔽量的基本算法伪代码(Basic Algorithm for Computing
Ambient Occlusion Quantities)

Example 17-2 使用拒绝采样法计算随机方向的算法伪代码(Algorithm for Computing
Random Directions with Rejection Sampling)

Example 17-3 使用可到达度和环境映射进行着色的片元Shader(Fragment Shader for
Shading with Accessibility Values and an Environment Map)

Example 17-4 latlong( )函数的定义(The latlong() Function Definition)

Example 17-5 computeBlur( )函数的定义(The computeBlur() Function Definition)

【关键词提炼】

环境光遮蔽(Ambient Occlusion)

拒绝采样(Rejection Sampling)

环境光遮蔽贴图(Ambient Occlusion Maps)

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
GPU Gems是一本关于图形处理器(GPU)编程的经典书籍,由Nvidia公司出版。这本书的内容涵盖了各种有关GPU编程的主题,包括渲染、光照、物理模拟、图像处理等。通过学习这本书,读者可以了解到如何充分利用GPU的并行计算能力来提高图形渲染的效率和质量。 为了进行GPU Gems的下载,可以通过以下几种途径实现。 首先,可以到Nvidia的官方网站上搜索GPU Gems相关的资源,并尝试下载电子版的PDF文件或者浏览在线的html版本。这需要通过分别访问各个章节的网页或者注册成为Nvidia开发者来获取下载权限。网上也有一些第三方提供GPU Gems资源下载的网站,可以通过搜索引擎查找。 其次,可以尝试在一些科研论文或者技术博客的网站上查找GPU Gems相关的下载链接。这些链接可能是其他开发者或者研究者在自己的网站或者博客上分享的资源。在这些网站上找到链接后,可以直接点击下载相应的资源。 此外,可以尝试通过一些知名的编程书籍网站或者图书馆的在线平台搜索GPU Gems相关的电子书。这些平台通常会有一些付费或者免费的电子书资源,读者可以根据自己的需求选择合适的版本进行下载。 总之,通过以上的途径,读者有很多选择来下载GPU Gems,他们可以根据自己的需求选择相应的方式。无论是通过官方网站、第三方网站,还是其他相关平台,读者都能够找到他们需要的GPU Gems资源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值