...

3 Likes

Sounds good!

Did you test it?



@Momoko_Fan what do you think?

Interesting.

However that sound a bit too good to be true…

There might some huge drawback that we don’t see…

yeah, I’m feeling a bit uneasy about this… not sure why…

yeah but if you’re right, why isn’t that massively used?

In any case that worth the try.



we need the number of light, then for each light its type, direction or position or both, the inner and outer angles for spot lights and the range for point lights.



@kwando how do your send your light data to the shader in your deferred rendering process?

@nehon Currently it’s done with shader uniforms, every point light is rendered as a separate geometry.



In the case of point lights my shader needs to know light position, color and radius of the light. One idea I’ve had is to encode color, position and radius into vertex buffers. Some light attributes will be repeated for every vertex in the lightvolumedata, but it will allow me to batch all point lights into a single draw call since I’m not using shader uniforms for the light attributes. Not tried this idea out yet but at least in my mind it would work.



My idea won’t work with this singlepass technique though.

Maybe this is just my “old school” lore creeping in, but something about dynamic for() loops in a shader rings alarm bells for me.

@pspeed said:
Maybe this is just my "old school" lore creeping in, but something about dynamic for() loops in a shader rings alarm bells for me.

Maybe but, compared to doing another full render pass, I guess we're safe....
@nehon said:
Maybe but, compared to doing another full render pass, I guess we're safe....


No, I mean that some GPUs won't be able to do the loop at all because it can't be unrolled. Maybe this is obsolete lore now.

I don’t know tbh. Anyway, we could have the actual code for a fallback for old gpus…

A google search of using non-constant conditions in for loops in GLSL pulls back some hits but the most recent are 4 or 5 years old. Maybe this really isn’t an issue anymore (and never seemed to be an issue except on ATI cards anyway) but when we have some ATI cards that can’t even do early returns it makes me wonder what percentage of viable cards actually support this.



I will defer to @Momoko_Fan, though. All of my “accepted lore” is 5+ years old.

There are still GPUs that are not capable of looping non constant number of times.

Also, since this requires texture buffer support, this also takes some GPUs out of the equation.

I think the best approach is to have a uniform array of light data (2 vec4s), where the lighting direction is computed in the fragment shader, we can pass the number of lights as a define but that might complicate the material’s single pass render method…

You can see an approach of what Momoko_Fan describes in the RealSlimShader project. See LightingSP_POM.frag for example.



Edit: The single pass shader suffers a bit from the overhead of doing stuff in the fragment unit (because of the varying limit) that with multi-pass can be done in the vertex unit (light vector calculation, TBN transformation, …). The break even is somewhere between 2 and 4 lights. And with 4 lights, there are a lot of opportunities to use vector commands (SIMD). I’m wondering if a multi pass shader that does 4 lights per pass would be good.

I switched to single pass only because the shaders I write does a lot of other things besides lights (simple animation, fading calculations). This is done per vertex, and it feels somewhat unneccesary to repeat that process once for each light, when all it would produce is the same results over and over.



Non-light stuff has to be taken into account as well.