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.
you may have array of structs uniforms (
uniform lightinfo glight[numlights], numlights compile-time constatnt), arrays not different declaringuniform lightinfo glight0, glight1....you uniform location via full name, eg:
glgetuniformlocation(program, "glight3.spotexponent")
note
glgetactiveuniformreturn string element 0 size give number of elements.uniform buffers important lots of lights , attributes. can store data structs on gpu, doesn't sent every time individual calls
gluniform*. can useglmapbuffermodify 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
elements aligned whopping big 16 byte boundaries (vec4 size). make struct more efficient, should pair
vec3sfloats.
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
Post a Comment