fillrate question
Hey everyone.
I have a question about fillrate. I have particle-based explosions in my 3D game that look really good when viewed from a distance. When the camera is up close to the explosions, however, the fillrate causes the framerate to drop into the single digits (GeForce 2 MX 400).
I''d like to know what I can do to avoid this slowdown. Are there any good strategies for avoiding fillrate-related slowdown? Or is it an avoidable "part of life" when rendering textures that fill large portions of the screen?
Thanks,
--Hoozit.
----------------------
Check out my game demo and resume at
www.fivestory.com/projects/game.
quote:
Are there any good strategies for avoiding fillrate-related slowdown?
Yes, buy a new 3D card
Seriously, that''s about the only thing you can do. You can try to enable alpha testing, so that totally transparent parts of the particle texture get culled away by the alphatest, before reaching the more expensive blending stage. That will save you some fillrate, but don''t excpect too much.
if your particle clouds are rather dense (it looks like they are, mostly white in the middle), you could there cull away inner particles and replace by one bigger (simply a white one).. so you could save there overdraw of tens/houndreds of particles that get white in the end anyways.
i don''t know your api, but if you use opengl, you could use the register_combiner extension to actually calculate your spherical "fluffy"texture, instead of mapping one onto it. yes, a primitive procedural texture that is. when i tested this, it speed up my rendering by over 50%, just because it was not actual fillrate, but texture sampling rate, too, wich made it go slow..
about the sphere generation..
assume this:
to be your particle.. in the center (marked with ''o''), we would have pos 0,0, left top -1,-1, right bottom 1,1 (or something like this..
now you can do simplest distance attentuation by having the vector to_center wich points from your current drawing pixel to o, and calculating this:
dst_att = unsigned(1 - x*x + y*y);
now, your coords are _not_ from -1 to 1, but from 0 to 1. so you have to get them in like that.. and then use expand_normal(coord) to get them as they should be..
i used a simple glColor(xcoord,ycoord,0); per edge to send over the coords, then
const0 = the actual particle color.. something bright.. yellow for example (you can set it from external sources.. or use SecondaryColor..)
rgb {
spare0 = expand_normal(col0) . expand_normal(col0);
}
out.rgb = const0;
out.alpha = unsigned_invert(spare0);
(this is no valid nvparse code, i''m quite a bit rusty.. having radeon9700)
but i think you use dx, right? then i''m not sure if you can get this working.. but even there, it should be possible..
for me, it doubled the fps on my gf2mx.. that was quite an amazing feeling..:D
"take a look around" - limp bizkit
www.google.com
i don''t know your api, but if you use opengl, you could use the register_combiner extension to actually calculate your spherical "fluffy"texture, instead of mapping one onto it. yes, a primitive procedural texture that is. when i tested this, it speed up my rendering by over 50%, just because it was not actual fillrate, but texture sampling rate, too, wich made it go slow..
about the sphere generation..
assume this:
x---x| o |x---x
to be your particle.. in the center (marked with ''o''), we would have pos 0,0, left top -1,-1, right bottom 1,1 (or something like this..
now you can do simplest distance attentuation by having the vector to_center wich points from your current drawing pixel to o, and calculating this:
dst_att = unsigned(1 - x*x + y*y);
now, your coords are _not_ from -1 to 1, but from 0 to 1. so you have to get them in like that.. and then use expand_normal(coord) to get them as they should be..
i used a simple glColor(xcoord,ycoord,0); per edge to send over the coords, then
const0 = the actual particle color.. something bright.. yellow for example (you can set it from external sources.. or use SecondaryColor..)
rgb {
spare0 = expand_normal(col0) . expand_normal(col0);
}
out.rgb = const0;
out.alpha = unsigned_invert(spare0);
(this is no valid nvparse code, i''m quite a bit rusty.. having radeon9700)
but i think you use dx, right? then i''m not sure if you can get this working.. but even there, it should be possible..
for me, it doubled the fps on my gf2mx.. that was quite an amazing feeling..:D
"take a look around" - limp bizkit
www.google.com
as if i would have nothing else to do, i set a demo up for you, so you can test and compare.. the whole thing is based on nuttys particle demo, you can find it here:
billboard.zip
on opengl.nutty.org
you need openil to run it. it is distributed in my zip, so download this one as well, wich is my pixelshader generated spherical particles:
Billboard2.zip
sure, his one has particles with nice animations.. but, at least here at work, the comparison is about this:
his demo: 14fps when all particles on screen
my demo: 36fps when all particles on screen
thats quite some speedboost. in short: never use textures if you don''t really need to..
btw, brightness can get adjusted from 1 to 2, so you can get overright particles.. the red ones are brightness 1.5... the rest is grabbing the colors from his demo..
i''ll contact him when he''s online later so he''ll possibly implement my one as well, so we get a switch button to change at runtime and compare..
"take a look around" - limp bizkit
www.google.com
billboard.zip
on opengl.nutty.org
you need openil to run it. it is distributed in my zip, so download this one as well, wich is my pixelshader generated spherical particles:
Billboard2.zip
sure, his one has particles with nice animations.. but, at least here at work, the comparison is about this:
his demo: 14fps when all particles on screen
my demo: 36fps when all particles on screen
thats quite some speedboost. in short: never use textures if you don''t really need to..
btw, brightness can get adjusted from 1 to 2, so you can get overright particles.. the red ones are brightness 1.5... the rest is grabbing the colors from his demo..
i''ll contact him when he''s online later so he''ll possibly implement my one as well, so we get a switch button to change at runtime and compare..
"take a look around" - limp bizkit
www.google.com
Davepermen: nice idea. Texture fetching is definitely expensive, so it doesn''t suprise me that your trick doubled your FPS. Unfortunately, it only lets you create spherical particles, but for most standard particle systems that should be all one needs anyway.
more is possible, depending on hw.. :D but yes, mainly spherical particles. but boosting them is quite useful anyways, as, as you said, most engines do use at some point spherical particles. and then its useful to boost the drawing speed..
btw, i was shocked to see that it boosts that much. initially i just wanted to try to do some effect with register combiners. then i realized how slow textures where on gf2 (by messing up combiners but seeing holy fast drawings..:D), so i tried this one..
it''s cool.
"take a look around" - limp bizkit
www.google.com
btw, i was shocked to see that it boosts that much. initially i just wanted to try to do some effect with register combiners. then i realized how slow textures where on gf2 (by messing up combiners but seeing holy fast drawings..:D), so i tried this one..
it''s cool.
"take a look around" - limp bizkit
www.google.com
What texture filtering are you using?
nVidia claims that tri-linear filtering cuts fill rate in half. For particles you probably don''t need mip-filtering to be anything more than POINT.
nVidia claims that tri-linear filtering cuts fill rate in half. For particles you probably don''t need mip-filtering to be anything more than POINT.
doesn''t really mather.. well it does, but not that much..
no textures is much much faster..
"take a look around" - limp bizkit
www.google.com
no textures is much much faster..
"take a look around" - limp bizkit
www.google.com
Wow, davepermen, thanks for the attention. I downloaded and ran your particle demo. It ran at 82 fps on my GeForce2 MX.
I am using DX 8, not OpenGL, and I am unfamiliar with register combiners, but I''ll read up on them and see if I can determine the appropriate DX methods. I''ll spend some time with your code (and Nutty''s code) as well.
to AP: I turn off all filtering before rendering the particle quads. So mag, min, and mip filtering are all set to D3DTEXF_NONE.
Thanks,
--Hoozit.
----------------------
Check out my game demo and resume at
www.fivestory.com/projects/game.
I am using DX 8, not OpenGL, and I am unfamiliar with register combiners, but I''ll read up on them and see if I can determine the appropriate DX methods. I''ll spend some time with your code (and Nutty''s code) as well.
to AP: I turn off all filtering before rendering the particle quads. So mag, min, and mip filtering are all set to D3DTEXF_NONE.
Thanks,
--Hoozit.
----------------------
Check out my game demo and resume at
www.fivestory.com/projects/game.
Another nice fillrate saving trick I heard about recently (I think from Tom Forsyth, though credited to Jan Svarovsky):
If what your particles have lots of opaque pixels in their texture, you can render them in two passes using alpha test and Z buffering to reduce fillrate problems. Consider what the alpha channel for a particle texture. Every O below is 100% opaque, i.e. Alpha=1.0 or Alpha=255. Every A below is some Alpha value less than 255 and greater than 0, i.e. some transparency. Every X below is a totally transparent pixel (Alpha=0)
Pass #1:
- Enable alpha test
- Enable Z buffer writes
- Set the alpha test mode to pass when alpha=255
- Render all particles
This renders all the O pixels in the texture above.
Alpha test happens before any Z buffer write or blending, so all the A and X pixels take no fillrate at all. Because Z buffering is enabled, no unnecessary blending takes place.
Pass #2:
- Enable alpha test
- Disable Z buffer writes
- Set the alpha test mode to pass when alpha<255
- Render all particles
This renders all the X and A pixels and ignores all the O''s. The only fillrate consuming overdraw comes from the X and A pixels.
So using the example above, of the 48 pixels being rendered, only 28 will ever overdraw.
This method has the nice side effect of having the most noticable parts of the particle (the opaque bit) Z distance correct.
You could also combine that with the methods suggested by others above.
Depending on what you''re doing another idea is to take advantage of frame to frame coherence and render the particles to a texture over time so that as the density of the particles (in a smoke system for example) grows, you don''t re-render particles which were born earlier.
--
Simon O''Connor
Creative Asylum Ltd
www.creative-asylum.com
If what your particles have lots of opaque pixels in their texture, you can render them in two passes using alpha test and Z buffering to reduce fillrate problems. Consider what the alpha channel for a particle texture. Every O below is 100% opaque, i.e. Alpha=1.0 or Alpha=255. Every A below is some Alpha value less than 255 and greater than 0, i.e. some transparency. Every X below is a totally transparent pixel (Alpha=0)
XAAAAAAXAAOOOOAAAOOOOOOAAOOOOOOAAAOOOOAAXAAAAAAX
Pass #1:
- Enable alpha test
- Enable Z buffer writes
- Set the alpha test mode to pass when alpha=255
- Render all particles
This renders all the O pixels in the texture above.
Alpha test happens before any Z buffer write or blending, so all the A and X pixels take no fillrate at all. Because Z buffering is enabled, no unnecessary blending takes place.
Pass #2:
- Enable alpha test
- Disable Z buffer writes
- Set the alpha test mode to pass when alpha<255
- Render all particles
This renders all the X and A pixels and ignores all the O''s. The only fillrate consuming overdraw comes from the X and A pixels.
So using the example above, of the 48 pixels being rendered, only 28 will ever overdraw.
This method has the nice side effect of having the most noticable parts of the particle (the opaque bit) Z distance correct.
You could also combine that with the methods suggested by others above.
Depending on what you''re doing another idea is to take advantage of frame to frame coherence and render the particles to a texture over time so that as the density of the particles (in a smoke system for example) grows, you don''t re-render particles which were born earlier.
--
Simon O''Connor
Creative Asylum Ltd
www.creative-asylum.com
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement