opengl - glsl multi light, best practice of passing data (array of structs?) -


working myself step step trying figure out more multi lights in glsl. read tutorials far none seems have answer this.

lets have such struct lighting:

struct lightinfo                                                            {       vec4 lightlocation;                                                                         vec3 diffuselightcolor;     vec3 ambientlightcolor;     vec3 specularlightcolor;     vec3 spotdirection;     float ambientlightintensity;     float specularlightintensity;     float constantattenuation;     float linearattenuation;     float quadraticattenuation;     float spotcutoff;     float spotexponent; }; uniform lightinfo glight; 

my first idea make

uniform lightinfo glight[numlights]; 

but read lot passing data way shader wouldn't work, since can't location of that. have admit didn't try myself yet, found couple of pages mentioning this, it's not wrong - or maybe outdated information?

the other idea make just:

uniform[numofargs] 

and split in shader again, if take example struct above have immense huge array soon, , taking information out of loop quite expensive too- , if want use similar number of lights max of 8 when using gl_lightsource - while wanted avoid using because of advantage having own struct information needed @ once.

of course not light in question require many parameters, light require them (and if stripping quite grow also). yet again use qsort first determine closest lights, limiting maxlights 3 (something suggested on many places), here again have expect bit more nowadays glsl , modern hardware although there no contradiction in using well, unrelated chosen solution.

so question now, what's best practice here, what's fast? or should stay gl_lightsource , passing additional information via uniform array? although doesn't seem make more sense me either.

the idea of light struct fine. forward rendering - passing lights 1 shader processes actual geometry - array fine.

  1. you may have array of structs uniforms (uniform lightinfo glight[numlights], numlights compile-time constatnt), arrays not different declaring uniform lightinfo glight0, glight1....

    you uniform location via full name, eg:

    glgetuniformlocation(program, "glight3.spotexponent")

    note glgetactiveuniform return string element 0 size give number of elements.

  2. uniform buffers important lots of lights , attributes. can store data structs on gpu, doesn't sent every time individual calls gluniform*. can use glmapbuffer modify parts of buffer if rest doesn't need changing.

    be aware of how structs , arrays packed (it's not intuitive)! related issues occur in non-uniform/uniform block cases too.

    see: sub-section 2.15.3.1.2 - standard uniform block layout

    to byte offset beginning of block, use gl_uniform_offset​ enum

    see: uniform buffer object

  3. elements aligned whopping big 16 byte boundaries (vec4 size). make struct more efficient, should pair vec3s floats.

you're right, if have more lights there in shader you'll have chop , choose. lights close important, might want prioritize lights in direction you're facing (those area of influence touches viewing volume formed projection matrix) , bigger/brighter lights (eg. sun/directional).

ultimately if have many lights method ceases work. next step swap deferred shading, brings few more issues (eg. blending/transparency).


Comments

Popular posts from this blog

java - WrongTypeOfReturnValue exception thrown when unit testing using mockito -

php - Magento - Deleted Base url key -

android - How to disable Button if EditText is empty ? -