如何编写可重用的glsl代码?

时间:2012-11-23 13:30:07

标签: include preprocessor glsl code-reuse

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

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

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

2 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:3)

我有一个基于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%确定是否存在性能损失。