在“我的世界”中,您可以将火炬放置在任何地方,每个火炬都会影响世界上的光照水平,并且您可以在世界范围内放置的火炬/光源数量没有限制。我99%确定火炬的照明在CPU上处理并为每个块存储,因此当在某个块上渲染光值时,只需要将其传递到着色器,但是光源不能为此移动原因。如果你有一个游戏,你可以放置可以四处移动的光源(箭头着火,带有灯光的矿车,发光的能量球)和灯光不是那么简单(颜色包括在内)什么是最有效的方法来计算灯光效果。
根据我的研究,我发现不同的渲染,不同的光照,动态创建具有不同光量的着色器并使用for循环(由于展开而无法使用制服)和静态光照贴图(这些可能是仅用于静止灯)。有没有其他方法可以进行照明计算,例如做除了允许移动灯光之外做什么类型的Minecraft,或者是否可以采用无限量的灯光并在数学上将它们组合成仅涉及几个灯光的近似值(这是一个想法我想出来但我无法弄清楚它是如何完成的?)
如果它有帮助,我是一名在OpenGL(传统和现代)方面具有良好经验的程序员,所以你可以给我代码片段,虽然我没有做太多的照明,所以简单的解释将不胜感激。如果你能指出我正确的方向,我也愿意做研究!
答案 0 :(得分:7)
你的标题有点误导infinite light
意味着像太阳一样无限距离的定向光。我会改用unlimited number of lights
。这里有一些我知道的方法:
(返回)光线跟踪器
他们可以原生处理任意数量的光源。光只是引擎中的另一个对象。如果射线击中光源,它只需要光强度并停止递归。不幸的是,当前的gfx硬件不适合这种渲染。有强 GPU 增强引擎,但专业的gfx硬件仍在开发中,尚未上市。内存要求与标准 BR 渲染没有太大差别,您仍然可以使用 BR 网格,但数学(分析)网格本机支持并且更适合这种情况。
标准BR渲染
BR 表示boundary representation
此类引擎(如 OpenGL 固定功能)只能处理有限数量的灯光。这是因为每个原语/片段需要完整的灯光列表,并且对每个原语或每片段的所有灯光进行计算。如果你得到很多光线,这将会很慢。
此外,当前GPU的内存(寄存器)内存有限,其中存储了灯光和其他渲染参数,因此有可能的解决方法,例如将光源参数存储在纹理中在 GLSL 着色器内按基元/片段迭代所有这些,但光的数量会影响粗略的性能,因此您受到目标帧速率和计算能力的限制。对此的额外内存要求只是带有光参数的纹理,而不是那么多(每个光源的矢量很少)。
光照地图
即使对于移动物体也可以计算它们。可以缓慢地计算复杂的光照贴图(不是每帧)。这会导致较小的光照效果,但您需要知道要查找的内容。光照贴图和阴影贴图非常相似,通常会立即计算出来。那里有简单的光照贴图和复杂的辐射图模型
这些是:
有些方法使用预渲染的 Z-Buffer 作为几何源,然后通过Radiosity或任何其他技术填充灯光。这些可以处理任意数量的灯光,因为这些地图可以计算,要求它们通常在后台计算并且偶尔更新一次。
快速移动的光源通常会更频繁地更新或从地图中排除,并呈现为透明几何体以产生光线效果。这需要的计算能力取决于基本的计算方法,如:
因此,您需要每次帧/地图更新渲染场景一次,并且还需要额外的缓冲区来存储渲染结果,高分辨率或体素贴图可以是大块内存。< / p>
多次通过光层
有些情况是在渲染场景后添加光线,例如我将其用于
以下是所有多通道渲染技术,您需要额外的缓冲区来存储子结果,并且通常在同一视图/场景上完成多遍渲染,因此使用预渲染几何体,这可以显着提高锁定 VAO 或已经渲染 Z-buffer 第一次传递的颜色和索引缓冲区。在此句柄之后作为单个或少量四边形传递(如在大气散射链接中),因此与基本 BR 渲染
正向渲染与延迟渲染
在谷歌这个forward rendering vs. deferred-rendering是我发现的第一个相关命中。它不是很好(有点模糊我的口味),但对于初学者来说已经足够了
该链接表明,对于高亮度数字而言,被修改的渲染更适合,但这很大程度上取决于使用了以前的技术。通常使用多次通过光层(具有标准的自定义渲染技术之一),因此在这种情况下它是真的,并且内存和计算能力需求与上一节相同。