定义自己的制服,而不是在 GLSL 中重用内置 OpenGL 变量。为什么?

发布于 2024-10-15 09:06:44 字数 308 浏览 6 评论 0原文

我正在编写一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

以往的大感动 2024-10-22 09:06:44

我从来没有听说过制服会减慢着色器的速度,它们就像编译时间常数(或者应该是)。

关于使用内置变量,不建议使用它们,因为它们在 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.

爱冒险 2024-10-22 09:06:44

关键是,在现代 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.

冷清清 2024-10-22 09:06:44

在 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.

滥情稳全场 2024-10-22 09:06:44

使用内置制服是一种不好的做法,因为:

  1. 你开始使用它们,它们对你来说就足够了。
  2. 您需要更多,因此您将为自定义属性制定特殊逻辑。
  3. 您可以对所有内容使用自定义属性,并且它们是受支持的,那么为什么要保留过时的内置逻辑呢?
  4. 您迁移到 OpenGL 3+ 核心上下文/ES 2 并忘记内置组件。

我自己完成了这些步骤并得出结论 - 如果我一开始就使用纯 GL-3,生活会更容易。

It is a bad practice to use built-in uniforms, because:

  1. You start to use them, and they are enough for you.
  2. You need more, so you'll make a special logic for custom attributes.
  3. You can use custom attributes for everything, and they are supported, so why to keep obsolete built-in logic?
  4. You migrate on OpenGL 3+ core context / ES 2 and forget about built-ins.

I've come through these steps myself and conclude - life would be easier if I started with pure GL-3 initially.

流年里的时光 2024-10-22 09:06:44

对原始问题的评论,关于性能。

  • 如果内置制服没有“特殊行为”,那么它不会比您定义的制服更快。在预定义的制服中没有什么是你做不到的。
  • 我能想到的所有内置制服都有特殊行为。例如,将灯光变换到眼睛空间,预乘照明模型系数。因此,驱动程序可能必须努力保持“建模”固定功能管道的制服同步。我不知道什么实现将始终完成这项工作,而不是在可能的情况下跳过这项工作...ymmv。
  • 您可以通过定制制服获得更好的灵活性。例如,即使您愿意,也不能将默认制服放入 UBO 中。
  • 虽然许多人建议不要使用内置程序,但驱动程序编写者可能花费了比您的日程允许的更多时间来优化矩阵转换等内容;如果您确实删除了自定义制服的内置程序,请审核性能以确保您的 CPU 端性能足够好。

最后,当不使用 UBO 时,驱动程序可能必须在更改着色器时更新所有制服。因此更多的制服可以减缓着色器的变化。

不幸的是,在所有情况下,您唯一真正能做的就是进行良好的测量; GL 不保证驱动程序中的优化内容。

A comment on the original question, about performance.

  • If a built-in uniform has no 'special behavior' then there it is no faster than one that is defined by you. There's nothing in the pre-defined uniforms that you can't do.
  • All of the built-in uniforms that I can think of have special behavior. For example, lights are transformed to eye space, lighting model coefficients are pre-multiplied. So the driver may have to do work to keep the uniforms that 'model' the fixed function pipeline in sync. I don't know what implementations will do this work always vs. skip this work when possible...ymmv.
  • You may get better flexibility with custom uniforms. For example, you can't put the default uniforms in a UBO even if you want to.
  • While a number of people have suggested not using the built-ins, the driver writers may have spent more time optimizing things like matrix transforms than your schedule permits; if you do remove built-ins for custom uniforms, audit performance to make sure your CPU-side performance is good enough.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文