【问题标题】:How to write reusable glsl code?如何编写可重用的 glsl 代码?
【发布时间】:2012-11-11 21:09:12
【问题描述】:

我的着色器经常共享许多相同的功能。例如漫反射/镜面光照的计算。我想写一次,然后在不同的着色器中重用代码。

Glsl 不了解文件,也不支持类似 c 的 #include 预处理器指令。

我知道 glsl 支持从多个 cstrings 编译源代码,但是你怎么知道要包含哪些 cstrings?您是否实现了自己的包含版本?还是为每个着色器创建某种元文件?

【问题讨论】:

  • 对我来说 GLSL 有点太低级了,以至于实际上不可能将它用于复杂的情况(例如:PBR albedo 通道可能是程序、2D 纹理、没有代码生成器的平面颜色或其他东西),但替代解决方案通常过于高级和侵入性,也不能完全符合我的目的。我最终用一个简单的预处理器编写了自己的 GLSL 小扩展。我曾经使用 Lua 作为“元语言”,但在我花时间编写自己的小简单解析器之前,它从未如此精简。
  • 如果你像我一样,有点控制狂,IMO 就是这样。您可以为自己预处理的 GLSL 语言添加一些扩展。我添加的第一个扩展是channel 关键字。它们允许我们做类似channel4 albedo; 这样的事情,这意味着它应该出现在用户界面中,此时艺术家可以选择是否用单个纹理、复合纹理堆栈、程序、平面颜色来表示反照率,等等。然后根据艺术家的选择动态生成 GLSL 代码。
  • 关于代码生成的最棘手的事情之一是,至少以我的方式,扩展需要能够生成代码,不仅在 main 之外,而且在它内部.例如,如果反照率是由一堆纹理定义的,它们可能都有自己的 UV 纹理坐标,需要在垂直着色器中插值并在片段着色器中访问。因此,代码生成必须不仅能够在main 之外生成/添加代码,而且还必须能够在内部生成/添加代码。不过,这对我来说是唯一真正棘手的部分。

标签: include preprocessor glsl code-reuse


【解决方案1】:

在大型项目中,着色器通常在首次运行(或更改图形选项时)组装,因此它们将包含所有供应商特定的功能,并针对用户机器和设置进行了优化。不仅是着色器,还有渲染管线的某些阶段。
您可以将 GLSL 视为 PHP 脚本为响应请求而吐出的 HTML\CSS\JavaSript 代码。并且您可以在循环中使用与 tampleting、代码注入(例如纹理查找量)相同的技术。这对图形设计师也有好处,因为他们可以通过参数化对着色器源进行简单控制 - 支票簿、输入字段等,它可以为特殊情况生成独特的着色器。

【讨论】:

    【解决方案2】:

    我有一个基于http://blackpixel.com/blog/494/xcode-using-includes-in-opengl-shaders/ [404 now] 的自定义解决方案。基本上它说您可以使用m4 工具来预处理文件。

    在 GLSL 源文件中只包含您想要重用的所需片段:

    include(Utils.glsl)
    include(Colors.glsl)
    
    ...
    
    void main (void) {
        ...
    }
    

    在 Xcode 中,将所有 glsl 文件添加到“Copy Bundle Resources”。

    使用此 shell 脚本添加“运行脚本”阶段:

    #!/bin/sh
    
    cd ${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}
    find . -name "*.fsh" | while read file; do
        echo Preprocess $file
        m4 "$file" > "$file.tmp"
        mv "$file.tmp" "$file"
    done
    
    exit 0
    

    脚本假定您的着色器具有.fsh 扩展名。修改它以匹配您的着色器扩展很简单。

    请注意:几乎任何人都可以轻松访问您的着色器。您可以将其用于开发并在释放它们之前将它们转换为字符串(除非您对其进行加密,否则不是真正的保护......)。

    此外,如果着色器之间没有太多共享,您最终会得到很多未使用的代码。我猜着色器编译器会处理它,但我不能 100% 确定是否存在一些性能损失。

    【讨论】:

      猜你喜欢
      • 2011-03-10
      • 1970-01-01
      • 2012-06-03
      • 2022-01-22
      • 1970-01-01
      • 2011-05-12
      • 2021-01-08
      • 2020-01-31
      • 2010-10-13
      相关资源
      最近更新 更多