Games202 - 作业1~3

记录写作业时的思考

Posted Kongouuu's Blog on October 26, 2021

作业1 阴影

硬阴影

计算出light mvp,让我们可以对比物体和shadow map记录的深度来进行遮挡计算。需要进行偏移计算,偏移可以通过入射光角度和法线进行计算来得到一个目标的偏移)

PCF计算

随机采样目标pixel附近的深度值和当前进行对比来计算visibility。

filter size根据shadow map的分辨率而定,如果阴影不够软可以增加(0~10倍)。

噪音特别严重,如果采用单一的采样核会减少,但阴影感觉会分层。

PCSS计算

PCSS的本质就是根据和遮挡物的距离去计算PCF filter的大小,如果跟遮挡物很靠近,那么我filter的圈子就小(阴影更硬)

和遮挡物的距离是取平均值,一样是通过随机的偏移核从阴影图找附近的像素, 要注意的是无遮挡和完全遮挡的话要额外标注比较合适。

找到遮挡物的平均深度之后可以自行设定什么时候硬什么时候软就可以得到基础的pcss

作业2 SH

[稍后补上]

作业3 SSR

第一部分 直接光照

第一部分的要求是完成一个简单的直接光照模型,这里要求完成两个函数: EvalDiffuse, EvalDirectionalLight

EvalDiffuse这里只需要按照Lambert Diffuse的办法把这个物体的BRDF(fr)给写出来就可以了。实际上diffuse模型就是单纯的拿底色罢了,就是从Diffuse Map下来的。如果考虑PBR里面的也就是拿底色除以PI,这是为了能量守恒。 当然作业这里在函数输入上多加了入射光和出射光的值,并且让我们找normal。 所以比起直接的返还一个BRDF值,我们需要把渲染方程内的cos一并给计算了。

EvalDirectionalLight这里就简单了,单纯的把给的光强Li加上Visibility就能算出来了,这部分就是直接光照。

我自己的作业里的兰伯特漫反射没用除以PI,这样看起来比较亮,我也不确定哪个是对的。

第二部分Ray Marching

光线追踪在这部分写的稍微简单,这里是使用给定的随机向量(根据法线生成的),来在深度图上进行一个光线的追踪。实际办法我这里是一个一个steps的走,没用去优化速度。每走一个step就去对比。我目前这个光线所在的点跟深度图是否有相交【相交判定为深度差不多,而不是光线深度大于深度图的遮挡物,这样计算是因为我没有进行hierarchy search去精确的找到碰撞点,所有以精准为主】

简单来说就是每走一步,算出目前的深度,和深度图对比,如果我碰到了深度图的遮挡物,那么我就返回

第三部分 间接光照计算

上面那个就是我们在计算直接光照时使用的渲染方程。 我们计算间接光照其实是使用一个完全相同的手段。在进行渲染方程的时候,我们实际上算出来的Lo(wo),就是面向我们眼睛这个立体角wo的光照能量。

间接光照是完全一样的,我们把被当作间接光源的点p’,当成我们的光源,然后使用那个点计算出打向我们的目标像素点p的光照值当作渲染方程的Li输入,加到之前计算好的直接光照值就可以了。下面我们来看一下本次作业的伪代码。

伪代码中的23就是在计算渲染方程的Li输入,这个时候的wi(光源输入角度)就是间接光源点p’到目标像素p的向量。我们通过23就能计算出位于目标点的渲染方程光照值。然后我们把这个光照值和向量,乘上1就可以完成间接光源到目标像素的渲染方程。

所以要注意的是在1的部分,wi就是我们选取的随机向量,wo为眼睛。

在23的部分,wi为光源,wo为我们选取的随机向量。

pdf要稍后考虑。

漏光

这个间接光照是一个屏幕空间的算法,也就是通过屏幕空间所储存的diffuse,depth,shadow来计算的。这样的一个坏处就是会有漏光,比如下图:

我们可以看到方块左下角有很严重的漏光,我这里标注了三个点: p为地面的目标像素, b为给p提供简介光照的点, f为有实际接受光照的表面。

这里b实际上是没用得到任何光照的点,应该是个阴影,但是他为给点p提供了不该有的光照。这里是因为在判断光源相交的时候把有接受到光源的表面f认成了b,因为在二维的深度图里面两者共享同一个坐标。当然,漏光也可以通过限制检测碰撞的深度差来解决

  1. Ray March的时候判定只有深度差别小的点能返回true
  2. Ray March返回结果后跟深度图对比我打到的点,去判断是否相近,选择性丢弃光照值。

解决后长这个样子:

image-20211027154737361