OpenGL:我应该在哪里放置着色器?


17

我正在尝试学习OpenGL ES 2.0,并且想知道“管理”着色器的最常见做法是什么。
我之所以问这个问题,是因为在我发现的示例中(例如与android sdk一起提供的API Demo中包含的示例),我通常会看到GLRenderer类中的所有内容,而我希望将它们分开,这样我就可以拥有例如,一个GLImage对象,无论何时我想绘制带纹理的四边形(我现在仅专注于2D),都可以重用,就像我在OpenGL ES 1.0代码中一样。在我发现的几乎每个示例中,着色器仅定义为类属性。例如:

public class Square {

public final String vertexShader =
        "uniform mat4 uMVPMatrix;\n" +
        "attribute vec4 aPosition;\n" +
        "attribute vec4 aColor;\n" +
        "varying vec4 vColor;\n" +
        "void main() {\n" +
        "  gl_Position = uMVPMatrix * aPosition;\n" +
        "  vColor = aColor;\n" +
        "}\n";

public final String fragmentShader =
        "precision mediump float;\n" +
        "varying vec4 vColor;\n" +
        "void main() {\n" +
        "  gl_FragColor = vColor;\n" +
        "}\n";
// ...
}

如果其中一些问题愚蠢,我会先道歉,但是我以前从未使用过着色器。

1)上面的代码是定义着色器(公共最终类属性)的常用方法吗?
2)我应该单独安排着色器课程吗?
3)如果在使用着色器的类之外定义了着色器,我将如何知道其属性的名称(例如,以下代码中的“ aColor”),以便可以绑定它们?

colorHandle = GLES20.glGetAttribLocation(program, "aColor");

Answers:


16

我一直不喜欢这种定义着色器(以字符串形式)的方式。我更喜欢在文本文件中进行读取,并在加载时读取它。在字符串中定义它对于调试很烦人,对我来说看起来很混乱。能够键入它并以应有的格式查看它,而不是在字符串中,要容易得多。

我还有一个单独的类,具有通用的着色器功能,例如读取着色器并打印用于着色器调试的日志信息。

无论在哪里定义着色器,都可以像在示例中一样访问名称。着色器可以使用字符串文字,因为一旦实现它们,这些值就不太可能更改。

但是,最终取决于您。如果它不会给您带来任何麻烦,那么您当前的工作方式将非常有用。


2
将着色器放在单独的文件中还意味着您可以使用方便的着色器编辑器并突出显示完整的语法,如果支持的话,甚至可以在程序中对其进行预览之前对其进行预览。
Raceimaztion 2012年

6
在字符串中包含着色器的唯一真正原因是需要进行快速测试和教程。文件处理会在其中添加大量“不必要的代码”。
贾里·孔帕

2
您还可以在着色器文件上实现热重载-允许您调试更改而无需重新启动游戏。生产力++
廖山

我喜欢将它们读成一个文件并有一个单独的Shader类的想法。总是以String的形式查看它们,这使我感到困惑,因为我不知道这是通常定义它们的方式还是仅仅是出于学习目的。谢谢!
miviclin

8

着色器(以及材质)管理是一个相当棘手的问题,当您的图形系统变得更加复杂时,您会发现每个着色器的硬编码都会导致大量的代码重复。以下是解决此问题的几种替代方法:

  • Jari Komppa评论说,只有几个着色器的小例子倾向于将它们硬编码为字符串,以避免文件处理
  • 更好的方法是使用单独的文件,在这些文件中可以突出显示语法并设置正确的格式。您还可以编写一个简单的调试系统,以监视这些文件中的更改,并在游戏运行时即时应用修改后的着色器。
  • 当材质数量增加时,几乎需要着色器生成器。基本上,您定义了诸如“片段着色器法线贴图片段”之类的常见片段,并通过包含所需的组件来构成完整的着色器。
    • 您可以使用硬编码的字符串片段,但这会很快变得混乱,因此再次使用文件是个好主意。
    • 您可以在单独的文件(或相同文件)中包含一些代码,也可以使用ubershader / supershader,在其中使用预处理器(或统一标志)来启用/禁用内容。

至于属性和统一名称等,您只需在所有着色器上使用一致的命名即可。


我一定会将我的着色器移到一个单独的文件中。谢谢!
miviclin
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.