65.9K
CodeProject 正在变化。 阅读更多。
Home

3D可视化入门、物理正确照明、下一步以及预计算照明模型的必要性

2009 年 4 月 20 日

CPOL

8分钟阅读

viewsIcon

19719

对游戏照明概念、其历史以及该领域的发展趋势进行的非常简单易懂的介绍

[本文是对游戏照明概念、其历史以及该领域发展趋势的非常简单易懂的介绍。]

在讨论实时3D图形中的照明模型时,不可能不提及John Carmack,他是Id Software的联合创始人,也是现代游戏行业的先驱之一。

1994年,Id Software发布了他们最成功的游戏之一:Doom,使用了Wolfenstein-3D引擎的先进版本。其最大的技术优势之一是更具沉浸感的伪3D环境、更好的图形和更自由的移动。

游戏本身非常棒,但3D环境实际上是一个以3D形式绘制的2D空间,缺乏真正的照明系统,正如您在以下截图中所见:

这两个问题在Id Software后来的发行版:Quake中得到了解决,Quake被认为是首批真正的3D电子游戏之一,也是首批使用预计算照明模型之一的游戏。

要有光

首先,快速看一下Quake的截图。

[给参与者的注释:]

与Doom的图片相比,第一个变化是这里的万物都是3D的。根本没有精灵,只有多边形、点和纹理。这至关重要,因为它使得第二个变化成为可能,即照明系统。请记住,精灵只是复制到屏幕上的图片,已经包含了它们的照明。这就是为什么它们与其他环境光照效果不佳的原因。与此不同,多边形和顶点可以包含属性来为照明引擎提供信息,如位置、方向等。

在截图中,您可以看到一个橙色的光源从右侧的门射入,照亮了中间的盒子和中间的角色。盒子还在地面上投下了阴影,墙壁上也有额外的阴影。总之,Quake拥有一个非常不错的照明模型,为游戏提供了更真实的照明,从而增强了沉浸感。让我们看看这一切是如何实现的...

顶点照明。对Quake来说足够吗?

3D照明模型最早的尝试之一就是所谓的顶点照明,这在nVidia的这篇文章中有很好的阐述。基本上,它计算构成3D模型的每个多边形每个顶点的受光量,并使用该光量来调节顶点的颜色,从而通过多边形插值颜色。

对于细节非常丰富的3D模型,其中顶点之间的距离很小,因此采样频率很高,它效果很好。但是,出于性能原因,3D游戏无法拥有无限的几何细节。1996年更是如此。下图显示了Quake使用的几何细节的近似程度。

如您所见,细节水平非常低。看看盒子投射到地面上的阴影。这是一个贯穿几何体的渐变,其中没有出现顶点,因此顶点照明无法保持该渐变。

即使是现在,也无法使用足够的几何细节来使顶点照明成为唯一的照明模型。

那么,现在怎么办?

答案是使用某种系统,允许我们在多边形的内点(而不仅仅是顶点)存储照明信息,而无需增加几何体的实际细节。将其想象成一个二维表格,其中包含数值,存储多边形每个内点接收到的光量。

现在很快就会出现一些问题。

  1. 该表格应该有多大?

    当然,这涉及到采样频率问题:我们进行的采样越多(每英寸点数,或其他),照明的细节就越多。

  2. 我们如何将多边形的内点与表格中的条目联系起来?

    稍后会看到。

  3. PC有空间容纳这么多信息吗?

    让我们为Quake做一个快速计算:每场景可能1000个多边形,照明表大小为32x32个样本,总共1024000个浮点数。这大约是4MB内存。

    如今,这看起来不算多,但请记住,Quake发布于1996年,当时典型的PC最好的是Intel 486或Pentium,时钟频率在66到133Mhz之间,系统内存可能为8MB或16MB。因此,将一半或四分之一的总可用内存用于照明是绝对不可行的。

  4. PC有足够的计算能力来处理这个照明系统吗?

    绝对没有。计算单个点的照明可能需要大量运算,而且每帧需要进行1024000次。

那么,这个该死的Quake是如何工作的?

这就是问题所在。像66Mhz的Pentium这样的PC如何实时处理所有这些照明和图形?

很简单,它做不到

如果你仔细想想,你会发现,虽然你可以在房间里自由移动,但灯光通常不会移动,在大多数情况下,物体也不会移动。那么,为什么不预先计算静态物体的照明一次,并将结果存储在某个地方呢?这就是Quake所做的。

它有一个关卡编辑器,允许你在场景中放置灯光,并离线计算环境的静态照明,将结果存储起来以备将来实时使用。

这节省了所有实时计算,解决了问题4的内存问题,但它没有解决问题3的内存问题,再次没有解释问题2。

问题2和3。场景中的光照贴图

看看存储关卡编辑器离线照明计算结果的照明表。等等……一个存储数值的2D表……嗯……我以前见过这个……数字图像或纹理与这些东西非常相似:2D数据表……而且……等等!如果我将这些结果存储在纹理或数字图像中,而不是简单的2D表……

是的,这就是关键。如果你将这些信息存储在纹理中,你可以:

  1. 使用压缩算法来减少所需的内存量。在许多地方,照明将非常相似,因此块打包和压缩将节省大量内存。这有助于解决问题3。
  2. 您已经有一个系统可以将多边形的内点与纹理的内容联系起来:纹理坐标。这解决了问题2。

没错。光照贴图是特殊的纹理,它们存储照明信息,而不是基础材质的外观。就像这张图一样。

它们在Quake中被广泛用于存储照明信息,并且是为您的3D引擎添加真实感的绝佳方式。自那时以来,光照贴图已成为任何现代3D应用程序的必备组件。

尽管有一些动态光照贴图的方法,但光照贴图通常只用于存储静态照明信息,之后与无法静态的其他类型的照明结合使用,用于移动灯光或对象:顶点照明、阴影贴图、阴影体积、顶点和像素着色器等。

纹理万岁!

一旦我们有了将3D物体表面上的点与纹理上的纹素关联起来的方法,我们就可以在纹理上存储任何类型的信息:凹凸、光泽、阴影、镜面反射分量等。

看看下面这个例子,取自此处(一篇非常好的着色文章)。这张图片属于《半条命》等游戏使用的Valve引擎

您可以看到,他们使用了一整套不同的纹理来存储表面信息的不同类型,获得了非常好的效果,正如《半条命2》中所见。

不要打破魔法

3D程序员自《毁灭战士》时代以来所从事的斗争,无非是为了真实感。换句话说,不要用奇怪或不准确的照明打破魔法。尽量做到准确,并关注使画面看起来逼真的细节。例如,看看这张图。

另一个例子

这些图片使用了非常简单的几何结构,几乎没有纹理……那么,是什么让它们如此逼真?

很简单……物理正确照明

照明是一切。它比我们在计算机图形学中可以使用的任何其他东西更能决定物体的外观。这些图像看起来逼真,因为它们使用了具有辐射度或全局照明概念的照明引擎。

照明不仅仅是找到0到1之间的光量。真实的照明引擎使用具有真实物理属性的光度学光源,并正确地在场景中传播光线,反射和折射每一条光线。真实的光量介于-无穷大和+无穷大之间,而真正的HDR显示系统会将这些值映射到屏幕上。

预计算照明模型的必要性

很明显,计算机图形学的下一个挑战不是真实感,而是能够实时完成所有这些计算。实现真正的动态照明。没有任何技巧……只有真正的动态照明。

当然,需要进行的计算量是巨大的。因此问题是:我们能在未来几年内实现它,还是仍需要预计算(静态)照明系统?

让我们做一个快速假设。如今,像V-Ray这样的非常好的照明引擎可能需要数小时才能计算出场景的照明。假设10小时(这绝不夸张)。我们每36000秒就能生成一张新图像。

所以,如果我们想以大约60fps(每0.016秒一张图像)的速度进行这些计算,我们将需要比我们现在拥有的计算能力大200多万倍的计算能力,这似乎有点太多了。当然,我们不能认为计算能力的演进是线性的,因为肯定会发现新的技术来加速计算,但无论如何,进步是巨大的,而且这样做似乎在短期内是不可行的。

因此,我们仍然需要预计算系统一段时间。

不过,谁知道呢!

© . All rights reserved.