首先我们来看上半部分,也就是如何计算光照贴图, 这里有一篇文章讲的很清楚,大家可以去看. http://www.flipcode.com/articles/article_lightmapping.shtml.具体的算法我就不细说了.
其大概可以分为以下几个步骤:
1. 生成光照贴图的UV坐标. 这本身就是一个很复杂的问题, 但实际上我们可以跳过这个问题, 我们可以用3dsmax来展UV, 这是一个手工活, 虽然加大了一些工作量,但是它可以保证贴图的利用率, 并且不用写一行代码.
2. 我们需要根据光照贴图的所有有效的象素的UV坐标, 得到其在世界空间的坐标.这个算法在上面的文章里有, 但并不是很完整, 在我的源码(LightMapping.cpp)里大家可以看到这个算法的完整实现.
3. 为每个有效象素计算光照, 这个可以参照Direct3D里的光照公式. 至于阴影, 我用的是射线追踪, 从光源对目的点引一条直线判断其是否被遮挡, 如果是则其为阴影, 否则其为计算出来的光照值.
4. 填充无效的象素. 由于我们对光照贴图的采样方式为线性采样(D3DTEXF_LINEAR), 因此其会读取到周围8个邻居象素的值, 因此我们把所有效象素的8个邻居的象素值做一下线性采样, 这样最后就不会出现黑边.
5. 柔化光照贴图, 因为上面计算出来的光照图会产生很硬的边, 如果对其做一下线性采样, 这样就不会太硬.最后就是渲染出来啦.
下面是计算光照图后的效果图:

