#define in shader


I’m trying to port the levels shader from Brad Larsons GPUImage2, but I get an error when trying to run the node:

11.09.2016 09.29.15,987 ShadersTest-RByiV8[10957]: VuoGlPool.cc:879  VuoGlShader_printShaderInfoLog()  ERROR: 0:2: Invalid call of undeclared identifier 'LevelsControl'

It seems like the #define part of the fragment shader isn’t running/compiled from searching for the general error message, but I’m a bit stuck on how to figure this out, so any help would be greatly appreciated. The source for the shader:

 ** Gamma correction
 ** Details: http://blog.mouaif.org/2009/01/22/photoshop-gamma-correction-shader/

#define GammaCorrection(color, gamma)  pow(color, 1.0 / gamma)

 ** Levels control (input (+gamma), output)
 ** Details: http://blog.mouaif.org/2009/01/28/levels-control-shader/

#define LevelsControlInputRange(color, minInput, maxInput)     min(max(color - minInput, vec3(0.0)) / (maxInput - minInput), vec3(1.0))
#define LevelsControlInput(color, minInput, gamma, maxInput)   GammaCorrection(LevelsControlInputRange(color, minInput, maxInput), gamma)
#define LevelsControlOutputRange(color, minOutput, maxOutput)   mix(minOutput, maxOutput, color)
#define LevelsControl(color, minInput, gamma, maxInput, minOutput, maxOutput)  LevelsControlOutputRange(LevelsControlInput(color, minInput, gamma, maxInput), minOutput, maxOutput)

varying vec2 textureCoordinate;

uniform sampler2D inputImageTexture;
uniform vec3 levelMinimum;
uniform vec3 levelMiddle;
uniform vec3 levelMaximum;
uniform vec3 minOutput;
uniform vec3 maxOutput;

void main()
    vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
    gl_FragColor = vec4(LevelsControl(textureColor.rgb, levelMinimum, levelMiddle, levelMaximum, minOutput, maxOutput), textureColor.a);


The problem is that the #define doesn’t work when the GLSL code is embedded within C code. Whether you put the #defines inside or outside of the VUOSHADER_GLSL_SOURCE() macro, the C preprocessor gobbles them up before the GLSL code ever has a chance to use them.

A workaround is to avoid using the VUOSHADER_GLSL_SOURCE() macro and instead put the shader source in double quotes. Unfortunately then you have to put the quotes, newlines, and backslashes on each line of the shader code since the macro is no longer there to do it. The attached file gives an example.

Another way to avoid using the VUOSHADER_GLSL_SOURCE() macro is to put the part of the shader source with the #defines in a separate .glsl file and include that in the GLSL code within the node class. See for example noise3D.glsl which is included in vuo.scene.explode.c.

Feature request Import shaders in VIDVOX’s Interactive Shader Format (ISF) should make all this easier, since you’ll be able to implement a node class with just the one GLSL file instead of having to embed GLSL in C.

levels.c.zip (1.82 KB)

Thanks! It isn’t really occurring too often so it should be manageable. ISF support looks really interesting! Which release is it scheduled for?

ISF support is planned for Vuo 1.3.