<p>There's a bunch of a approaches, but none is perfect.</p>

<p>It's possible to share code by using <code>glAttachShader</code> to combine shaders, but this doesn't make it possible to share things like struct declarations or <code>#define</code>-d constants. It does work for sharing functions.</p>

<p>Some people like to use the array of strings passed to <code>glShaderSource</code> as a way to prepend common definitions before your code, but this has some disadvantages:</p>

<ol>
<li>It's harder to control what needs to be included from within the shader (you need a separate system for this.)</li>
<li>It means the shader author cannot specify the GLSL <code>#version</code>, due to the following statement in the GLSL spec:</li>
</ol>

<blockquote>
  <p>The <strong>#version</strong> directive must occur in a shader before anything else, except for comments and white space.</p>
</blockquote>

<p>Due to this statement, <code>glShaderSource</code> cannot be used to prepend text before the <code>#version</code> declarations. This means that the <code>#version</code> line needs to be included in your <code>glShaderSource</code> arguments, which means that your GLSL compiler interface needs to somehow be told what version of GLSL is expected to be used. Additionally, not specifying a <code>#version</code> will make the GLSL compiler default to using GLSL version 1.10. If you want to let shader authors specify the <code>#version</code> within the script in a standard way, then you need to somehow insert <code>#include</code>-s after the <code>#version</code> statement. This could be done by explicitly parsing the GLSL shader to find the <code>#version</code> string (if present) and make your inclusions after it, but having access to an <code>#include</code> directive might be preferable to control more easily when those inclusions need to be made. On the other hand, since GLSL ignores comments before the <code>#version</code> line, you could add metadata for includes within comments at the top of your file (yuck.)</p>

<p>The question now is: Is there a standard solution for <code>#include</code>, or do you need to roll your own preprocessor extension?</p>

<p>There is the <code>GL_ARB_shading_language_include</code> extension, but it has some drawbacks:</p>

<ol>
<li>It is only supported by NVIDIA (<a href="http://delphigl.de/glcapsviewer/listreports2.php?listreportsbyextension=GL_ARB_shading_language_include" rel="noreferrer">http://delphigl.de/glcapsviewer/listreports2.php?listreportsbyextension=GL_ARB_shading_language_include</a>)</li>
<li>It works by specifying the include strings ahead of time. Therefore, before compiling, you need to specify that the string <code>"/buffers.glsl"</code> (as used in <code>#include "/buffers.glsl"</code>) corresponds to the contents of the file <code>buffer.glsl</code> (which you have loaded previously).</li>
<li>As you may have noticed in point (2), your paths need to start with <code>"/"</code>, like Linux-style absolute paths. This notation is generally unfamiliar to C programmers, and means you can't specify relative paths.</li>
</ol>

<p>A common design is to implement your own <code>#include</code> mechanism, but this can be tricky since you also need to parse (and evaluate) other preprocessor instructions like <code>#if</code> in order to properly handle conditional compilation (like header guards.)</p>

<p>If you implement your own <code>#include</code>, you also have some liberties in how you want to implement it:</p>

<ul>
<li>You could pass strings ahead of time (like <code>GL_ARB_shading_language_include</code>).</li>
<li>You could specify an include callback (this is done by DirectX's D3DCompiler library.)</li>
<li>You could implement a system that always reads directly from the filesystem, as done in typical C applications.</li>
</ul>

<p>As a simplification, you can automatically insert header guards for each include in your preprocessing layer, so your processor layer looks like:</p>

<pre><code>if (#include and not_included_yet) include_file();
</code></pre>

<p>(Credit to Trent Reed for showing me the above technique.)</p>

<p><strong>In conclusion</strong>, there exists no automatic, standard, and simple solution. In a future solution, you could use some SPIR-V OpenGL interface, in which case the GLSL to SPIR-V compiler could be outside of the GL API. Having the compiler outside the OpenGL runtime greatly simplifies implementing things like <code>#include</code> since it's a more appropriate place to interface with the filesystem. I believe the current widespread method is to just implement a custom preprocessor that works in a way any C programmer should be familiar with.</p>

CC BY-SA 4.0
2019-08-20T18:34:02.520Z
Shaders can also be separated into modules using [glslify](https://github.com/glslify/glslify), though it only works with node.js.
Anderson Green
CC BY-SA 4.0
2023-03-03T19:48:29.853Z
What about just using the C++ preprocessor, which already can handle `#include`s and ´#if´s?
HelloGoodbye
CC BY-SA 4.0
2024-09-22T14:41:43.443Z
@HelloGoodbye you have to be a bit careful because it might not handle GLSL specific things correctly, like #version and #extension
Nicolas Louis Guillemot
CC BY-SA 3.0
2015-08-08T01:33:56.490Z
2015-08-10T19:16:27.473Z
2015-08-10T19:16:27.473Z
Nicolas Louis Guillemot
<p>I generally just use the fact that glShaderSource(...) accepts an array of strings as it's input.</p>

<p>I use a json-based shader definition file, which specifies how a shader (or a program to be more correct) is composed, and there I specify the preprocessor defines I may need, the uniforms it uses, the vertex/fragment shaders file, and all the additional "dependency" files.
These are just collections of functions that gets appended to the source before the actual shader source.</p>

<p>Just to add, AFAIK, the Unreal Engine 4 uses an #include directive that gets parsed and append all the relevant files, before the compilation, as you were suggesting.</p>

CC BY-SA 3.0
2015-08-07T14:26:32.683Z
2015-08-07T14:26:32.683Z
Matteo Bertello
<p>I don't think there is a common convention, but if I'd take a guess, I'd say that almost everyone implements some simple form of textual inclusion as a preprocessing step (an <code>#include</code> extension), because it is very easy to do so. (In JavaScript/WebGL, you can do that with a simple regular-expression, for example). The upside of this is that you can perform the preprocessing in an offline step for "release" builds, when the shader code no longer needs to be changed.</p>

<p>In fact, an indication that this approach is common is the fact that an ARB extension was introduced for that: <a href="https://www.opengl.org/registry/specs/ARB/shading_language_include.txt" rel="noreferrer"><code>GL_ARB_shading_language_include</code></a>.
I'm not sure if this became a core feature by now or not, but the extension was written against OpenGL 3.2.</p>

CC BY-SA 3.0
2015-08-08T01:08:40.533Z
GL_ARB_shading_language_include is not a core feature. In fact, only NVIDIA supports it. (http://delphigl.de/glcapsviewer/listreports2.php?listreportsbyextension=GL_ARB_shading_language_include)
Nicolas Louis Guillemot
CC BY-SA 3.0
2015-08-07T19:11:21.303Z
2015-08-07T23:09:16.677Z
2015-08-07T23:09:16.677Z
glampert
<p>Some people have already pointed out that <code>glShaderSource</code> can take an array of strings.</p>

<p>On top of that, in GLSL the compilation (<code>glShaderSource</code>, <code>glCompileShader</code>) and linking (<code>glAttachShader</code>, <code>glLinkProgram</code>) of shader is separate.</p>

<p>I have used that in some projects to split shaders between the specific part, and the parts common to most shaders, which is then compiled and shared with all shader programs. This works and is not difficult to implement: you just have to maintain a dependency list.</p>

<p>In terms of maintainability though, I am not sure it is a win. The observation was the same, let's try to factorize. While it indeed avoids repetition, the overhead of the technique feels significant. Moreover, the final shader is more difficult to extract: you cannot just concatenate the shader sources, as the declarations end in an order that some compilers will reject, or will be duplicated. So it makes it more difficult to do a quick shader test in a separate tool.</p>

<p>In the end this technique addresses some DRY issues, but it's far from ideal.</p>

<p>On a side topic, I am not sure if this approach has any impact in terms of compilation time; I have read that some drivers only really compile the shader program on linking, but I haven't measured.</p>

CC BY-SA 3.0
2015-08-08T17:35:24.210Z
From my understanding, I think this does not solve the problem of sharing struct definitions.
Nicolas Louis Guillemot
CC BY-SA 3.0
2015-08-08T17:39:53.133Z
@NicolasLouisGuillemot: yes you are right, only instructions code is shared this way, not declarations.
Julien Guertault
CC BY-SA 3.0
2015-08-08T05:31:58.103Z
2015-08-08T05:31:58.103Z
Julien Guertault
<p>I often find myself copy-pasting code between several shaders. This includes both certain computations or data shared between all shaders in a single pipeline, and common computations which all of my vertex shaders need (or any other stage).</p>

<p>Of course, that's horrible practice: if I need to change the code anywhere, I need to make sure I change it everywhere else.</p>

<p>Is there an accepted best practice for keeping <a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a>? Do people just prepend a single common file to all their shaders? Do they write their own rudimentary C-style preprocessor which parses <code>#include</code> directives? If there are accepted patterns in the industry, I'd like to follow them.</p>

CC BY-SA 3.0
2015-08-07T12:39:15.597Z
This question may be a bit controversial, because several other SE sites don't want questions about best practices. This is intentional to see how this community stands regarding such questions.
Martin Ender
CC BY-SA 3.0
2015-08-07T12:40:15.333Z
Hmm, looks good to me. I'd say we are to a large degree a bit "broader"/"more general" in our questions than, say, StackOverflow.
Christian Rau
CC BY-SA 3.0
2015-08-07T14:24:01.983Z
StackOverflow went from being a 'ask us' to a 'dont ask us unless you **have to** please' board.
insidesin
CC BY-SA 3.0
2015-08-07T15:43:26.963Z
If it's meant to determine on-topicness, then how about an associated Meta question?
S.L. Barth is on codidact.com
CC BY-SA 3.0
2015-08-07T15:51:43.950Z
@S.L.Barth I figured I could still do that once anyone objects, but sure, why not.
Martin Ender
CC BY-SA 3.0
2015-08-07T16:06:09.930Z
[Discussion on meta.](http://meta.computergraphics.stackexchange.com/q/53/16)
Martin Ender
CC BY-SA 3.0
2015-08-09T00:36:10.310Z
I wrote [this](http://stackoverflow.com/a/20605122/1888983) a while back. Beyond `#include`, I find injecting `#define`s is most useful. One shader, many permutations.
jozxyqk
<glsl>
Sharing code between multiple GLSL shaders
Martin Ender
# Sharing code between multiple GLSL shaders

(Asked by: username_0 on 2015-08-07)

I often find myself copy-pasting code between several shaders. This includes both certain computations or data shared between all shaders in a single pipeline, and common computations which all of my vertex shaders need (or any other stage).

Of course, that's horrible practice: if I need to change the code anywhere, I need to make sure I change it everywhere else.

Is there an accepted best practice for keeping [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)? Do people just prepend a single common file to all their shaders? Do they write their own rudimentary C-style preprocessor which parses `#include` directives? If there are accepted patterns in the industry, I'd like to follow them.

**Tags:** glsl

> **Comments:**
> **username_0**: This question may be a bit controversial, because several other SE sites don't want questions about best practices. This is intentional to see how this community stands regarding such questions.  
> **username_1**: Hmm, looks good to me. I'd say we are to a large degree a bit "broader"/"more general" in our questions than, say, StackOverflow.  
> **username_2**: StackOverflow went from being a 'ask us' to a 'dont ask us unless you **have to** please' board.  
> **username_3**: If it's meant to determine on-topicness, then how about an associated Meta question?  
> **username_0**: @username_3Barth I figured I could still do that once anyone objects, but sure, why not.  
> **username_0**: [Discussion on meta.](http://meta.computergraphics.stackexchange.com/q/53/16)  
> **username_4**: I wrote [this](http://stackoverflow.com/a/20605122/1888983) a while back. Beyond `#include`, I find injecting `#define`s is most useful. One shader, many permutations.  

---

## 4 answers

### Answer by username_5 on 2015-08-08. Score: 26 | Accepted answer

There's a bunch of a approaches, but none is perfect.

It's possible to share code by using `glAttachShader` to combine shaders, but this doesn't make it possible to share things like struct declarations or `#define`-d constants. It does work for sharing functions.

Some people like to use the array of strings passed to `glShaderSource` as a way to prepend common definitions before your code, but this has some disadvantages:

1. It's harder to control what needs to be included from within the shader (you need a separate system for this.)
2. It means the shader author cannot specify the GLSL `#version`, due to the following statement in the GLSL spec:

> The **#version** directive must occur in a shader before anything else, except for comments and white space.

Due to this statement, `glShaderSource` cannot be used to prepend text before the `#version` declarations. This means that the `#version` line needs to be included in your `glShaderSource` arguments, which means that your GLSL compiler interface needs to somehow be told what version of GLSL is expected to be used. Additionally, not specifying a `#version` will make the GLSL compiler default to using GLSL version 1.10. If you want to let shader authors specify the `#version` within the script in a standard way, then you need to somehow insert `#include`-s after the `#version` statement. This could be done by explicitly parsing the GLSL shader to find the `#version` string (if present) and make your inclusions after it, but having access to an `#include` directive might be preferable to control more easily when those inclusions need to be made. On the other hand, since GLSL ignores comments before the `#version` line, you could add metadata for includes within comments at the top of your file (yuck.)

The question now is: Is there a standard solution for `#include`, or do you need to roll your own preprocessor extension?

There is the `GL_ARB_shading_language_include` extension, but it has some drawbacks:

1. It is only supported by NVIDIA (<http://delphigl.de/glcapsviewer/listreports2.php?listreportsbyextension=GL_ARB_shading_language_include>)
2. It works by specifying the include strings ahead of time. Therefore, before compiling, you need to specify that the string `"/buffers.glsl"` (as used in `#include "/buffers.glsl"`) corresponds to the contents of the file `buffer.glsl` (which you have loaded previously).
3. As you may have noticed in point (2), your paths need to start with `"/"`, like Linux-style absolute paths. This notation is generally unfamiliar to C programmers, and means you can't specify relative paths.

A common design is to implement your own `#include` mechanism, but this can be tricky since you also need to parse (and evaluate) other preprocessor instructions like `#if` in order to properly handle conditional compilation (like header guards.)

If you implement your own `#include`, you also have some liberties in how you want to implement it:

* You could pass strings ahead of time (like `GL_ARB_shading_language_include`).
* You could specify an include callback (this is done by DirectX's D3DCompiler library.)
* You could implement a system that always reads directly from the filesystem, as done in typical C applications.

As a simplification, you can automatically insert header guards for each include in your preprocessing layer, so your processor layer looks like:

```
if (#include and not_included_yet) include_file();

```

(Credit to Trent Reed for showing me the above technique.)

**In conclusion**, there exists no automatic, standard, and simple solution. In a future solution, you could use some SPIR-V OpenGL interface, in which case the GLSL to SPIR-V compiler could be outside of the GL API. Having the compiler outside the OpenGL runtime greatly simplifies implementing things like `#include` since it's a more appropriate place to interface with the filesystem. I believe the current widespread method is to just implement a custom preprocessor that works in a way any C programmer should be familiar with.

> **Comments:**
> **username_6**: Shaders can also be separated into modules using [glslify](https://github.com/glslify/glslify), though it only works with node.js.  
> **username_7**: What about just using the C++ preprocessor, which already can handle `#include`s and ´#if´s?  
> **username_5**: @username_7 you have to be a bit careful because it might not handle GLSL specific things correctly, like #version and #extension  

---

### Answer by username_8 on 2015-08-07. Score: 11

I generally just use the fact that glShaderSource(...) accepts an array of strings as it's input.

I use a json-based shader definition file, which specifies how a shader (or a program to be more correct) is composed, and there I specify the preprocessor defines I may need, the uniforms it uses, the vertex/fragment shaders file, and all the additional "dependency" files.
These are just collections of functions that gets appended to the source before the actual shader source.

Just to add, AFAIK, the Unreal Engine 4 uses an #include directive that gets parsed and append all the relevant files, before the compilation, as you were suggesting.


---

### Answer by username_9 on 2015-08-07. Score: 5

I don't think there is a common convention, but if I'd take a guess, I'd say that almost everyone implements some simple form of textual inclusion as a preprocessing step (an `#include` extension), because it is very easy to do so. (In JavaScript/WebGL, you can do that with a simple regular-expression, for example). The upside of this is that you can perform the preprocessing in an offline step for "release" builds, when the shader code no longer needs to be changed.

In fact, an indication that this approach is common is the fact that an ARB extension was introduced for that: [`GL_ARB_shading_language_include`](https://www.opengl.org/registry/specs/ARB/shading_language_include.txt).
I'm not sure if this became a core feature by now or not, but the extension was written against OpenGL 3.2.

> **Comments:**
> **username_5**: GL_ARB_shading_language_include is not a core feature. In fact, only NVIDIA supports it. (http://delphigl.de/glcapsviewer/listreports2.php?listreportsbyextension=GL_ARB_shading_language_include)  

---

### Answer by username_10 on 2015-08-08. Score: 4

Some people have already pointed out that `glShaderSource` can take an array of strings.

On top of that, in GLSL the compilation (`glShaderSource`, `glCompileShader`) and linking (`glAttachShader`, `glLinkProgram`) of shader is separate.

I have used that in some projects to split shaders between the specific part, and the parts common to most shaders, which is then compiled and shared with all shader programs. This works and is not difficult to implement: you just have to maintain a dependency list.

In terms of maintainability though, I am not sure it is a win. The observation was the same, let's try to factorize. While it indeed avoids repetition, the overhead of the technique feels significant. Moreover, the final shader is more difficult to extract: you cannot just concatenate the shader sources, as the declarations end in an order that some compilers will reject, or will be duplicated. So it makes it more difficult to do a quick shader test in a separate tool.

In the end this technique addresses some DRY issues, but it's far from ideal.

On a side topic, I am not sure if this approach has any impact in terms of compilation time; I have read that some drivers only really compile the shader program on linking, but I haven't measured.

> **Comments:**
> **username_5**: From my understanding, I think this does not solve the problem of sharing struct definitions.  
> **username_10**: @username_5: yes you are right, only instructions code is shared this way, not declarations.  

---

