webgl指南--绘制阴影的原理

523 阅读2分钟

下图时webgl指南里面绘制阴影的主要步骤:

2158122-20210628112926153-1279683547.png

假设有这么一个场景 2158122-20210628113527796-175386449.png

相机位置和光源位置的视角分别为(以下分别称相机视角、光源视角) 111.png

第一步

利用FBO(帧缓冲区对象)得到的在光源视角得到的深度信息。

2158122-20210628140110380-1902693540.png

比较简单,只是简单MVP变换,光栅化后把变换后的Z值写入R通道,由于三角形再正方形得前面,所以三角形范围的深度信息会覆盖正方形的深度信息。如果把第四个值改成1.0就可以得正方形和三角形得颜色都是红色(为了好理解),但是三角形偏暗一点,类似下图(假设值),可以改一下代码直接输出到颜色缓冲区看一下。

第二步

回到相机视角正常渲染,分别计算相机视角的MVP变换(28行,这个是要显示到屏幕的)和光源视角的MVP变换(29行,这里的变换和第一步的变化是一样的),前者通过gl_Position传到的片元着色器,后者通过Varying。

2158122-20210628141836877-1909939716.png

到了片元着色器,因为webgl的x、y再[-1,1],而图片的坐标在[0,1],如下图,所以需要通过42行转换一下

2.png

下面通过一个片元来解释一下:

假设P点刚好在三角形阴影的直角点。P点在光源视角的MVP变换(29行)下在经过坐标转换(42行)可以得到O点的坐标未[Xo,Yo,Zo]。经过前面的变换后O点的[Xo,Yo]和E点的[Xe,Ye]是相等的,所以可以通过O点的[Xo,Yo](43行)得到前面计算的E点的深度信息(44行,当时记录在了R通道)。假设P点在光源视角(O点)的深度值Zo = 0.7,而E点由于三角形在正方形的前面,深度信息记录的是三角形的深度值,假设是Ze = 0.5,由于Zo比Ze大,所以P点在阴影中(45行,至于为什么+0.05我也不清楚)。以此类推就可以算出那些片元在阴影中了。

2158122-20210628155009236-1045178261.png