下图时webgl指南里面绘制阴影的主要步骤:
假设有这么一个场景
相机位置和光源位置的视角分别为(以下分别称相机视角、光源视角)
第一步
利用FBO(帧缓冲区对象)得到的在光源视角得到的深度信息。
比较简单,只是简单MVP变换,光栅化后把变换后的Z值写入R通道,由于三角形再正方形得前面,所以三角形范围的深度信息会覆盖正方形的深度信息。如果把第四个值改成1.0就可以得正方形和三角形得颜色都是红色(为了好理解),但是三角形偏暗一点,类似下图(假设值),可以改一下代码直接输出到颜色缓冲区看一下。
第二步
回到相机视角正常渲染,分别计算相机视角的MVP变换(28行,这个是要显示到屏幕的)和光源视角的MVP变换(29行,这里的变换和第一步的变化是一样的),前者通过gl_Position传到的片元着色器,后者通过Varying。
到了片元着色器,因为webgl的x、y再[-1,1],而图片的坐标在[0,1],如下图,所以需要通过42行转换一下
下面通过一个片元来解释一下:
假设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我也不清楚)。以此类推就可以算出那些片元在阴影中了。