完整资源:
前情提要:
从0开始编写minecraft光影包(0)GLSL,坐标系,光影包结构介绍
前言
在当了n天的懒狗之后,还是 掘腚 决定填一下坑。。今天来完成咱光影包的第一个特效,也是最基础的特效–阴影绘制
阴影实现原理
众所周知,光照到物体上会反射,而光被物体挡住,物体遮蔽的部分就会呈现暗色,这就是阴影。
如图所示:
dbq放错图了。。
已知一个点 P,光源为 O 点 ,如何判断 P 点是否落在阴影中呢?
这里有一个很简单的方法:比较 P点到光源的距离 和 PO连线上离光源最近的实体点到光源的距离
假设
- P 点到光源的距离 = s1
- PO 连线上离光源最近的实体点到光源的距离 = s2
如果 s1 > s2 则说明 P 点在阴影中
如图:因为同一直线上,有别的点离光源更近,说明P点被覆盖,故 P 在阴影中。
P点在阴影中,那么我们直接将其涂黑就好了。难点在于如何获取P点到光源的距离
P点到光源的距离
已知一个点 P,光源为 O 点
已知 P 点,要看 P 点是否需要被涂黑,需要计算P点到光源的距离。
在 “太阳的屏幕坐标系” 下,z轴(即深度通道)为该点到太阳的距离。可是我们只知道 P 点在屏幕坐标系中的位置,而如何知道 P 点在 “太阳的屏幕坐标系” 下的位置?
好在 shadermod 提供了变换矩阵作为可用变量。下面给出四个可用的变换矩阵:
uniform mat4 shadowModelView;
uniform mat4 shadowModelViewInverse;
uniform mat4 shadowProjection;
uniform mat4 shadowProjectionInverse;
值得注意的是,太阳视角下的坐标系,并非opengl的默认坐标系,需要通过 “我的世界坐标” 转换而得到。
还记得 “我的世界坐标” 吗?上一篇博客提到过。即原点在摄像机处的世界坐标,原点随着摄像机移动而移动。
下面给出各种坐标和太阳视角下的坐标的转换关系: