图形_GAMES101/202学习笔记

0. 写在前面

本文仅为个人学习GAMES101、202图形学课程时记录的笔记。
其中大部分图形学知识仅是基础内容,后续对这部分内容有更深入的研究后会持续更新。

1. 矩阵变换和光栅

1.1 MVP

  • Model
    图形_GAMES101/202学习笔记_第1张图片

  • View

    • 定义相机位置(position),相机朝向 Lookat(g)和up(t)、lookat 和up可以固定相机朝向
      把相机放在原点,lookat -Z轴,up at Y轴,相当于相机永远不动、而是物体在动。
    • 将相机中心平移到原点,g旋转到-Z轴,t旋转到Y轴,(g×t)旋转到X轴
      图形_GAMES101/202学习笔记_第2张图片
      • 平移:
        图形_GAMES101/202学习笔记_第3张图片
      • 旋转:
        将任朝向的相机旋转到指定朝向是比较难算的,但是将轴朝向旋转到指定朝向是好算的,可以先得到轴朝向到指定朝向的变换,再反过来求逆变换(对旋转矩阵来说相当于转置)
        • Rotate X to (g×t),Y to t, Z to -g,得到R(view)^-1
          图形_GAMES101/202学习笔记_第4张图片
        • 转置得到 R(view)
          图形_GAMES101/202学习笔记_第5张图片
        • M(view) = R(view)*T(view)
  • Projection
    图形_GAMES101/202学习笔记_第6张图片

  • 正交投影变换:

    • 正交投影的视锥是个长方体Cuboid([l, r][b, t][f, n]),其映射变换矩阵:
      图形_GAMES101/202学习笔记_第7张图片
  • 透视投影变换:
    图形_GAMES101/202学习笔记_第8张图片

    • 透视投影的相机范围是个棱台 Frustum,将Frustum先挤压成一个Cuboid,再使用正交投影的方式映射
      ① 近平面的所有点不变
      ② 远平面上的点z值不变
      ③ 远平面上的中心点不变

    • 求将Frustum变换成Cuboid的矩阵 图形_GAMES101/202学习笔记_第9张图片

    • 定义视锥
      Fov Y、Aspect ratio 计算 l r 和 b t
      图形_GAMES101/202学习笔记_第10张图片
      ① Aspect ratio 屏幕宽高比:近平面
      ② Vertical Field of View:fovY,垂直可视角:从相机处,往平面上下两边的中点连线,所夹的角度
      ③ 水平可视角 则是往平面左右两边中点连线
      图形_GAMES101/202学习笔记_第11张图片

  • 视口变换
    图形_GAMES101/202学习笔记_第12张图片

    • 从 [-1, 1]^2 变换到屏幕空间 [ 0, width] *[0, height]
    • 只变换 xy轴,z轴不管

1.2 光栅

  • 像素填充三角形
    • 三角形的好处:
      • 最基础的多边形,其他任意多边形都可以拆分成三角形
      • 三角形内部必定是一个平面
      • 三角形的内部和外部定义清晰,好判断(向量叉积)
      • 三角形内任意一点,可以根据和三个顶点的位置关系,插值得到其他数据的值
    • 叉乘判断点在三角形内部还是外部
      图形_GAMES101/202学习笔记_第13张图片
      对每个三角形,两层for循环判断像素是否在三角形内,每个三角形都有一个image数组来保存像素是否在三角形内的结果
      图形_GAMES101/202学习笔记_第14张图片
      • 指定三角形顺序 p0, p1, p2(顺时针或逆时针都可以)
      • 向量p0Q和p0p1叉乘,得到的结果值是z的正负,使用右手定则,可以得到Q在p0p1左边还是右边
      • 对p0p1, p1p2, p2p0 都进行叉乘计算,只有三个同正或同负(同在每条边的左边、或右边),才是在三角形内部
    • Bounding Box 使用轴向包围盒(AABB)降低判断次数
      图形_GAMES101/202学习笔记_第15张图片
    • 扫描线算法
      图形_GAMES101/202学习笔记_第16张图片
  • 锯齿
    • 锯齿是源于屏幕像素对图像采样后,决定选择像素,或丢掉像素导致像素画出的图形和原图像有偏差。
      对图像进行模糊(滤波)操作后再采样,可以抗锯齿。
      图形_GAMES101/202学习笔记_第17张图片
      对图像先采样再模糊不行。原因是:先进行模糊会截掉图像对应频谱的边缘部分,使频谱取样时不容易重叠,重叠会导致走样。
    • MSAA(超级采样):在软件层将一个像素分成若干个小像素点,以扩大采样点的方式,达到反走样近似。
      图形_GAMES101/202学习笔记_第18张图片
      图中将每个像素分成4个小像素,分别判断4个小像素是否在三角形内,最终以 三角形内像素/4 的比例,乘原像素颜色得到新的颜色。
      其实就是模糊操作
    • FXAA:先采样,得到锯齿后,通过图像匹配算法找到边界,把锯齿边界换成无锯齿的边界(区别于先采样后模糊这种不可行的做法)

2. 着色

2.1 简单光照模型

  • 自发光
    图形_GAMES101/202学习笔记_第19张图片

  • 漫反射:兰伯特
    图形_GAMES101/202学习笔记_第20张图片

  • 高光反射:Blinn Phong
    图形_GAMES101/202学习笔记_第21张图片
    半程向量用 V和L的归一化向量来求:H = (V.normalize() + L.normalize()).normalize()

2.2 纹理着色

图形_GAMES101/202学习笔记_第22张图片
计算uv,传到texture,获取texture color,替换漫反射中的kd项
以三角形为单位,3D模型的三角形映射到纹理展开后的位置,其中映射关系由美术提供,默认已经有对应的映射关系。
展开后的纹理坐标系为UV,U轴和V轴的范围都在[0, 1]

  • 纹理太小的问题(分辨率小,缺失细节)
    • 多个像素都采样到同一个纹素,导致一整片像素都取同一个点,成块状
    • 采样纹素时会得到非整数值,非整数时采样点如果取离点最近的纹素,会导致一整片像素都取到同一个点
  • 纹理太大的问题(分辨率大,细节多)
    • 像素采样的纹理太过离散,不连续,会有锯齿或摩尔纹
    • 透视投影导致近大远小,对于绘画远处的像素点,一个像素点会覆盖比较大范围的纹理,而这个像素通过点查询的纹理并不能代表这个范围内的纹理值
  • 点查询纹理 Point Query:返回一个像素点对应的纹理值
    • Bilinear 双向线性插值:取相邻的四个纹素根据位置进行插值
      图形_GAMES101/202学习笔记_第23张图片

      找临近的纹素的四个中心点,已知四中心点和红点的坐标,根据坐标位置,在u00 - u10 和u01-u11进行一次横向插值,得到u0,u1,再u0-u1 进行一次竖向插值。

    • Bicubic 双向三次线性插值:取相邻16个纹素

  • 范围查询纹理 Range Query:返回一个像素区域内覆盖的纹理的平均值
  • MipMap:近似的正方形的范围查询
    图形_GAMES101/202学习笔记_第24张图片
    提前生成一个纹理金字塔,每次生成的新的纹理的分辨率是上一次的一半。总共会增加三分一的空间。
    • 求一个屏幕像素范围内的纹理
      图形_GAMES101/202学习笔记_第25张图片
      取目标像素周围的两个临近像素,分别把三个像素的中心点映射到纹理上的位置,在UV空间中连接着几个点,算出一个像素单位对应在纹理空间内的长度L,当L等于1时,代表一个像素即对应一个纹素,直接取这个纹素的值就是像素覆盖面积的平均值,当第0层的长度为L时,在mipmap的Log2L层就能得到一个像素对应一个纹素。
      这样离得近的物体,要在mipmap的低层查询,才能得到更多细节,离得远的物体,在mipmap的高层查询。
      如果只在0层、1层、2层这样查,会有不连续的问题。因为Log2L不一定是整数。
      这里继续使用插值,可以在两层纹理中插值查,可以得到一个连续的数据。
      三线性插值:先在上一层和下一层进行双线性插值,得到在两个层各自的纹理数据,再两个层之间进行插值。
      图形_GAMES101/202学习笔记_第26张图片
  • 各项异性过滤
    mipmap仅能算正方形区域,会出现像素区域转为纹理空间的区域并非正方形,而是奇怪的长方形。而这时如果采用mipmap(正方形)来求平均,会额外带入更大的范围,导致模糊过度。
    图形_GAMES101/202学习笔记_第27张图片
    • 比起mipmap(只存储对角线纹理),多存储了横向的只有宽度变化的矩形纹理、纵向的只有高度变化的矩形纹理。
      比mipmap更精确一点,同时储存面积变为增大3倍(mipmap是1/3)
      图形_GAMES101/202学习笔记_第28张图片

2.3 三角形重心坐标求插值

  • 重心坐标:三角形组成的平面内任意一个点(x, y),都可以表示成三个顶点ABC坐标的线性组合
    图形_GAMES101/202学习笔记_第29张图片
  • 三个分量的计算方法:根据面积来算
    图形_GAMES101/202学习笔记_第30张图片
  • 三个分量的计算方法之二:根据ABC顶点的坐标来算
    图形_GAMES101/202学习笔记_第31张图片
  • 三角形重心的重心坐标:1/3,1/3,1/3、均匀三等分
    图形_GAMES101/202学习笔记_第32张图片
  • 重心坐标三维空间插值
    图形_GAMES101/202学习笔记_第33张图片
    重心坐标在投影前算出的α、β、γ,和投影后算出的是不一致的。
    已知三个顶点上的颜色、深度、法线等等信息,可以先通过ABC坐标和V坐标求出v点的重心坐标参数α、β、γ,再结合ABC点的图形参数插值算v点的图形参数
    重心坐标也可以用来计算纹理,纹理的uv坐标只映射了三角形的顶点坐标,三角形内的每个点的纹理(颜色)需要插值算,这个纹理也是光照模型中的Kd参数。

3. 光线追踪概述

4. 光线传播方法概述

5. 实时阴影

5.1 ShadowMapping

  • 原理
    两个Pass
    图形_GAMES101/202学习笔记_第34张图片
    • Render from Light,从光源方向出发,通过纹理像素看向场景内的物体,记录每个像素中离光源最近的距离,输出到深度纹理 ShadowMap
    • Project to light for shadow,从相机角度出发,看到的每一个点,和光源连线计算深度,再和深度纹理比较,相对较远说明被遮挡了,在阴影中。相对较近的,说明没被遮挡,无阴影。
  • ShadowMapping的问题
    • Self occlusion 自遮挡(Shadow Acne):因为ShadowMap是有分辨率限制的,并不能记录场景内每个点的深度值,而是一块纹理像素代表一个很小的区域的深度值,如下图,蓝线这个ShadowMap像素覆盖的区域,使用的是红色点的深度值,如果从相机出发时,取到的是黑色线段内的点,和光源连线做距离比较,黑色线段区域就是小于深度缓存的,是亮的,而另一段黄色区域则是大于深度缓存,是暗的,就会出现一段亮,一段暗的情况。
      图形_GAMES101/202学习笔记_第35张图片
      解决:(项目使用)增加bias的方式来解决这个问题,具体方式就是当一个点深度大于记录深度的值超过一个阈值时,我们才认为这个点在阴影内。但有个问题是,bias值大的话,在脚部区域的阴影可能会被错误的去除,看上去人是浮空的。
    • Aliasing 走样,因为ShadowMap的分辨率问题(也就是精度问题,画出来的影子是有锯齿的 图形_GAMES101/202学习笔记_第36张图片
  • Percentage Closer Soft Shadows(PCSS)软阴影
    图形_GAMES101/202学习笔记_第37张图片
    • 由PCF(Percentage Close Filtering)演变而来、优化阴影边缘的锯齿技术
      • PCF不是在ShadowMap的资源上进行Filter(平均),是在取到深度信息后的计算过程中进行Filter,它是不会改变ShadowMap的.
      • 在取到shadow point对应在ShadowMap上的像素时,在其周边多取几个像素的深度值来判断该shadow point的阴影情况,如3×3、5×5之类(也就是FilterSize),一般遮挡标记为1(阴影),非遮挡标记为0,相加后取平均,得到的值则为计算阴影时的系数。
    • PCSS
      i. 当PCF的FilterSize越小,如1×1,则阴影越硬、当FilterSize越大,则阴影越软。PCSS是对不同的被遮挡区域,采取不同的FilterSize来绘制阴影,达到软阴影的效果。
      ii. 面光源才有软阴影,平行光和点光是没有软阴影只有硬阴影,而面光源是无法生成ShadowMap的,是取面光源的中心点,按照点光源的方式生成的ShadowMap.
    • 如何计算FilterSize
      • 软、硬阴影和投射遮挡物深度(实际是取平均深度)与shadow point的距离相关,当dis越小,则阴影越硬(FilterSize越小,反之则阴影越软(FilterSize越大

      • FilterSize的计算
        图形_GAMES101/202学习笔记_第38张图片

        • W(penumbra)是阴影的半影区域,也就是软阴影区域,也可以理解为FilterSize的大小。
        • 其值由两个相似三角形计算,公式如下:
          取决于面光源大小、面光源到遮挡物(Blocker)的距离、Blocker到阴影接收点的距离。
          在这里插入图片描述
      • Blocker的深度计算:
        计算FilterSize的前提就是需要得到Blocker的位置,采取一块和shadow point相关的遮挡区域的平均深度(在ShadowMap中覆盖的像素的平均)来计算。
        ① 简单处理:自己规定一个区域,如5×5
        ② 将ShadowMap放置在Light计算深度贴图时定义的视锥的近平面,连接shadow point和Light,所覆盖的区域,就是Blocker搜索出来的区域
        图形_GAMES101/202学习笔记_第39张图片

      • 多光源只能一个一个处理,每一个光源进行一次ShadowMapping

      • PCSS比较耗的地方:

        • Blocker Search 和 Filter,这两步对于选出的区域,需要每个像素都循环处理过去
        • 解决:随机采样、降低循环次数、但会出现噪声 => 项目更愿意使用PCSS,因为解决噪声有成熟方案

5.2 Variance Soft Shadow Mapping (VSSM)

  • 通过一系列近似的操作和Mipmap,加速第一步Blocker Search和第三步Filter

  • 加速Filter:

    • Filter的目的是想计算选出来的深度区域、和shadow point做比较后,被遮挡的比例是多少,求一个系数
    • 可以使用一个正态分布去近似这个比例,不需要特别精准
      图形_GAMES101/202学习笔记_第40张图片
    • 计算正态分布需要均值和方差
      • Mean 均值,求一个区域的平均值,可以用Mipmap很快的取到、但是Mipmap只能做方形

      • 更精准的数据结构:Summed Area Tables(SAT),支持任意矩形

      • Variance 方差,用一个和均值相关的函数求得
        在这里插入图片描述
        但原先的ShadowMap只能取到depth做均值的平方(也就是第二项,没法直接取到depth平方做均值(第一项
        所以这里用原先深度贴图的一个通道,来储存depth平方(square depth map)
        因为depth只需要一个RGBA中的一个通道储存即可,所以不需要另外存一张贴图

      • 当得到均值和方差后,构建正态分布函数,取遮挡的比例,其实也就是取CDF的面积(即x左边的区域面积)
        图形_GAMES101/202学习笔记_第41张图片
        算CDF面积:
        ① 数学上可以把积分面积做成一张表,提供查询
        ② 没有解析解,有数值解

      • 因为上述面积太难算,该方案用一个Chebychev不等式,来近似的求得面积
        该不等式表明,从t开始往右的面积,是一定会小于右边的这块计算。
        这里将小于等于,直接当作是约等于,即t往右的面积,可以通过均值、方差和t组成的这个算式求得
        该不等式还有个规定是 t需要在均值的右边、如果t在均值左边,则算出来的值不准,不过这里也忽略了这个规则。大致准确即可。
        这样即可绕过正态分布的计算,通过一个近似的式子来计算
        图形_GAMES101/202学习笔记_第42张图片

      • 整个加速过程总结:

        • 生成depth map的同时生成 square depth map以及Mipmap,注:Mipmap是在GPU上生成的,而且GPU生成一张Mipmap的速度非常快,可以不考虑消耗
        • 运行时的消耗情况:
          都是O(1)级别,并且不需要采样和循环
  • 加速Blocker Search

    • Blocker Search计算的其实是depth map上的一块区域内,遮挡物所在像素的平均深度(区别于Filter的整块区域平均)
      也就是下图蓝色的区域,假如shadow point的深度是7,则蓝色区域都是比7更近的,会遮挡的
      图形_GAMES101/202学习笔记_第43张图片

    • 定义三个深度

      • 整块区域的平均深度,Z(avg),从Mipmap取

      • 遮挡区域和非遮挡区域的各自平均深度
        我们需要求得就是Z(occ),遮挡物平均深度
        在这里插入图片描述

      • 深度公式满足
        在这里插入图片描述

        这里的N是所有的像素个数、N1是非遮挡物像素、N2是遮挡物像素个数
        N1/N表示的非遮挡物所占比例,以及N2/N的比例,都可以通过之前的Chebychev不等式来求
        然后假设Z(unocc),非遮挡物的深度值等于shadow point的深度值7
        即可求得最终Z(occ)的值

5.3 MipMap and Summed-Area-Table VSSM

  • MipMap:结果不精准

    • MipMap的特性,方形,不支持任意矩形区域查询
    • 假如查询的区域,并不是刚好从MipMap的某一块区域的起点开始,而是从中间开始,横跨多块区域,则要做插值,就可能不准
    • 如果边长不是2的次方,需要通过三线性插值来算
      图形_GAMES101/202学习笔记_第44张图片
  • SAT - Summed Area Table(数据结构):结果精准

    • 一维
      图形_GAMES101/202学习笔记_第45张图片
      预处理,多开辟O(n)空间,并且先花O(n)时间把Input转化为SAT
      Input表示原数组
      SAT表示原数组从左边开始往右加,每多加一个元素后的总和的值
      如果想取到中间的某几个元素的合,可以通过SAT中的元素相减得到,如20-9=11可以得到Input中第4、5、6项的合
    • 二维
      图形_GAMES101/202学习笔记_第46张图片
      通过预计算得到一个二维数组,每个元素即从原点到当前元素所有累加的合
      通过SAT的元素相减,可以取到任意某一块区域的大小

5.4 Moment Shadow Mapping

  • VSSM的问题:
    • 做了太多的假设,当遮挡物的几何分布不符合正态分布时,PCF算不准,阴影里可能有部分变暗,有部分变亮(亮的部分感官问题很大
      左边没问题,右边有问题
      图形_GAMES101/202学习笔记_第47张图片

    • 不等式也可能不准

  • Moment Shadow Mapping解决的是VSSM计算分布不准确的问题
    多记录depth的三次方、四次方,用高阶函数去模拟分布
    用4阶数据即可很好的模拟PCF的正确结果
    图形_GAMES101/202学习笔记_第48张图片
    c. 对比结果
    图形_GAMES101/202学习笔记_第49张图片

5.5 Distance Field Soft Shadows

6. 实时光照

6.1 [RSM] Reflective Shadow Maps

  • 通过Shadow Map把场景离散化,Shadow Map上的每一个像素,作为一个接收直接光照的Area Shading Point,再根据这个Shading Point计算接收间接光的point P的影响。

  • 在不加速的情况下,算法复杂度和Shadow Map的分辨率相关,为O(n*n)

  • 因为不知道Shading point的光照出射方向,所以假设Shading point都是Diffuse漫反射材质。(知道光源入射方向和观察方向才可以算Shading,在这里Shading point q是次级光源,观察方向是p->q)

  • 计算:
    图形_GAMES101/202学习笔记_第50张图片

  • 把对接收点立体角的积分转换为光源面积的积分
    a. Li(q->p) q->p辐射的Radiance
    b. V(p, wi) q->p的visibility情况,RSM这里假设都无遮挡
    c. Fr(p, q->p, w0) BRDF项

  • 求Li(q->p)
    图形_GAMES101/202学习笔记_第51张图片
    a. Fr是diffuse的BRDF计算
    b. Li是出射的Radiance,其计算为:出射Radiance / 入射的Irradiance = BRDF
    c. 入射的Irradiance = flux / dA

  • 找离得近的次级光源,而不是计算所有的次级光源
    把p点投影回Shadow map,在Shadow map中离得近,就假设其在三维空间也离得近
    图形_GAMES101/202学习笔记_第52张图片

  • Shadow map的存储
    图形_GAMES101/202学习笔记_第53张图片

    a. Depth 深度
    b. World Coordinate 世界坐标,用来判断实际两个点的距离
    c. Normal 法线,用于算COS项
    d. Flux

  • 存在的问题
    a. Shadow map的问题这里都有(和光源数量相关
    b. 不检查次级光源的可见性
    c. 过多的假设:次级光源都由diffuse物体发出、加速采样时采用Shadow map代替distance

6.2 [LPV] Light Propagation Volumes

  • 解决问题: 在Shading Point能直接取到所有次级光源输出给它的间接光照的Radiance
  • 解决思路:
    • 把场景分为若干3D的格子(用三维纹理存储),这些格子用来传播间接光照的Radiance

    • 通过RSM计算接收直接光的Shader Point,也就是次级光源,以这些point为起点,往周围六个面传播Radiance

    • 初始值:
      每个格子中生成的朝任意方向传播的Radiance分布,用二阶的SH压缩
      图形_GAMES101/202学习笔记_第54张图片

    • 传播:往六个面传播的Radiance,直接加到那个面上
      图形_GAMES101/202学习笔记_第55张图片

    • 存在问题:

      P无法照亮右边的点,但是因为这两个在同一个格子内,所以P点发出的间接光Radiance也是右侧点的Radiance(其实是整个格子的Radiance),会导致本不该被间接光照亮的地方变亮。
      当几何粒度比划分的格子小时会出现该问题

6.3 [VXGI] Voxel Global Illumination

6.4 [SSAO]Screen Space Ambient Occlusion

屏幕空间环境光

  • SSAO

    • 在屏幕空间上,依据屏幕上的数据,模拟全局光照(模拟间接光)
    • 假设每个point接收到的间接光都是一样的,是一个常数
    • 但是考虑visibility项,即不是每个point都能接收到间接光,每个point有不同的visibility
      图形_GAMES101/202学习笔记_第56张图片
      如果不考虑遮挡,也就是左图的Phong模型,每个shading point都加一个相同的间接光强度)
  • AO的数学原理
    图形_GAMES101/202学习笔记_第57张图片
    把渲染方程中的Visibility项根据“RTR equation”拆出来,得到下面的式子
    图形_GAMES101/202学习笔记_第58张图片

    • 蓝色框(kA)代表单独的visibility项 => shading point看向半球时的visibility的加权平均
    • 橙色框代表间接光照的Radiance输入:前述AO假设为常数
      BRDF计算,diffuse材质,也是常数
    • 两项相乘得到该point的间接光照
      图形_GAMES101/202学习笔记_第59张图片
      cosθ×dwi => Projected Solid Angle,符合拆分方程的定义
      且对cosθ×dwi的积分就等于pi
  • 基于射线的遮挡计算
    图形_GAMES101/202学习笔记_第60张图片Shading point在法线所在的半球方向上发射射线,记录打到障碍物的比例

  • SSAO的遮挡计算
    图形_GAMES101/202学习笔记_第61张图片

    • 在屏幕上以Shading point为圆心、半径R的球内随机取一些点,将这些点转换到相机空间内,然后对比之前渲染场景时记录的深度值,深度值更深的点则认为是由Shading point出发会被挡住的点。
    • 有一点小问题就是上图中的第二个圆,其中有一个点按这个方法会判断错误。
      图形_GAMES101/202学习笔记_第62张图片
      计算Visibility项只考虑在法线方向上的半球,如果有法线信息,则计算该半球上绿点(不被遮挡的点)占所有采样点的比例,就是Visibility的值
      如果没有法线信息:
      当红球数量超过采样点一半的时候,说明半球上存在遮挡的可能性,然后计算绿点占一半采样点的比例,就是Visibility的值
  • SSAO的问题
    图形_GAMES101/202学习笔记_第63张图片
    错误的认为凳子和地板有接触

  • 采样的频率
    图形_GAMES101/202学习笔记_第64张图片
    用少量的采样,再加模糊

6.5 [SSDO]Screen Space Directional Occlusion

  • 基于SSAO,对SSAO假设间接光照都相同做出的改进

  • SSDO增加了间接光的ColorBlend,而不只是SSAO中的黑白灰
    图形_GAMES101/202学习笔记_第65张图片
    第二行最后一图,SSDO有Bounce的情况下,黄色物体对蓝色物体的间接光是呈黄色

  • SSDO和SSAO思路上的区别
    图形_GAMES101/202学习笔记_第66张图片

    • SSAO认为,会被射线打中的部分是被遮挡的,这部分不会产生间接光,而间接光是来源于没打中障碍的那部分射线
    • SSDO认为,没打中障碍的那部分射线是直接光的来源,而间接光是来源于射线打中的那部分遮挡所产生的间接光
    • 原因是SSAO认为间接光是来源于较远距离外的部分,而SSDO认为间接光是来源于较近距离的部分。
  • 遮挡计算
    图形_GAMES101/202学习笔记_第67张图片

    • 在Shading point P的法线方向半球采样
    • SSDO假设P点到采样点的遮挡关系,就是从Camera出发到采样点是否被遮挡,这样通过采样点转化到相机空间,再计算深度值,得出遮挡关系。
    • 得到遮挡关系后,计算这个点对于点P的间接光的影响
    • 存在的问题:图2的A点和图3的A点其实都是无法对P点有间接光影响的,但是在该方法下,都会产生影响
  • 存在的问题

    • 小范围的间接光照
    • 从相机出发的遮挡关系计算不准确
    • 最大的问题,由于是基于屏幕信息做的间接光模拟,无法得知面背后的信息
      图形_GAMES101/202学习笔记_第68张图片
      当出现如图3、4这样的情况,屏幕信息并不知道黄色物体背面的信息,就无法得出间接光模拟

6.6 [SSR]Screen Space Reflection

屏幕空间反射:在屏幕空间做光线追踪
图形_GAMES101/202学习笔记_第69张图片

  • 思路
    图形_GAMES101/202学习笔记_第70张图片
    • 由相机方向往场景内打射线,打到后反射到场景的壳上,求交点
      通过一段一段的步长递进,比较步长点和场景深度,当发现有一个递进的步长点在场景内部时(深度比较),即产生了交点。
    • 步长的规则:动态步长
      • 生成Depth Mipmap,不同于常规的Mipmap,这里每一层Mipmap不使用上一层4个格的平均值,而是用最小值(记录最小深度)
        Eg. Mipmap每一层边长是上一层的一半
        图形_GAMES101/202学习笔记_第71张图片

      • 步进思路(Hierarchical Tracing)
        从最低层Mipmap的深度精度开始移动射线,如果射线和最低深度没有交点,下一次步进增加一层Mipmap(即增大步长),如果和当层的最低深度发生交点,则需要回退到上一层精度,并且判断是在回退后的哪一部分(在下图里就是左格还是右格),从包含交点的那部分,在回退后的Mipmap精度上再计算一次,回到最初增加Mipmap层级的那个逻辑继续计算。直到在最低层Mipmap计算到相交则停止。或者光线出屏幕。
        图形_GAMES101/202学习笔记_第72张图片

参考资料

GAMES101
GAMES202

你可能感兴趣的:(图形,图形学)