定义自己的制服,而不是在 GLSL 中重用内置 OpenGL 变量。为什么?
我正在编写一个 3D 图形引擎。
我听说在着色器程序中使用太多统一变量是不好的,因为它会导致速度减慢。
另一方面,有人说重复使用一些内置变量(例如 gl_TextureMatrix)是一种不好的做法。
我应该如何组织创建我的着色器程序? 我应该为每种机制编写大量的制服还是可以依赖这些内置变量? 例如,我应该使用内置 gl_LightSource 还是定义自己的带有光源信息的统一数组,以便我的场景中可以有更多灯光?我也了解延迟渲染技术,但我想先做基本的多个灯光。
或者,哪些内置变量可以重用?
这些做法的优缺点是什么?
I am writing a 3D graphics engine.
I've heard that it is bad to use too much uniform variables in your shader program because it can cause slowdown.
On the other side, some say that re-using some built-in variables like gl_TextureMatrix is kind of bad practice.
How should I organize creating my shader programs ?
Should I write plenty of uniforms for each mechanism or can I rely on those built-in variables ?
For example, should I use built-in gl_LightSource or define own uniform array with light source informations, so I can have more lights on my scene? I also know about deferred rendering techniques but I want to do basic multiple lights first.
Or maybe, which built-in variables are 'OK' to reuse?
What are (dis)advantages of each of these practices?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我从来没有听说过制服会减慢着色器的速度,它们就像编译时间常数(或者应该是)。
关于使用内置变量,不建议使用它们,因为它们在 OpenGL 3.0 中已被弃用,并且对于 OpenGL Core 配置文件,它们不可用。为了可编程性,它们被删除。您可以为您想要的任何内容定义自己的变量,这很好。
所以,这只是一个可编程性的问题,如果你正在学习并且想使用它们,那也没关系。
I've never heard that uniforms can slowdown the shader, they are like compile time constants (or should be).
About using built-in variables, it's not recommended to use them, because they are deprecated in OpenGL 3.0 and with the OpenGL Core profile, they are not available. They were removed for sake of programmability. You can define your own variables for anything you want and that is fine.
So, it's just a matter of programmability, if you are learning and want to use them, it's also fine.
关键是,在现代 3D 图形编程中,API 对如何绘制场景做出了更少的假设,并将更多的控制权转移给了开发人员。 OpenGL 和 Direct3D 都是如此。当然,大多数场景都使用顶点、颜色、法线、纹理坐标等,这些都导致了固定的管线。但是,如果我想要粒子引擎的起始位置和速度怎么办?这会将重力和时间放入统一变量中。
因此,为了回答您的问题,假设您想进入现代图形开发,请停止使用任何预定义的制服并定义您自己的制服。从 OpenGL 3 开始,预定义的制服无论如何都消失了,您需要准确定义渲染场景所需的内容。对于固定管道的老手来说,这常常感觉像是倒退了一步。 “什么?我已经实现了已经运行良好的矩阵???”然而,当他们发现不再需要仅仅为了准备渲染而进行 500 次不同的 glEnable 调用时,他们很快发现这得到了巨大的回报;着色器程序精确定义了他们想要如何绘制场景。
简而言之,同时生活在两个世界中(同时使用着色器和所有固定管道功能)是一个坏主意。如果固定管道可以完成您需要它完成的所有操作,请坚持使用 OpenGL 2,并以您当前熟悉的方式完成工作。如果您需要高级渲染技巧,请深入研究 OpenGL 3+,永不回头。
The point is that in modern 3D graphics programming, the API is making fewer assumptions about how to draw your scene and shifts more of the control to the developer. This is true of both OpenGL and Direct3D. Sure, most scenes use vertices, colors, normals, texture coordinates, etc., which all resulted in the fixed pipelines. However, what if I want to have starting positions and velocities for a particle engine? This would put gravity and time into uniform variables.
So, to answer your question, assuming you want to move into modern graphics development, stop using any predefined uniforms and define all your own. As of OpenGL 3, the predefined uniforms are gone anyway, and it rests upon you to define exactly what you need to render your scene. For veterans of the fixed pipeline, this often feels like a step backwards. "WHAT?? I have implement the matrices that were working fine already???" However, they quickly find that this pays off greatly when they see that they no longer have to make 500 different glEnable calls just to prep the rendering; the shader program defines precisely how they want to draw the scene.
In short, it's a bad idea to live in both worlds (using shaders and all the fixed pipeline functionality together). If the fixed pipeline does everything you need it to do, stick to OpenGL 2 and just get the job done the way you are currently familiar with. If you need advanced rendering tricks, dive into OpenGL 3+ and never look back.
在 OpenGL-4 中,所有这些预定义的制服都消失了,但我通常只使用旧名称,这样我就可以重用旧的着色器。
In OpenGL-4 all those predefined uniforms are gone, but I usually just use the old names, so that I can reuse my old shaders.
使用内置制服是一种不好的做法,因为:
我自己完成了这些步骤并得出结论 - 如果我一开始就使用纯 GL-3,生活会更容易。
It is a bad practice to use built-in uniforms, because:
I've come through these steps myself and conclude - life would be easier if I started with pure GL-3 initially.
对原始问题的评论,关于性能。
最后,当不使用 UBO 时,驱动程序可能必须在更改着色器时更新所有制服。因此更多的制服可以减缓着色器的变化。
不幸的是,在所有情况下,您唯一真正能做的就是进行良好的测量; GL 不保证驱动程序中的优化内容。
A comment on the original question, about performance.
Finally, when not using UBOs, the driver may have to update all uniforms when changing shaders. So more uniforms can slow down shader changes.
In all cases, unfortunately the only thing you can really do is take good measurements; the GL makes no guarantees as to what's optimized in the driver.