shadowmap阴影的原理:
判断顶点距离光源的位置,如果是最近的,那么顶点不会有阴影覆盖。否则,顶点被阴影覆盖。
所以,首先判断顶点到光源的位置。就要先获得离光源最近的片段的深度。
于是,深度图来了。深度图就渲染到纹理吧,这里就用到FBO了,这个我就不细说了。
透视投影变换可以得到3D到2D的图像,变换的最终结果是vec4 Final = Projection * View * Model * Vertex;
Vertex 顶点本来就是vec4(vec4(x,y,z,w))。而Direction 方向是vec3。
经过Perspective透视变换后,x/w,y/w,z/w。都会在[-1,1]这个范围内。
Perspective(fovy,ratio,znear,zfar)这个函数得到的深度值z/w的增长不是线性的。离znear越近深度值z/w越精确。
在视景锥空间内,当顶点到摄像机的距离刚好为znear,深度z/w为0。当顶点到摄像机的距离为zfar,深度z/w为1。
但由于不是线性的,深度值会越来越不准确。所以我们要实现一个线性的深度,写个shader。
主要的就是float depth =distance(CameraPostion.xyz,WorldPos.xyz);
CameraPostion为光源的位置,因为我们计算的是进过世界坐标变换后的顶点的位置到光源的位置。depth 就是两者之间的距离。
另外一点是,OpenGL的Texture采样的话 vec4 color = texture(sampler2D,texcoord);得到的vec4总是在0.0到1.0的颜色空间范围。