在旧版的OpenGL中,存在以下内容:


glLight(...)
gl_LightSourceParameters

现代照明方式是通过光手动将源参数传递给vao-s中的着色器?还是制服?

为什么这些东西不受欢迎?

如果我在场景中有100个光源,我显然无法使用所有光源计算照明。因此,以某种方式在特定对象的阴影中,我只需要关心对其重要的光源。

我认为,例如,我应该仅将8个光源移至着色器,基于它们的“强度”。

但是这样调用每个帧不是太复杂吗?

我应该如何在现场处理大量光源?

/我读到了有关延迟照明的信息,但这是唯一的方法吗?/

#1 楼

为什么不推荐使用这些功能?

不推荐使用这些功能,因为与旧的固定管线相比,OpenGL API转向了可编程管线。可编程管线提供了实现各种以前难以实现或根本不可能实现的效果和解决方案所必需的灵活性。您仍然可以访问这些功能,因为它们是支持较旧系统所必需的,但是除此之外,我看不出不使用可编程管线的任何原因。
如何传递参数

如果我们在谈论灯光的参数(例如它们的位置或强度),则可以使用制服传递它们。特别是,您应该查看Uniform Buffer Objects。

在着色器中看起来像这样:

struct Light {
   int type;
   vec3 diffuse;
   vec3 position;
   bool on;
   ...
};

#define MAX_NUM_LIGHTS 8

uniform lightBlock {
    Light lights[MAX_NUM_LIGHTS];
};


请注意,这已经给了您一种传递所需灯光的方法。使您的着色器期望具有8个灯光的统一缓冲区,将其复制到客户端代码中的数组中,然后使用API​​发送它们。有关如何使用API​​函数执行此操作的更多信息,请查看上面有关UBO和此链接。

调用每个帧是否太复杂?

取决于您的场景以及如何选择要传递给着色器的灯光的条件。如果您担心每帧通过制服发送8盏灯的数据,则不必担心,这是您最少的担心。问题在于灯光的选择过程以及场景/阴影模型的复杂性,因为随着灯光数量的增加,成本也会随之增加。




前向渲染器:如果您的场景和阴影模型很简单,也许8个灯都可以。如果您实现现代阴影模型,则8盏灯可能有点过多。关键是您必须使用场景和阴影模型对其进行测试,并在所有模型之间找到折衷方案。也许传递4而不是8灯,也许您应该简化着色模型等。
延迟渲染器:由于其设计方式,延迟渲染器确实可以帮助进行多种光照渲染。但是,我认为延迟渲染可能会带来其他困难,因为它是一个更复杂的系统。而且,透明度和其他方面可能很难处理。
其他注意事项:请记住,有可能进行优化。有可能优化特定的灯光。也许并非所有人都需要动态的:考虑光照贴图和其他基于图像的照明。您应该考虑您的场景是否可以应用其中的任何一种。

总而言之,在推迟还是前进之间进行选择是一个重大决定。首先,请仔细考虑您的场景要求,并设计出选择灯光的策略。考虑到着色模型的复杂性。为了进行优化,您可以结合使用多种技术,例如简化一些远离相机且仅通过相关光源的光线。当您拥有测试框架时,请在所有这些之间妥协。