1
votes

Here is the deal, I want to make a particle system based on textures and I have a cloud texture. I map the texture to 10 different polygons each having same size and textures. when I blend them over each other, a problem rises and pixels which are in say 5 polygons become too white! i don't want this. What I want is something like accumulation buffer's effect. I want to take an effect like this:

say Rx,Bx,Gx be each pixels color when only 1 polygon is in page and pixel is inside it. Now we have n polygons each having same size and texture.

Rtotal = R1/n+R2/n+...+Rn/n same for Gtotal and Btotal

What can I do to get such results from alpha blending.

BTW here is the initialization.

glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glEnable(GL_DEPTH_TEST) ;
glDepthFunc(GL_ALWAYS);

glEnable(GL_NORMALIZE);
glColor4f(.5,.5, .5,.2); 
glBlendFunc (GL_SRC_ALPHA, GL_DST_ALPHA);
1
You forgot to tell your target OpenGL version.Kos
You could do a two pass solution with shaders, where you count the number of particles in each fragment in the first pass. Then you can do the divide the way you described.Plow
Sounds like a cool answer :D but is hard for me cause i am new to shaders.Amir Zadeh

1 Answers

2
votes

It's difficult to make the result exactly as you want it to be, as you'd need to know for each pixel how many fragments were there.

If it's enough for you to make the particles look OK, then it should be enough to change the blending mode.

They are accumulating to white because you probably are using additive alpha blending:

result = source_color*source_alpha + destination_color

Or plain additive blending:

result = source_color + destination_color

(where source is "the color of a given fragment" and destination is "what was already in the framebuffer in that place").

Both of those decay to white with a lot of "layers". But you can use "true" alpha blending:

result = source_color * source_alpha + destination_color * (1-source_alpha)

which will not decay to white.

In OpenGL, this corresponds to:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

That's not exactly what you wanted since the result will be order-dependent, but it should be 100% sufficient for a particle system. Hope that helps.

(Also, don't forget to render the solid geometry before the particles and disable z-write then.)