[osg-users] Pragmatic shader - a new #pragma directive proposition

Sebastian Messerschmidt sebastian.messerschmidt at gmx.de
Thu Jan 14 00:52:59 PST 2016


Hi Robert,

This seems more complicated than needed.
Why not pass the number of lights as a compile time constant

#pragma import_defines (NUM_LIGHTS)

shader_state->setDefine("NUM_LIGHTS",12);

and use uniform arrays:

uniform vec4 u_LightColor[NUM_LIGHTS];

for (int i = 0; i < NUM_LIGHTS;++i)
{
     light+=calcLight(u_LightColor[i], ...):
}

I feel your approach will bloat the preprocessor code path and will 
complicate the use.



> Hi all,
>
> With the pragmatic shader one could implement multiple lights and 
> other repetitive constructs like this:
>
> -- start of shader code --
> #pragma import_defines ( LIGHTING, LIGHT0, LIGHT1 )
>
> #ifdef LIGHTING
>   #ifdef LIGHT0
> uniform vec4 u_LightColor0;
>   #endif
>   #ifdef LIGHT1
> uniform vec4 u_LightColor1;
>   #endif
>
> varying vec4 basecolor;
>
> void light( in vec4 lightColor, inout vec4 color );
> #endif
>
> void main(void)
> {
>     basecolor = gl_Color;
>
> #ifdef LIGHTING
>   #ifdef LIGHT0
>     light( u_LightColor0, basecolor);
>   #endif
>   #ifdef LIGHT1
>     light( u_LightColor1, basecolor);
>   #endif
> #endif
>
>     gl_Position   = gl_ModelViewProjectionMatrix * gl_Vertex;
> }
> -- end of shader code --
>
> ... and to enable both lights:
>
> stateset->setDefine("LIGHTING");
> stateset->setDefine("LIGHT0");
> stateset->setDefine("LIGHT1");
>
> The problem with this approach is that nobody really knows in advance 
> how many more lights will be needed. Moreover, the shader can get 
> heavily bloated when more and more lights are added. As a solution I 
> would like to propose a new #pragma construct:
>
> #pragma repeat_begin( DEFINE_IDENTIFIER${SubstitutionParameter} )
> (shader code block)
> #pragma repeat_end()
>
> ... and the shader code supporting arbitrary number of lights would 
> then look like this:
>
> -- start of shader code --
> #pragma import_defines ( LIGHTING, LIGHT${Member} )
>
> #ifdef LIGHTING
> #pragma repeat_begin( LIGHT${Member} )
> uniform vec4 u_LightColor${Member};
> #pragma repeat_end()
>
> varying vec4 basecolor;
>
> void light( in vec4 lightColor, inout vec4 color );
> #endif
>
> void main(void)
> {
>     basecolor = gl_Color;
>
> #ifdef LIGHTING
> #pragma repeat_begin( LIGHT${Member} )
>     light( u_LightColor${Member}, basecolor);
> #pragma repeat_end()
> #endif
>
>     gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
> }
> -- end of shader code --
>
> ... where ${Member} is a substitution parameter and LIGHT is define 
> identifier. Then with:
>
> stateset->setDefine("LIGHTING");
> stateset->setDefine("LIGHT${0}");
> stateset->setDefine("LIGHT${1}");
> stateset->setDefine("LIGHT${5}");
>
> ... where ${0}, ${1}, ${5} are substitution values, osg would produce 
> following shader code:
>
> -- start of shader code --
> #define LIGHTING
> #define LIGHT0
> #define LIGHT1
> #define LIGHT5
>
> #ifdef LIGHTING
> uniform vec4 u_LightColor0;
> uniform vec4 u_LightColor1;
> uniform vec4 u_LightColor5;
>
> varying vec4 basecolor;
>
> void light( in vec4 lightColor, inout vec4 color );
> #endif
>
> void main(void)
> {
>     basecolor = gl_Color;
>
> #ifdef LIGHTING
>     light( u_LightColor0, basecolor);
>     light( u_LightColor1, basecolor);
>     light( u_LightColor5, basecolor);
> #endif
>
>     gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
> }
> -- end of shader code --
>
> Before I do any coding I'd like to know if proposed solution would be 
> of any use to the osg community? Or maybe there is a better way? I'm 
> currently solving these kinds of problems with uniform arrays, but 
> unfortunately, the uniform array has its own max number of elements 
> and the management code of such approach tend to be complicated...
>
> Cheers,
> Robert Milharcic
>
> _______________________________________________
> osg-users mailing list
> osg-users at lists.openscenegraph.org
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org



More information about the osg-users mailing list