原理:shadow map过程
- 要创建一张 纹理。
- 把摄像机放在光源的位置
- 把渲染结果绑定在纹理上(RTT)
- 把要产生阴影的物体渲染一边,只渲染深度信息,不渲染颜色信息。
- 有两种办法
- 把需要接受阴影的物体传进这种纹理。渲染的时候加一段判断代码
- 做个贴花
可以看看这个:Theory里有详细的介绍
http://devmaster.net/posts/shader-effects-shadow-mapping
只是viewport大小就很不错了,再配上高斯模糊。我简单说一下
黑色是地形,红色是个球,黄色是光源。我们要在地形上画阴影。那就需要在 frag_shader 里知道每个像素点,哪个地方是被挡住的。如果被挡住,这个点就画成 最终输出颜色 = 阴影颜色*90% + 原本的颜色*10%(随便写个公式)。关键是如何判断被挡住。
图解
用深度信息来判断:
首先我们要在 光源的视角画出这个地形的深度信息,然后把 这个深度信息 z 和 之前准备的深度图同一个位置的 z 做比较:
if ( 地形像素z > 深度图z ){
说明,有一个物体的z 比地形的z小,说明这个物体把地形挡住了,所以地形上这个像素应该有阴影;
}
else{
如果没有被挡住,说明 地形像素的z 是离光源最近,且未被遮挡的
}
所以我们要把所有 产生阴影的 物体画在深度图上
深绿色 是那个光源位置 看到的球 , z比较小。
浅绿色是地形的z,比较大, 其他白色区域表示 z最大。(如果地形不产生阴影,其实把全部地形产生阴影,速度不快,对现在来说没必要!!浅绿色就应该是白色的,也就是最大的z),完成。物体要接受阴影,得改物体渲染,地形要有阴影,地形渲染就得改。深度图不难画,难在怎么渲染阴影上,因为不改的话,用固定管线我不会做。
例子
以画地形为例,也就是用光源视角总深度图A ,和地形的深度图B。
AB的 view_matrix 都是光源的,通过 AB 比较判断阴影区域,最后画在画面上的地形是 C, C是就是普通渲染。 用的 view_matrix 是camera的。
A要先画一边,把所有dem,模型都画上,画在一张图片上。画的方式得新写,因为渲染只写入深度信息, 输出是 32位float,不是rgb。BC同时进行。画出B后直接跟A(通过一张纹理传入)比较。用原来的办法话C,然后得到结果,通过结果来计算C。C老的渲染方式来渲得到的结果 是rgb,再通过阴影的参数做些变化,最终输出颜色。
http://www.gamerendering.com/category/shadows/shadow-mapping/