Sign in to follow this  
catch

Blending Performance

Recommended Posts

Last night I threw together a 2d lighting scheme using a canvas (pbuffer) and some alpha blending. The looks are almost exactly what I wanted, however there was a substantial performance hit. Don't get me wrong, the performance is acceptable, but I suppose dropping from 400fps (without any kind of optimizations) to 80fps was enough to make me wonder how wrong I did it. Here's a screen shot: http://toa.nething-goes.com/images/screen_080107.jpg The only way I could get the proper results for colored lights was to first subtract pixels from the canvas, then to draw the color of light I wanted on top of that. Is this just the nature of the pbuffer and a lot of blending? Or is there a way to utilize blending to be faster? I read a bit about additive, multiplicative, and subtractive type blending. From the really few and far between postings I found on it, it seems subtractive is the faster way to go. Anyway, here's the blending functions I'm doing, and the draw order.. This is all off memory since the source is at home, I'm at work, but I'm pretty sure this is right. regular sprites: blend_src_alpha, blend_one_minus_src_alpha light(on pbuffer): blend_zero, blend_one_minus_src_color light: blend_src_alpha, blend_one_minus_src_alpha canvas: blend_src_alpha, blend_one_minus_src_alpha Thoughts?

Share this post


Link to post
Share on other sites
You've gone from a render time of 2.5 milliseconds to 12.5 milliseconds. If you've gone from 1 pass to 4 or 5, this is to be expected. By those four blend statements, do you mean that you have four passes? I think you could do it in just three -

-render scene to something
-render lighting to something else - additive blending
-multiply them together - multiplicative blending

but I'm not sure.

What passes do you do, exactly?

Share this post


Link to post
Share on other sites
Quote:
Original post by hoodedpaladin
You've gone from a render time of 2.5 milliseconds to 12.5 milliseconds. If you've gone from 1 pass to 4 or 5, this is to be expected. By those four blend statements, do you mean that you have four passes? I think you could do it in just three -

-render scene to something
-render lighting to something else - additive blending
-multiply them together - multiplicative blending

but I'm not sure.

What passes do you do, exactly?



1) Render Scene (blending here is src_alpha, one_minus_src_alpha)
2) Render blend zero step to canvas (to "lighten" area) (zero, one_minus_src_color)
3) Render light color. (src_alpha, one_minus_src_alpha)
4) Render canvas (src_alpha, one_minus_src_alpha).

I wish I could consolidate 2 & 3, but they're different blend functions. I've tried a lot of combinations, but I can't get it to be subtractive with a color component. Of course maybe I'm thinking of it wrong?

The real FPS drop comes from #3. If I skip that portion (no color), it's much faster.

EDIT: Hmm, I've tried rendering step 1 and 3 in the same pass, perhaps I should try that again. Before the results were poor, but I was likely doing something wrong.

Share this post


Link to post
Share on other sites
So, in pass 2 you draw grey on the pbuffer to make the ambient light? Couldn't you just clear it to grey? I wonder if that would be faster, or if it would take up fillrate like any other drawing would.

Share this post


Link to post
Share on other sites
Well, at step 2 I clear it to the ambient color, then I draw the first round of lights (subtractive) to remove away pixels, to lighten the stuff beneath it.

It's sort of like a fullscreen dark mask, that I subtract areas from (lights), to brighten. Then I render the color of the lights afterward (step 3) to achieve colored lighting.

Share this post


Link to post
Share on other sites
Okay, now I see what you're saying now about not being able to combine passes 2 and 3. You're working with an alpha channel on your lightmap, which isn't really necessary. Your method is like putting a colored screen in front of the scene to act as a light-reducer, but a lightmap already has information about how light a point should be, without needing an alpha channel.

This tutorial on Ron Frazier's site ( http://www.ronfrazier.net/apparition/ , click on research projects, then the "Per-Pixel Point Lights and Spot Lights" tutorial) illustrated the technique to me - the very last two pictures are a rendered lightmap, and the final lit scene created by multiplying the lightmap and the scene. It seems to me that this would require 3 passes at most - the scene, the lightmap, and multiplication.

BTW, just on an unrelated note, that lightmap is what inspired my latest efforts - levels that are simple geometrically, with blank, flat walls, defined only with a bunch of dynamic lights. I'm not sure I can pull it off anyways, my work on this isn't too serious at the moment.

Share this post


Link to post
Share on other sites
Quote:
Original post by hoodedpaladin
Okay, now I see what you're saying now about not being able to combine passes 2 and 3. You're working with an alpha channel on your lightmap, which isn't really necessary. Your method is like putting a colored screen in front of the scene to act as a light-reducer, but a lightmap already has information about how light a point should be, without needing an alpha channel.

This tutorial on Ron Frazier's site ( http://www.ronfrazier.net/apparition/ , click on research projects, then the "Per-Pixel Point Lights and Spot Lights" tutorial) illustrated the technique to me - the very last two pictures are a rendered lightmap, and the final lit scene created by multiplying the lightmap and the scene. It seems to me that this would require 3 passes at most - the scene, the lightmap, and multiplication.

BTW, just on an unrelated note, that lightmap is what inspired my latest efforts - levels that are simple geometrically, with blank, flat walls, defined only with a bunch of dynamic lights. I'm not sure I can pull it off anyways, my work on this isn't too serious at the moment.


First, let me say thanks for your responses on this.

I have seen the Frazier demos, but they are based around register combiners, aren't they? I had opted not to use register combiners because of the Nvidia-only requirement, and they're quite old.

I would do GLSL beyond that, but I was hoping by using a trick like this to get 80% of the results I wanted, I'd have even lower hardware requirements.

But I may be mistaken on the register combiners thing.

Share this post


Link to post
Share on other sites
Yeah, the rest of Ron's tutorial is pretty obsolete.
I use GLSL for per-pixel lighting.
You can just draw textured circles additively onto a pbuffer. All I was talking about is the way Ron combines a lightmap with the scene to shade it, not the way he does the shading. After you draw the lightmap, you draw the rendered scene onto it using a blend function that will multiply the images together (I forget what it is; you probably know it).

Share this post


Link to post
Share on other sites
im sure u could simplfy it down heaps than what u have

draw scene normally
->enable blending (u will have to experiment what modes perhaps GL_SRC_COLOR, GL_ONE)

loop through lightareas
- draw lightarea circle in a plain color

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this