3
\$\begingroup\$

I'm new to OpenGL and GLSL, and bit confused about calling conventions of shader functions.

I'm trying to implement various procedural noise algorithms in GLSL. I'd like to have separate files for each noise and call these functions inside other fragment shaders.

Let say I have 2 files perlin.glsl and simplex.glsl.

perlin.glsl consists of pnoise2, pnoise3, pnoise4

simplex.glsl consists of snoise2, snoise3, snoise4

I have another fragment shader marble.frag which calls both snoise2, pnoise2 and has a main()

  1. How do I call fragment shader functions inside other fragment shaders?

  2. Is this considered a good practice?

  3. Can you think of a better alternative?

Thanks

\$\endgroup\$
4
\$\begingroup\$

When uploading shader source, you may provide more than one string. The lines of the strings are concatenated into the full text source for the shader compiler.

You can thus emulate an include system (poorly) by putting the text of the required sources before the string with the main shader source.

This is the origin of the numbers before the line numbers you may see in shader error logs, it's simply the index in the string array that contains the faulting source.

If you do not control the shader compilation stage but control the program linking stage, you may also attach multiple shader objects of the same kind to a program. This however requires forward declaration of the functions used.

\$\endgroup\$
  • \$\begingroup\$ Thank you for your answer! Would I have to concatenate the required source for every shader that uses the noise functions? I think I'll end up with quite a few shaders using noise funcitons and wouldn't want to compile the same code over and over if I don't have to. \$\endgroup\$ – user1880907 Mar 2 '15 at 22:32
  • 1
    \$\begingroup\$ Not compiling the same code over and over is where "attach multiple shader objects to the same kind of program" comes in. you can compile both your noise functions and your actual shader to seperate vertex shader objects, and then link to the program doing: glAttachShader(progID, noise2shader_ID); glAttachShader(progID, myshader_ID); glCompileProgram(); as long as you don't have conflicting declarations within the shaders. \$\endgroup\$ – Wolfgang Skyler Mar 2 '15 at 23:54
  • \$\begingroup\$ @WolfgangSkyler Thank you for your reply, it helped a lot :) \$\endgroup\$ – user1880907 Mar 3 '15 at 0:25
  • \$\begingroup\$ Are there any performance drawbacks by linking together multiple shaders instead of combining their source code? Can the compiler perform the same optimizations in both cases? \$\endgroup\$ – Tara Jul 8 '16 at 1:10
  • 1
    \$\begingroup\$ @Dudeson As GLSL is compiled in the driver, it depends on the approach the vendor takes. Some vendors has historically even compiled all shaders twice, once at glCompileShader for early validation and again for real at glLinkProgram. I personally have not tested the performance at all. \$\endgroup\$ – Lars Viklund Jul 9 '16 at 17:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.