http://www.cs.virginia.edu/~gfx/courses/2004/Intro.Fall.04/handouts/06-light.pdf

光照贴图(Lightmapping)与辐照度(Radiosity)  

2008-05-23 08:44:13|  分类: 遊戲程序製作|字号 订阅

光照贴图 (Lightmapping) 与辐照度 (Radiosity)

                                                             作者龚静

                                                                                           日期: 2006-8-22

 

 

 

       对于一个3D场景光照是加强真实感的重要因素目前来说大概可以分为静态光照和动态光照.在这里我们主要讨论的是静态光照静态光照的好处很多比如渲染速度快效果好可以逐象素的计算光照和阴影.缺点就是光照的效果是静态的并且其需要一定的预处理时间我把这篇文章分为两部分上部分为计算光照贴图下部分为计算辐照度.

 

       首先我们来看上半部分,也就是如何计算光照贴图这里有一篇文章讲的很清楚,大家可以去看.http://www.flipcode.com/articles/article_lightmapping.shtml.具体的算法我就不细说了.

 

其大概可以分为以下几个步骤:

1.       生成光照贴图的UV坐标这本身就是一个很复杂的问题但实际上我们可以跳过这个问题我们可以用3dsmax来展UV, 这是一个手工活虽然加大了一些工作量,但是它可以保证贴图的利用率并且不用写一行代码.

2.       我们需要根据光照贴图的所有有效的象素的UV坐标得到其在世界空间的坐标.这个算法在上面的文章里有但并不是很完整在我的源码(LightMapping.cpp)里大家可以看到这个算法的完整实现.

3.       为每个有效象素计算光照这个可以参照Direct3D里的光照公式至于阴影我用的是射线追踪从光源对目的点引一条直线判断其是否被遮挡如果是则其为阴影否则其为计算出来的光照值.

4.       填充无效的象素由于我们对光照贴图的采样方式为线性采样(D3DTEXF_LINEAR), 因此其会读取到周围8个邻居象素的值因此我们把所有效象素的8个邻居的象素值做一下线性采样这样最后就不会出现黑边.

5.       柔化光照贴图因为上面计算出来的光照图会产生很硬的边如果对其做一下线性采样这样就不会太硬.最后就是渲染出来啦.

 

下面是计算光照图后的效果图:

光照贴图(Lightmapping)与辐照度(Radiosity) - hurst831028 - 小叶子的田地~

 

下面是经过柔化的效果图:

光照贴图(Lightmapping)与辐照度(Radiosity) - hurst831028 - 小叶子的田地~

 

我们看上面的场景大家会发现除了受光照的地方其它地方都太黑一般来说我们可以给它加上环境光来解决这个问题但是其带来的结果就是颜色太平因为所有黑的地方都是一个颜色而真实世界不可能是这个样子对于真实世界中不仅仅只有光源能发光每一个表面都能散射光对于上面的场景被照亮的区域再向周围散射光能这样一次次进行下去直到每整个屋子都被照亮,这就是这篇文章的下部分辐照度.

 

关于辐照度这里也有一篇文章供大家参考http://freespace.virgin.net/hugo.elias/radiosity/radiosity.htm具的算法我也不细说了,.其太致的思想就是把场景的的表面分为一个个小patch, 而对于我们来说这个小patch对应的就是光照图的一个象素然后把眼睛放到这个小patch在从这个patch表面的法向方向观看场景这个过程我们可以通过D3D9ID3DXRenderToEnvMap这个接口的BeginHemiSphere来实现,.它可以把场景渲染到一个半球体上.(这里我有一个疑惑, BeginHemiSphere

这个函数是接收两个参数,  第一个为: IDirect3DTexture9* pTexZPos,

第二个为: IDirect3DTexture9* pTexZNeg.

但最后我渲出的前半球的场景在pTexZNeg内里?).

 

       因为越面向法向的象素其接收的光能应该越大并且要修正投影变换带来的负面影响我们需要把渲染出来的场景图乘上光能衰减图来纠正最后的结果.最后我们把场景图的颜色值加起来并归一化这就是这个象素的接收的辐射光能把它加上原来的颜色值就可以了当然这个辐射过程可能需要很多次才能达到比较好的效果.

 

       关于这个算法它有一个缺点就是太慢我要根据上面那篇介绍辐射度的文章介绍的方法对其进行了优化具体的可以参考原文和我的源码.

 

       对上面场景应用了12次辐射后的效果图如下:

光照贴图(Lightmapping)与辐照度(Radiosity) - hurst831028 - 小叶子的田地~

       对上面场景应用了16次辐射后的效果图如下:

 

光照贴图(Lightmapping)与辐照度(Radiosity) - hurst831028 - 小叶子的田地~

如果大家有更好的想法或者什么疑惑可以给我发邮件godmangj@126.com .

 

该文章的源代码:  radiosity_src.rar. (需要DXSDK_Feb_2006, 工程项目为Visual Studio.Net 2003)

动行程序:        radiosity_bin.rar

       注意以上代码仅供大家个人学习或研究使用未经允许不能用于商业用途.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值