My shaders often share much of the same functionality. For instance calculation of diffuse/specular lighting. I would like to write this one time and then reuse the code across different shaders.
Glsl has no knowledge of files, and no support for a c-like #include
preprocessor directive.
I know glsl has support for compiling source from multiple cstrings, but how would you know which cstrings to include? Do you implement your own version of include? Or do you create some sort of metafile for each of your shaders?
In the large projects shaders often assembled at the first run (or when graphic options are changed) so they will include all vendor specific functional and are optimized for user machine and settings. And not only shader but also some stages of render pipeline.
You can treat GLSL as HTML\CSS\JavaSript code that PHP script vomits in response to the request. And you can use same technics as tampleting, code injections(for example amount of texture lookup) in loops. And it's also good for graphic designers because they have simple control on shader source through parameterization - checkbook, input fields etc and it can produce unique shader for unique cases.
I have a custom solution based on http://blackpixel.com/blog/494/xcode-using-includes-in-opengl-shaders/ [404 now]. Basically it said that you can use m4 tool to preprocess the files.
In the GLSL source files just include the desired fragment you want to reuse:
include(Utils.glsl)
include(Colors.glsl)
...
void main (void) {
...
}
In Xcode, add all glsl
files to “Copy Bundle Resources”.
Add a “Run Script” phase with this shell script:
#!/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
The script assumes your shaders have .fsh
extension. It’s trivial to modify it to match your shader extensions.
Be warned: your shaders will be easily accessible to almost anyone. You may use it for development and convert them to strings before releasing them (not a real protection unless you encrypt it...).
Also, if there is no much sharing between shaders, you'll end up with a lot of unused code. I guess the shader compiler will take care of it but I'm not 100% sure if there is some performance penalty.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With