[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