marciano wrote:
I haven't tried that but I think you could first render the transparent objects in some sort of ambient pass using the mode 'Blend' (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) and after that accumulate the lighting using 'AddBlended' (GL_SRC_ALPHA, GL_ONE) in multiple passes.
Hmm, you might be right, I'll give this technique a go -- it should only take a minute to set up in the pipeline!
[edit] I haven't tried it yet, but I think the math works out perfectly with this technique. Without any ambient lighting, you could just use zero/black in the initial alpha-blending pass.
Also, even if you render multiple lights per pass, you may still want to perform multiple passes (e.g. 16 lights with 8 per pass), in which case this technique is important for alpha-blending to always be available without placing limits on the number of lights per object.
A = Alpha
D = Diffuse texture
M = aMbient lighting
L# = Lighting
FB = existing Frame Buffer value
Single-pass algorithm:
FB = (M+L1+L2)*D*A + (1-A)*FB
Your multi-pass algorithm:
FB = M*D*A + (1-A)*FB
FB = L1*D*A + FB
FB = L2*D*A + FB
or on one line:
FB = L2*D*A + L1*D*A + M*D*A + (1-A)*FB
Which simplifies down to the original single-pass result of:
FB = (M+L1+L2)*D*A + (1-A)*FB
The only problem is I don't think this can be implemented with the current pipeline commands. I need to execute:
Code:
for each model
draw ambient pass
for each light
draw light pass
But the current pipeline commands will only allow me to execute:
Code:
for each model
draw ambient pass
for each light
for each model
draw light pass
which means the draw-ordering will be incorrect.[/edit]
Quote:
it breaks generality. Currently, light sources could for example have any number of projective textures (within the hw limits of course).
...
We could introduce the concept of simple lights which don't have projective textures or shadows. Those would be easy to handle in a single pass and could be vectorized nicely.
Yeah I didn't think about how flexible horde currently is with light shaders/materials... It
is possible to create complex lights right now that can't easily be batched together.
e.g. Putting a projected-texture-spotlight and a simple point-light into a single pass would make for very complex shaders!
I guess these "simple lights" could be similar in structure to GL's fixed-function lights? Or something slim like the existing lighting uniforms:
Code:
vec4 lightPos // radius in w
vec3 lightDir
vec3 lightColor
float lightCosCutoff
^If this is going to be turned into an array, you could probably move 'lightCosCutoff' into lightDir.w, and while we're at it, an extra parameter like a brightness-multiplier could be stored in lightColor.w (
seeing as vec3 uniforms will be placed in vec4 registers anyway).
Also, it would probably make sense to only batch lights that share the same shader and context.
Initially, you could also restrict batching for lights that have shadows. Later on this restriction could be lifted if the shadow mapping code is made more flexible.
Actually, in cases where lights can have extra parameters than what horde provides (i.e. not a "simple light"), you would probably have to restrict batching to lights of the same
material instead of same
shader, so, for example, the projected texture for both lights is the same.
This might actually alleviate the need for a definition of what a "simple light" is -- any non-shadow-casting light using light.material.xml will act like a "simple light" (in that they'll all get batched together, but not with custom lights or shadow-casters) -- and also allows custom lights to be batched together in the same manner.