PDA

View Full Version : Multipass, Blending and Z-Order


Hydrael
05-07-2006, 11:36 PM
Hello everyone,

I've recently implemented a per Pixel lighting shader for multiple lights within my engine. At the moment, it's one rendering pass per light in view. Each pass, the scene is rendered with texturing disabled and blendmode (GL_ONE,GL_ONE) active (additive blending). After that's done, I have all the lighting information for the active frame.
That result will then be multiplied (GL_ZERO, GL_SRC_COLOR) with another pass with texturing enabled and lighting disabled to create the final image.

The problem I now have, is that I do get some Z-Order issues (or is it transparency due to the blending?). Here is what I mean (the right image shows the same spot with normal fixed function pipeline lighting (single pass)):

http://img271.imageshack.us/img271/9079/blending17tv.jpg

Here is the responsible piece of code from my rendering loop:
glEnable(GL_LIGHT0);
glBlendFunc(GL_ONE,GL_ONE);
glEnable(GL_BLEND);

m_pPerPixelShader->Activate();
for(int i=0;i<m_iActiveLightCount;i++)
{ //Lighting passes
ActivatePerPixelLight(i);
RenderBruteForce(RENDERLIGHTING);
}
m_pPerPixelShader->Deactivate();

glDisable(GL_LIGHT0);
glBlendFunc(GL_ZERO,GL_SRC_COLOR);
glEnable(GL_TEXTURE_2D);
RenderBruteForce(RENDERTEXTURED); //Textured pass
glDisable(GL_BLEND);


I'm using DepthFunc(GL_LEQUAL), because nothing else seems to work for the additive blending.

Can anyone spot, what I'm doing wrong?
Thanks in advance

Chris

juhnu
05-08-2006, 12:45 AM
You need to render a z-only pass with the color writes disabled, before rendering your lights.

Hydrael
05-08-2006, 01:27 AM
Great, thank you!
Could you by any chance tell me the syntax, on how to enable/disable writing to the color buffer, since I haven't done that yet?

juhnu
05-08-2006, 01:31 AM
glColorMask()

Hydrael
05-08-2006, 01:33 AM
Thanks a lot - I'll give it a try, as soon as I get home from work ;)

Reedbeta
05-08-2006, 03:09 AM
By the way, your FPS counter shows you only getting 25 fps on the pixel-lit scene - it "should" be far more than that if you're only doing one light. Just letting you know that there's plenty of room for optimization, when you get around to that ;)

Hydrael
05-08-2006, 03:52 AM
Yes, I know ;)

At the moment the whole pixel thingy is just plugged in to see if it works ;)
Right now I'm i.e. really rendering one pass per light - later, I will process 2-3 lights in the shader to reduce passes. The screenshots above use approx. 3 lights.

Furthermore my spatial partitioning (AABBTree) is currently disabled due to recent changes within my map file format (I was too lazy to reimplement that again yet). I'm just using some simple frustum culling here (that's why my rendering function is called "RenderBruteForce" atm) ;)

As soon as I'm done experimenting and get my lazy back up again, the framerate with using per-pixel lighting will at be least tripled ;)

Edit: Ok, it works now:
http://img174.imageshack.us/img174/4365/blendok1fe.jpg

Thanks again :yes:

Hydrael
05-09-2006, 11:47 PM
Another thing regarding performance:

Over at Gamedev.net I've just read of the possibility to use textures (http://www.ronfrazier.net/apparition/index.asp?appmain=research/per_pixel_lighting.html) for attenuation calculaton.
With that in mind, I could drop the attenuation calculations within my lighting shader and probably increase performance by another good bit :happy:

Reedbeta
05-10-2006, 01:40 AM
It depends if your shader is compute limited or texture bandwidth limited. If it is the latter, then adding another texture lookup won't help. Generally a simple lighting shader is going to be texture limited. In my experience I have found that it doesn't really help to do things like attentuation or dot product calculations using textures. By all means try it though :yes:

EDIT: Just FYI, the website you linked to is really old. It describes using register combiners, one of the precursors of modern pixel shaders, where you HAD to do the attentuation with a texture because the pixel pipeline didn't have enough generality to compute it directly.

bladder
05-10-2006, 01:45 AM
It depends if your shader is compute limited or texture bandwidth limited. If it is the latter, then adding another texture lookup won't help. Generally a simple lighting shader is going to be texture limited. In my experience I have found that it doesn't really help to do things like attentuation or dot product calculations using textures.

Unless you're targeting ps1.x hardware, then you kinda need that attenuation map.

Hydrael
05-10-2006, 01:58 AM
Yeah, seems like I posted a bit too fast - I've now also read, that this technique was used back in PS1.x days and is outdated nowadays.

But I guess I'll give it a try anyway...out of interest ;)

Axel
05-11-2006, 01:38 PM
Modern hardware has an ever increasing ALU/TEX-Ratio. If its not uber-complex you very likely will do best doing the calculations in the shader instead of using a LUT.

.oisyn
05-12-2006, 05:00 AM
However, using a texture enables you to create cool lighting effects as you can specify your own distance-attenuation curve. We used it in Tomb Raider: Legend as well :)