我的着色器经常共享许多相同的功能。例如漫反射/镜面光照的计算。我想写一次,然后在不同的着色器中重用代码。
Glsl 不了解文件,也不支持类似 c 的#include
预处理器指令。
我知道 glsl 支持从多个 cstrings 编译源代码,但是你怎么知道要包含哪些 cstrings?您是否实现了自己的包含版本?或者您是否为每个着色器创建某种元文件?
我的着色器经常共享许多相同的功能。例如漫反射/镜面光照的计算。我想写一次,然后在不同的着色器中重用代码。
Glsl 不了解文件,也不支持类似 c 的#include
预处理器指令。
我知道 glsl 支持从多个 cstrings 编译源代码,但是你怎么知道要包含哪些 cstrings?您是否实现了自己的包含版本?或者您是否为每个着色器创建某种元文件?
在大型项目中,着色器通常在第一次运行(或更改图形选项时)组装,因此它们将包括所有供应商特定的功能,并针对用户机器和设置进行了优化。不仅是着色器,还有渲染管道的某些阶段。
您可以将 GLSL 视为 PHP 脚本为响应请求而吐出的 HTML\CSS\JavaSript 代码。并且您可以在循环中使用与 tampleting、代码注入(例如纹理查找量)相同的技术。它对图形设计师也有好处,因为他们可以通过参数化对着色器源进行简单控制——支票簿、输入字段等,它可以为独特的情况生成独特的着色器。
我有一个基于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% 确定是否存在一些性能损失。