4改变顶点位置_[GPU Gems3] 4. 次世代SpeedTree渲染

Chapter 4. Next-Generation SpeedTree Rendering​developer.nvidia.com
d3b2d0fd1a937684bf78c4978dc1c39f.png

介绍

本文介绍了渲染树的几个手段,分别是

  • 轮廓裁剪(Silhouette Clipping)增加了树枝和树干外形的细节
  • 阴影贴图提供了逐树叶级的真实感自我遮挡
  • 使用双叶面光照模型和HDR来优化光照
  • 半透明覆盖(alpha to coverage)来抗锯齿

轮廓裁剪

对于下图黄框中的内部细节,使用浮雕映射(relief mapping)来处理。对于蓝框中的轮廓细节,使用了一种称为轮廓裁剪的技术,在垂直于视线向量的方向上挤压物体的轮廓。类似于浮雕映射,这些轮廓对高度图进行光线追踪,以决定哪个像素实际上被轮廓所遮挡。

8d9d161d2f8adf470845d4f024b871f9.png
  • 轮廓挤出
    根据逐顶点的法向量和视线向量的点积,插值找到三角形边上点积为0的点。在找到的点利用几何着色器构造两个三角形进行挤出。

991f7c70bc2036618dd03dadc370f823.png

1e1ab5c36628e89193b0d013a6591df1.png

c1de4f25d831b7353d4bb75b5e8ffaed.png
  • 高度追踪
    挤出后的顶点的基切线和纹理坐标不需要变化。为每个顶点计算视线向量。如下图所示,在像素Shader中,从点A开始逐步沿着视线向量的反方向移动来改变它的纹理坐标,最终到达B点。然后执行浮雕映射中的高度追踪查找。当发现交点时,就计算该片元的漫反射光照和阴影,否则该片元进行抗锯齿或者丢弃。算法的改进手段有把线性和二分查找结合(Policarpo2004)或预计算来加速跟踪(Dummer2006)

f14d8df1d5fb5d3c296025ab934c6b25.png

979202f7c4e602f4a72e2c34fbd1a66f.png

e2f9740ceea2751924980616fad132f2.png
  • 轮廓LOD:随树离相机距离变远时,轮廓的宽度逐渐减为0,对远处的树不进行轮廓处理。

阴影

SpeedTree中的阴影是离线预计算的,因此存在没有自遮挡和阴影不真实的问题,有以下解决手段:

a7aa1bcf5ff00e707b2a9db2625dcb1b.png
  • 树叶自遮挡
    此处讨论的树叶情况是树叶广告牌,总是朝向相机,使用的方法是阴影映射。当渲染树叶时,树叶朝向相机。当渲染阴影贴图时,它们转而朝向光源。绕中心点旋转会出现下图(a)中只有一半树叶片接受阴影的情况,为了避免这种情况使用(b)中旋转后向光源移动的方法。

99cb50bf25e7a420db9199f951766356.png


但直接对树叶平面片投射阴影会使得阴影像延长的条纹。解决方法是在视线方向使用偏移系数来改变阴影的位置,偏移系数存储在纹理中。使用新的树叶位置,把被遮挡的像素投射到光照空间并对阴影进行采样。

bdaacd106ac74e7a32180cbb7f25ca8b.png
Leaf Texture and Accompanying Depth-Offset Texture

1a35f371dd97f785e2d1e1d2f6a41e23.png
The Impact of Leaf Offsets with Self-Shadowing
  • 级联阴影贴图:将视锥体分割为几个区域并分别为每个区域将阴影贴图渲染到不同的纹理。为了减少CPU负担,不同的级联使用不同频率的更新。

树叶光照

  • 双边光照
    当树叶从后面被照亮时,树叶的主要亮度来自于透射的光,色彩会轻微变黄或变红。

94574271a16327f3cdd046d9eaef40cb.png


使用的策略是在像素着色器生成偏黄的树叶颜色(Diffuse.g * 0.9, Diffuse.g * 1.0, Diffuse.g * 0.2),并根据视线方向和光线方向的夹角μ,在原来颜色和计算的黄色之间插值,μ越接近于π,树叶颜色越黄,镜面高光也越小。

e41cbb9a59fdfb20081cbd8dfd2fcae4.png
  • 镜面高光
    首先使用普通的镜面反射,但远处的树会闪闪发光,因此根据距离来减少镜面反射。其次,为了实现叶片如下图的反射效果,使用一个粗糙的V型法向量贴图把树叶分成两半。最后,为了避免镜面反射细节太多造成闪烁,使用粗糙的mipmap层次的贴图使得反射光更加平滑柔和。

f13d17eec6295d689c7232a3ef78bdf4.png

半透明覆盖

半透明覆盖把像素着色器输出的alpha值转化为应用于MSAA渲染目标的子像素分辨率上的覆盖掩码。当MSAA分解被使用时,结果会是一个透明的像素。使用半透明覆盖时,可以极大减少方块状区域和硬边缘,尤其是动态时可以减少它们造成的闪烁。

5e56d958ea889539d96d41df1aef80f3.png
The Impact of Alpha to Coverage

为了在LOD之间视线交叉衰减,使用不同alpha测试值的两个LOD被同时绘制。半透明覆盖来执行交叉衰减,虽然可能会有透明度的问题,但很难被注意。

63e762c855ce6f427ff849d5c2c486e2.png

半透明衰减也可以对生成的轮廓边进行反锯齿。为了实现该目的,在轮廓边上生成一个窄的边界区域,它使轮廓的不透明度从完全不透明变为透明。在高度追踪期间,记下对高度图的最小损失并根据这个值来改变像素的不透明度。如果视线向量和高度图相交则alpha为1,如果不相交且最小损失小于屏幕空间的1.5个像素,则逐渐衰减到0,否则直接为0.

1fbc3b85cd06a3a8b57cdeabaac9a42f.png

9b40075c0a42a7c13580352ad66939cb.png
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值