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

导读: 十分清晰易懂的辐射度和光照图的文章,不过依赖于D3D的部分接口.同时没有包括光照图生成的内容
  
  
  
  对于一个3D场景光照是加强真实感的重要因素, 目前来说大概可以分为静态光照和动态光照.在这里我们主要讨论的是静态光照. 静态光照的好处很多, 比如: 渲染速度快, 效果好, 可以逐象素的计算光照和阴影.缺点就是光照的效果是静态的, 并且其需要一定的预处理时间. 我把这篇文章分为两部分, 上部分为计算光照贴图, 下部分为计算辐照度.
  
  首先我们来看上半部分,也就是如何计算光照贴图, 这里有一篇文章讲的很清楚,大家可以去看具体的算法我就不细说了.
  
  其大概可以分为以下几个步骤:
  1. 生成光照贴图的UV坐标. 这本身就是一个很复杂的问题, 但实际上我们可以跳过这个问题, 我们可以用3dsmax来展UV, 这是一个手工活, 虽然加大了一些工作量,但是它可以保证贴图的利用率, 并且不用写一行代码.
  2. 我们需要根据光照贴图的所有有效的象素的UV坐标, 得到其在世界空间的坐标.这个算法在上面的文章里有, 但并不是很完整, 在我的源码(LightMapping.cpp)里大家可以看到这个算法的完整实现.
  3. 为每个有效象素计算光照, 这个可以参照Direct3D里的光照公式. 至于阴影, 我用的是射线追踪, 从光源对目的点引一条直线判断其是否被遮挡, 如果是则其为阴影, 否则其为计算出来的光照值.
  4. 填充无效的象素. 由于我们对光照贴图的采样方式为线性采样(D3DTEXF_LINEAR), 因此其会读取到周围8个邻居象素的值, 因此我们把所有效象素的8个邻居的象素值做一下线性采样, 这样最后就不会出现黑边.
  5. 柔化光照贴图, 因为上面计算出来的光照图会产生很硬的边, 如果对其做一下线性采样, 这样就不会太硬.最后就是渲染出来啦.
  
  下面是计算光照图后的效果图:
  
  下面是经过柔化的效果图:
  
  我们看上面的场景, 大家会发现除了受光照的地方其它地方都太黑, 一般来说我们可以给它加上环境光来解决这个问题, 但是其带来的结果就是颜色太平, 因为所有黑的地方都是一个颜色, 而真实世界不可能是这个样子, 对于真实世界中不仅仅只有光源能发光, 每一个表面都能散射光, 对于上面的场景被照亮的区域再向周围散射光能, 这样一次次进行下去直到每整个屋子都被照亮,这就是这篇文章的下部分: 辐照度.
  
  关于辐照度这里也有一篇文章供大家参考具的算法我也不细说了,.其太致的思想就是, 把场景的的表面分为一个个小patch, 而对于我们来说这个小patch对应的就是光照图的一个象素. 然后把眼睛放到这个小patch上, 在从这个patch表面的法向方向观看场景. 这个过程我们可以通过D3D9的ID3DXRenderToEnvMap这个接口的BeginHemiSphere来实现,.它可以把场景渲染到一个半球体上.(这里我有一个疑惑, BeginHemiSphere
  这个函数是接收两个参数, 第一个为: IDirect3DTexture9* pTexZPos,
  第二个为: IDirect3DTexture9* pTexZNeg.
  但最后我渲出的前半球的场景在pTexZNeg内里?).
  
  因为越面向法向的象素其接收的光能应该越大, 并且要修正投影变换带来的负面影响, 我们需要把渲染出来的场景图乘上光能衰减图来纠正最后的结果.最后, 我们把场景图的颜色值加起来并归一化, 这就是这个象素的接收的辐射光能, 把它加上原来的颜色值就可以了, 当然这个辐射过程可能需要很多次才能达到比较好的效果.
  
  关于这个算法它有一个缺点就是太慢, 我要根据上面那篇介绍辐射度的文章介绍的方法对其进行了优化, 具体的可以参考原文和我的源码.
  
  对上面场景应用了12次辐射后的效果图如下:
  对上面场景应用了16次辐射后的效果图如下:
  
  如果大家有更好的想法或者什么疑惑可以给我发邮件. godmangj@126.com.
  
  该文章的源代码: radiosity_src.rar. (需要DXSDK_Feb_2006, 工程项目为Visual Studio.Net 2003)

本文转自
http://www.ynuit.com/print.asp?articleid=1380
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值