OpenGL 灯光限制
当我阅读红皮书时,我感到很困惑,openGL 场景中最多可以有 8 个灯光(数量取决于实现,但应该在 8 左右)。
但我可以想象有很多情况需要更多的灯光,所以我认为游戏开发中有一个解决这个问题的技巧。
例如,您有一条很长的街道,有 50 个手电筒,或者您可以有 20 个人都使用手电筒的小队。您实际上是如何模拟这些情况的?有一个问题,光只照亮网格的一部分,而不是光源和物体之间的整个圆锥体,所以如果我们没有 100% 干净的空气,也必须有某种模拟。这是怎么做到的,游戏运行流畅?(我还读到启用所有 8 个灯可能会杀死 FPS)
As I was reading RedBook I stayed quite confused, that openGL can have maximum 8 lights in scene (number depending on implementation, but should be arround 8).
But I can imagine number of situations that would need more lights, so I think there's a trick arround this in game dev.
For example, you have very long street with 50 strretlights, or you can have squad of 20 peoples all using flashlights. How you actually simulate those situations? There's a problem, that light iluminates only the part of mesh, not whole cone between source and object, so if we don't have 100% clean air, there must be some sort of simulation also. What's the way this is done, and the game runs smooth?(I read also that enabling all 8 lights could kill FPS)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
8 个灯光是固定 GL 管道的限制,您可以在其中启用每个灯光,设置模式、参数等。现在您有了像素着色器,并且照明是在着色器内完成的。在那里您可以使用大量动态(未烘焙到纹理中)灯光。您只需要充分提供所有这些灯光的参数(也许在纹理中),并测试您的着色器能够处理多少灯光。此外,在着色器中,您可以剔除太弱的灯光(对像素值贡献太少)或太远的灯光。
更新:具有分支的复杂着色器甚至可以生成灯光(想想长街或圣诞树)。它可能比提供大量参数更有效。
8 lights is the limitation of fixed GL pipeline, where you enable each of them, set mode, parameters, etc. Now you have pixel shaders, and lighting is done within shader. There you can use large number of dynamic (not baked into textures) lights. You only need to supply all these lights' parameters sufficiently (maybe, in a texture), and test how many lights your shader is able to process. Also, in shader you can cull too weak lights (contributing too little into pixel value) or just too distant ones.
Update: complex shader with branching can even generate lights (think of long street or christmas tree). It could be more efficient than supply large number of parameters.
光照是计算机图形学中一个非常复杂的主题。
当然,真正重要的是对象照明,模拟现实世界的照明或我们目标的效果。照明环境可以由许多光源组成,以接近我们想要实现的真实效果。
OpenGL 光照实现是动态光照,它们是光点抽象,允许“光照”(即给出颜色)渲染顶点(用于渲染三角形)。 ...顶点被照亮,获取每个光的颜色贡献。
正如您所提到的,渲染过程需要更多时间,我们启用的灯光越多。为了尽量减少这种情况,您有不同的可能性。
OpenGL 固定光照有助于顶点颜色,它与其他顶点颜色进行插值以栅格化三角形。在几何体由几个三角形组成的情况下,您看不到每个三角形内部的任何光锥,因为其片段的颜色是三种颜色(三个顶点)插值的结果。
为了实现更精确的照明,软件应确定每个片段(像素)颜色(像素照明),就像顶点被灯光着色一样,但正如您所理解的,像素可能比顶点更多。
一种方法是在光栅化阶段计算(使用着色器或 OpenGL 扩展)光源对几何体每个像素的贡献,或使用延迟光照确定像素颜色。
延迟光照使用多个纹理(对应于视口)来存储每个显示像素的灯光参数。通过这种方式,您可以在生成图像后执行光计算,为每个像素确定一次像素光贡献,而不是为每个几何像素确定一次。
Lighting is a very complex topic in computer graphics.
What really matter is, of course, the object illumination, emulating the real world lighting or the effect we are targeting. The lighting environment could be composed by many sources in order to approximate the real effect we are trying to achieve.
OpenGL lighting implementation are dynamic lights, which are light point abstraction which allow to "light" (that is, give a color) to rendered vertices (which are used for render triangles). ...the vertex is illuminated, get color contribution for each light.
As you mentioned, the rendering process take more time more lights we has enabled. To minimize this, you have different possibilities.
OpenGL fixed lighting contributes to vertex color, which is interpolated with other vertex colors in order to rasterize the triangle. In the case the geometry is composed by few triangles, you cannot see any light cone inside the each triangle, because its fragment's color are the result of the interpolation of three colors (the three vertices).
To achieve a more precise lighting, the software shall determine each fragment (pixel) color (pixel lighting) in the same way a vertex is colored by lights, but as you can understand, there could be more pixels than vertices.
An approach is to compute (using shaders or an OpenGL extension) the light's contribution for each pixel of the geometry during the rasterization phase, or determine the pixel color using deferred lighting.
Deferred lighting uses multiple textures (corresponding to the viewport) to store lights parameters for each displayed pixel. In this way you execute light computation after the image is produced, determining pixel light contribution once for each pixel, instead of once for each geometry pixel.
游戏中使用的技巧之一是用纹理模拟光线。
因此,在您的路灯示例中,“照亮”区域实际上将是更亮的纹理图像。只有最近的灯才会成为光源才能获得正确的效果。
还有类似的方法,其中半透明纹理或具有透明圆锥体的纹理覆盖场景以产生相同的效果。
不要忘记,实时计算阴影等意味着必须从光的角度渲染场景,以计算任何给定位置的光强度。因此,对于 8 个灯光,在实际渲染场景以供显示之前,您最多需要渲染场景(或场景的一部分)最多 8 次。即使这是在 GPU 而不是 CPU 上完成的,也是非常昂贵的。
One of the tricks that will be used in games is to simulate the light with a texture.
So in your street light example, the "lit" areas will actually be a brighter texture image. Only the nearest lights will be light sources to get the correct effects.
There are similar approaches where semi-transparent textures or textures with a transparent cone are overlaid the scene to give the same effect.
Don't forget that to compute the shadows etc. in real-time means that the scene has to be rendered from the point of view of the light to calculate the intensity of the light at any given location. So for 8 lights you are rendering the scene (or parts of the scene) up to 8 times before actually rendering the scene for display. Even if this is done on the GPU rather than the CPU it's very expensive.