0

我正在使用 Java 编写一个非常原始的 3D 图形引擎,该引擎基于 1995 年的 3D 游戏编程的黑色艺术。我已经到了可以在屏幕上绘制单色多边形并在“场景”周围移动相机的地步。我什至有一个 Z 缓冲区,它可以通过按 Z 对这些像素进行排序来正确处理半透明对象,只要我一次不显示太多半透明像素。我正处于要添加照明的地步。我想保持简单,环境光看起来很简单,定向光也应该相当简单。但我真的想要点光源,它能够移动光源并投射出非常原始的阴影(大多数情况下我不希望光线穿过墙壁)。

我的问题是我不知道解决这个问题的最佳方法。我想象一个点光源以规则的角度投射光线,如果这些光线与多边形相交,它将照亮该多边形并停止向前移动。但是,当我考虑一个具有多个光源和多个多边形以及所有这些光线的场景时,我想它会变得非常慢。我也不知道如何处理多边形距离光源足够远而落在两条光线之间的情况。我会给每个光源一个最大距离,如果我给它足够的光线,那么在这个距离内不应该有任何两条光线相距太远而错过多边形的点,但这只会增加我的问题数量要执行的计算。

我的问题是:是否有一些技巧可以点光源来加快它们的速度,或者只是为了更好地组织它?恐怕我只会做一个嵌套 for 循环的噩梦。我不能使用 openGL 或 Direct3D 或任何其他作弊,因为我想自己编写。

如果你想看我到目前为止的结果,这里是一个 youtube 视频。我已经修复了坏的相机旋转。http://www.youtube.com/watch?v=_XYj113Le58&feature=plcp

4

1 回答 1

0

实时 3D 应用程序的照明(或者更确切地说,过去通常是)通过非常简单的近似值完成 - 请参阅http://en.wikipedia.org/wiki/Shading。阴影很昂贵——通常在光栅化 3d 引擎中是通过阴影贴图阴影体积来完成的。点光源使阴影更加昂贵。

动态实时光源直到最近才成为游戏中的常见功能——仅仅是因为它们给渲染系统带来了如此沉重的负担。这些游戏利用专用显卡。因此,我认为如果您决定包含动态阴影投射点光源,您可能很难从引擎中获得良好的性能。

如今,照明通常以两种方式应用:

  1. 传统上这是“前向渲染”。在这种方法中,对于每个顶点(如果您正在为每个顶点进行照明)或片段(如果您正在按像素进行),您将计算每个光源的贡献。
  2. 最近,“延迟”光照变得流行,其中几何和额外数据(如法线和颜色信息)都被渲染到中间缓冲区 - 然后用于计算光照贡献。这样,照明计算不依赖于几何数。但是,它确实有很多其他开销。

有很多选择。然而,实现比过去几年专用显卡使用的一些基本模型更复杂的东西将是一项挑战!

我的建议是从简单的东西开始——没有阴影的基本照明。从那里您可以扩展和优化。


你在做射线三角相交测试是为了什么?您是否只想照亮光线可以到达的三角形?我认为每盏灯与每一个多边形的光线三角形交叉点将非常昂贵。对于没有阴影的照明,通常您只需遍历每个面(或者如果您是按顶点执行,则遍历每个顶点)并计算并添加每个灯光的照明贡献 - 您将在开始光栅化之前执行此操作,因为您必须无论如何都要通过所有多边形。

您可以通过使用任何照明模型来计算照明,非常简单,例如 朗伯反射率- 根据表面法线和从表面到光线的方向矢量的点积对表面进行着色。确保您的向量在相同的空间中!这可能就是你得到奇怪结果的原因。如果您的表面法线在世界空间中,请务必计算世界空间光矢量。在某些空间计算光照有很多好处,你可以稍后再看,现在我建议你先把基础知识开始运行。也看看 Blinn-phong - 这是多年来使用的着色模型显卡。

对于带阴影的照明 - 查看我发布的链接。它们的开发是因为逼真的照明计算起来非常昂贵。

顺便说一句,LaMothe 有一本名为 Tricks of the 3D Game Programming Gurus-Advanced 3D Graphics and Rasterization 的后续书。
这将带您完成对 3d 引擎进行编程的每一步。我不确定黑色艺术书的内容。

于 2012-09-18T21:43:29.223 回答