Real-Time Rendering Fourth Edition 学习笔记之 -- 第五章:着色基础(Shading Basics)

“A good picture is equivalent to a good deed.”
—Vincent Van Gogh



1 着色模型(Shading Models)

第一步首先确定使用哪种着色模型:
在这里插入图片描述
在这里插入图片描述
本章示例中采用的是 Gooch着色模型:
在这里插入图片描述
在这里插入图片描述
结合灯光后可以总结为:
在这里插入图片描述



2 光源

本节描述光照和常见的灯光类型,可以参考之前写过的DX12笔记:
Introduction to 3D Game Programming with DirectX 12 学习笔记之 — 第八章:光照



3 光照模型的实现


3.1 频率的评估(Frequency of Evaluation)

在设计着色实现的时候,计算需要根据频率的评估进行划分。
首先,评估计算的结果是否在整个Draw Call中是恒定的,如果是的话,计算应该有应用,特别是CPU来进行,如果放到GPU会有更大的开销。然后将结果通过图形API放到着色器输入参数中。
比如是否有只需要执行一次的运算,比如shader的编译,可以放到加载程序或者安装的时候进行离线预编译。
另一种情况是,某些着色计算是随着应用一直改变,但是改变得很慢,而且计算量非常大。比如游戏中的24小时天气效果。它的计算就可以划分到多个帧中分批计算。
另一种情况是,基于每帧都需要的计算,比如连接view和perspective矩阵;或者逐模型的,比如基于位置更新模型光照参数;或者逐Draw Call的,比如更新模型每个材质的参数。将这些输入参数,根据更新频率来进行分组,可以帮助GPU constant参数更新的性能。

如果着色计算的结果是根据Draw Call改变,那么它就不能由shader input进行传入。它比如有可编程着色阶段来计算。理论上,着色计算可以在任何可编程阶段进行,每个阶段对于的频率如下:

  • Vertex shader—Evaluation per pre-tessellation vertex.
  • Hull shader—Evaluation per surface patch.
  • Domain shader—Evaluation per post-tessellation vertex.
  • Geometry shader—Evaluation per primitive.
  • Pixel shader—Evaluation per pixel.

在实际应用中,着色计算一般都是逐像素进行的。逐顶点运算主要用以变换和编写。下图展示了逐像素和逐顶点计算的差别。
在这里插入图片描述
需要注意的是,vertex shader经常创建单位法向量,但是线性差值会改变它的长度,所以在pixel shader中又需要重新将向量标准化,如下图。即使差值后长度会变化,在vertex shader中还是需要单位化法向量,因为如果长度不同,差值出来的法向量的方向会发生偏差,如下图左右对比:
在这里插入图片描述
与表面法向量不同,点朝向的相连个,比如view向量和光照向量,它们不会做差值运算。
在pixel shader中通过减法计算出来的向量不要进行标准化,否则会导致计算出现偏差,如下图:
在这里插入图片描述
之前有提到过,vexter shader将位置变换到合适的坐标系,但是哪个坐标系比较合适呢?这个需要根据实际需求来确定,比如场景中如果有大量灯光,那么变换到世界坐标系就比较合适,因为不需要变换灯光的位置;否则变换到camera坐标系比较合适。

上面已经讨论了大部分实现的思路,但是也有一些例外,比如一些逐primitive着色公式的风格化效果:flat shading:
在这里插入图片描述
flat shading可以基于geometry shader来实现,但是最近大部分还是基于vertex shader来实现。它让primitive使用第一个vertex的属性,并且关闭线性差值。


3.2 实现的例子

本节实现的例子是从Gooch模型扩展出来的,它的公式在

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值