当前位置: 代码迷 >> 综合 >> RTR4读书笔记 Chapter5 Shading Basics
  详细解决方案

RTR4读书笔记 Chapter5 Shading Basics

热度:48   发布时间:2024-01-27 05:04:33.0

5.1 阴影模型(Shading Model)

Gooch Model,根据顶点法线与灯光方向的接近程度来计算冷暖色调。
该光照模型不考虑光照的强度与颜色,只使用了光照方向。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述±号指Clamp01
r = 2(n * l)*n - l为反射光方向的计算


5.2 光源(Light Sources)

5.2.1 方向光(Directional Light)

无特定位置,方向、颜色、光照强度不变的光。

5.2.2 精准光源(Punctual Lights)

点光源(Point Light)

没有尺寸、形状、大小,但有特定位置的光。
其光照强度随距离而衰减,首先是以距离的平方成反比,但这样会产生“在极近处光的强度将无限大”的问题,而不同的引擎有不同的解决算法:
r指光照距离
UE:增加了一个值较小(UE中为1cm)系数ε
在这里插入图片描述
CryEngine & Frostbite :
在这里插入图片描述
还有一个问题,即“无论多远,光的强度永远无法为0”。
解决方案:
在这里插入图片描述
在这里插入图片描述

聚光灯(Spotlights)在这里插入图片描述

5.2.3 其他灯光类型(Other Light Types)

区分“其他灯光”的依据是“灯光方向的计算方式”,
除了前面提到的光源类型外,古墓丽影还拥有使用线段代替点的光源。对于每个着色像素,将线段上最接近点的方向用作光方向

到目前为止讨论的光的类型是抽象的。
实际上,光源具有一定的大小和形状,并且可以从多个方向照亮表面点。在渲染中,此类光源称为区域光源,并且在实时应用中的使用稳步增长。
区域光渲染技术分为两类:模拟区域光被部分遮挡的阴影边缘柔化的技术和模拟区域光对表面着色的影响的技术


5.3 实施着色模型(Implementing Shading Model)

5.3.1 评估频率(Frequency of Evaluation)

在设计着色实现时,需要根据计算的评估频率对计算进行划分。

  1. 首先,确定给定计算的结果在整个绘制调用中是否始终恒定。在这种情况下,尽管GPU计算着色器可以用于特别昂贵的计算,但是计算可以由应用程序执行,通常在CPU上执行。结果通过统一的着色器输入传递到图形API。
  2. 另一种情况是,阴影计算的结果在应用程序运行中发生变化,但是变化速度非常之慢以至于不需要在每一帧进行更新。
    例如,照明因素取决于虚拟游戏世界中的一天中的时间。
  3. 其他情况包括每帧执行一次的计算,例如将视图矩阵和透视图矩阵连接在一起;或每个模型一次,例如根据位置更新模型照明参数;或每个绘图调用一次,例如,模型中每种材料的更新参数。

如果着色计算的结果在一次Draw Call中发生更改,则无法通过统一的着色器输入将其传递给着色器。此时应使用可编程着色器:

  • 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.(像素)

我们可以在顶点着色器计算漫反射,而在片元着色器计高光,这的确能省下一些计算,但这在实践中并不是最佳方案,着色模型的线性变化部分往往在计算上花费最少,并且以这种方式拆分着色计算往往会增加足够的开销(例如重复的计算和其他变化的输入),以胜过任何好处。
如前所述,在大多数实现中,顶点着色器负责非着色操作,例如几何变换和变形。

数据的坐标系的变换,通常应选择能够最大程度减少计算量的坐标系。

5.3.2 实施实例(Implementation Example)

编写了一个以GLSL实现的光照模型实例。
其中,点光源被定义为vec4位置与vec4颜色,这些定义为vec4而不是vec3,以符合GLSLstd140数据布局标准的限制。尽管在这种情况下,std140layout可能会导致一些空间浪费,但它简化了确保CPU和GPU之间的数据布局一致的任务

5.3.3 材质系统(Material Systems)

以最简单的形式,参数化材质需要两种类型的材质实体:材质模板(material templates)和材质实例(material instances)。
每个材质模板都描述了一类材料,并具有一组参数,可以根据参数类型为其分配数字,颜色或纹理值。
每个材质实例都对应于材质模板及其所有参数的一组特定值。
诸如Unreal Engine之类的某些渲染框架允许使用更复杂的层次结构,其中材质模板是从多个级别的其他模板派生的。

材质系统最重要的任务之一是将各种着色器功能划分为单独的元素,并控制这些元素的组合方式。
在许多情况下,这种类型的组合很有用,包括以下几种:

  • 用几何处理(例如,刚性变换,顶点混合,变形,镶嵌,实例化和剪切)进行表面着色合成。这些功能的位点是独立变化的:表面着色取决于材质,几何处理取决于网格。
  • 使用诸如像素丢弃和混合之类的合成操作来合成表面阴影。这与移动GPU尤其相关,在移动GPU中,混合通常是在像素着色器中执行的。通常期望独立于用于表面着色的材质来选择这些操作。
  • 使用着色模型本身的计算组合用于计算着色模型参数的操作。这允许编写一次着色模型实现,并将其与计算着色模型参数的各种不同方法结合使用。
  • 相互组成可单独选择的材质特征,选择逻辑以及着色器的其余部分。这样可以分别编写每个功能的实现
  • 组合阴影模型并通过光源评估计算其参数:计算每个光源的clight值并绘制其阴影点。

变体过多
现代材质系统同时使用运行时和编译时的着色器变量,即使不再只在编译时处理全部负担,但总体复杂性和变量数量仍在增加,因此仍然需要编译大量着色器变量,材料系统设计师采用不同的策略来解决这些设计目标。
尽管有时将它们作为互斥的系统体系结构表示,但是这些策略可以并且通常可以合并在同一系统中。这些策略包括以下内容:

  • 代码重用——使用"#include"预处理指令访问其他shader中的功能。
  • 删减法——编写一个“超级Shader”,运行时将用不到的功能关闭。
  • 相加法——大量的功能定义为带有输入和输出连接器的节点,并且将它们组合在一起。如节点式Shader编辑器。
  • 基于模板——定义了一个接口,只要符合该接口,就可以插入不同的实现。这比加性策略更正式,通常用于较大的功能块。这种接口的一个常见示例是着色模型参数的计算与着色模型本身的计算之间的分离。UE具有不同的“material域”,其中包括Surface域用于计算着色模型参数,而LightFunction域用于计算标量值,该值可调制给定光源的光线。类似的surface shader结构也存在于其中Unity。

5.4 走样与反走样(Aliasing and Antialiasing)

5.4.1 采样与滤波原理(Sampling and Filtering Theory)

从原理上来讲,走样的产生原因是采样频率过低
在这里插入图片描述

5.4.2 基于屏幕的反走样(Screen-Based Antialiasing)

MSAA(Multisampling antialiasing)

在这里插入图片描述

TAA(temporal antialiasing)

*时域抗锯齿
可使用以前帧的结果来改善图像
是因为延迟着色技术与MSAA和其他多采样支持不兼容,因此TAA近年来也受到了很大的关注。

采样模式(Sampling Patterns)

随机化采样
在这里插入图片描述

RGSS(Rotated grid supersampling)

在这里插入图片描述

形态学方法(Morphological Methods)

MLAA(morphological antialiasing)
是一种后期处理型的反走样方法,大体上就是“猜测边缘,进行颜色差值计算”
在这里插入图片描述


5.5 透明度、Alpha值以及合成(Transparency,Alpha,and Compositing)

纱门透明(screen-door transparency)
即简单地将在透明物体后面的物体的颜色与透明物体颜色混合。

5.5.1 混合指令(Blending Order)

over operator

在这里插入图片描述
cs为透明物体颜色(s意为source,而d意为destination)

additive blending(相加)

在这里插入图片描述
所有透明物体要在不透明的物体绘制完成后开始绘制。
z-buffer的局限性在于每个像素只能存储一个对象。
如果多个透明对象与同一像素重叠,则z-buffer不能单独容纳并稍后解析所有可见对象的效果。
当在任何给定像素的透明表面上使用时,通常需要以从后到前的顺序进行渲染。
不这样做可能会给人错误的视觉效果。实现这种排序的一种方法是按照各个对象的质心沿视图方向的距离对其进行排序。
若是凹面体,则仍可能会出现错误的渲染效果。

under operator

在这里插入图片描述
当透明物体在前面,不透明物体在后面时,从前往后画的公式under.
其中alpha值的计算与顺序无关。

5.5.2 顺序无关的透明(Order-Independent Transparency)

Order-independent transparency(OIT) ,也叫depth peeling(深度剥离),
使用了2个z-buffer和多个pass:
首先,第一个pass进行渲染遍历,以使所有表面的z深度(包括透明表面)都在z-buffer中。然后第二个pass渲染所有透明物体,当一个透明物体的深度值与第一个pass的z-buffer中的值相等时,说明这个物体属于“最近的‘一批’透明物体”,将其值记入color-buffer中,然后舍弃该片元。第三个pass再次渲染所有透明物体,此时可以得出“第二近的一批透明物体”……重复操作,即peel(剥离),随后将所有不透明物体绘制即可。颜色混合操作使用under

深度剥离有许多变体,如Bavoil和Myers提出了双深度剥离,其中在每个遍历中剥离两个深度剥离层,即最接近和最远的剩余剥离层,从而将渲染遍的数量减少了一半。

鉴于各种类型的透明内容,渲染方法和GPU功能,没有完美的解决方案来渲染透明对象。

5.5.3 预乘Alpha与合成(Premultiplied Alphas and Compositing)

over用于照片或对象的合成渲染的混合,这种操作被称之为合成(compositing)


5.6 显示编码(Display Encoding)

主要是关于伽马校正的概念
相关视频