Hi Sebastian ,

On 14.1.2016 15:47, Sebastian Messerschmidt wrote:
Am 14.01.2016 um 15:01 schrieb Robert Milharcic:
Hi Sebastian,

First of all, the lightning shader only illustrates one of the cases where 
(optionally) repeating a code block containing substitution parameter can be 
useful. I used the multi-light lightning as an illustration only.

First, thank you for your input. Yes, that is more or less the same approach 
I'm currently using. The downside of this approach is that it requires 
additional nontrivial code logic for the uniform array management 
(u_LightColor) and that is why I started to look at the alternatives.
What could be more complicated there than to setup individual uniforms? Sorry 
this doesn't pass as a valid argument. If you have to hold the number of used 
lights somewhere you can hold a reference to the uniform as well.


Sorry, but that is not what I had in mind.  The problem here is the management of the array 
uniform's content and not the reference to it or the light count etc. Let say I only want to 
disable one of the lights, say LIGHT0 eg. stateset->setDefines("LIGHT0", 
osg::StateAttribute::OFF). What will you do?
Let's say you have a fixed maximum on N, than you create a UBO/Array of this 
size and provide a count-uniform for the maximum valid entries.
If a light gets disabled, you simply remove it, copy it to the back and set 
your count to N-1.
In the shader you simply loop from 0 to count instead of N. That might break 
compiler optimization, but it won't hurt too much I guess.
When using the setDefine, OSG will have to issue a recompile of this new 
variant, which will degrade performance if all combinations are needed.

Assume 16 Lightsource, that will produce 65536 possible shader programs ... and 
that is only 16, not 500, or 1000 ...
Having 1024 individually switchable Lightsources would totally wreck your idea 
of having an alternative to my solution.
2^1024 might exceed the numbers of atoms in the known universe, so there is not 
a remote chance to solve this with shader combinations...


The question was purely rhetorical. I just wanted to prove my point regarding the 
uniform's content management vs already provided setDefines("LIGHT0", 
osg::StateAttribute::OFF). I didn't expect all that. Sorry for the fuzz :)  BTW, I'm not 
planing to toggle all possible on/off combinations just to see all the permutations, the 
normal graph usage is what I'm after.


There is also an upper limit for the size of the array that needs to be taken into account.
At least 512. If this is not enough you can use Uniform buffer objects (UBO)[1] 
or Shader Storage Blocks[2] which support
If this is not enough for your light-count you will probably hit performance 
problems first.


Yes, that is true. The upper limit is not a problem for this specific 
multi-light problem.
Even so, UBOs support in the order of ten-tousands. If this is still isn't 
enough, a texture will provide maximum space.
Might be your example, but the number of individual uniforms is less than that. 
And putting a heap of uniforms into the stateset will fasten the handbrake on 
the CPU side.

Also, the loop represents unnecessary overhead (though, this is not a problem on a never hardware).
That's an assumption of yours. Usually constant folded loops with single return 
and without break, continue-statements are unrolled by the compiler.
I'll accept performance comparisons however ;)


Yes, you are right about that. The constant loop will most probably be unrolled 
by the compiler. Of courses, that is another assumption on top of the previous 
assumption :)

On the other hand, my suggestion fits well into existing pragmatic shader 
composition logic and probably has less downsides.

Downside is that you're trying to invent a meta-language here out of reasons 
that I commented on. The downside of your approach is a preprocessor language 
with no clear advantages over the tools already at your disposal.
So to say, the current language is already turing-complete and you're trying to 
put some syntactic sugar on top, which adds some high degree of complexity to 
the parser and to the shader-code.

Exactly, that was my intention, to add a higher degree of complexity and hopefully solve 
some problems that "turing-complete" language can't.
Turing complete solves all computable problems ;-)
I do understand your motivation, but I still don't see the gain really.
I've presented some alternative ways to solve your problem, as I came across 
some of those challenges too.
The idea Robert mentioned might be a good one, basically we could use some kind 
of callback to let the user-code preprocess the shader, wait actually we can 
already do this, when it is loaded via a LoadCallback :-)
Actually I'm preprocessing my shader code when it's loaded to perform "include" and 
automated shader-define setup, so this might work for your "loop" too.


That would defeat the purpose of the #pragma(tic) shader composition. You may 
then as well pre-parse #pragma import_defines and #pragma requires and 
pre-generate all the shader permutations. The purpose of #pragma(tic) shader 
composition is shader generation based on current define set (see the 
osg::State).

Cheers
Robert Milharcic
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to