🔒 Locked
fillrate question
Advertisement
Original Post
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
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
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)
XAAAAAAX
AAOOOOAA
AOOOOOOA
AOOOOOOA
AAOOOOAA
XAAAAAAX
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
Thanks, Simon. I''ll give it a try and benchmark it. That sounds like just what I needed.
--Neil.
----------------------
Check out my game demo and resume at
www.fivestory.com/projects/game.
--Neil.
----------------------
Check out my game demo and resume at
www.fivestory.com/projects/game.
davepermen : that is GREAT.. framerate goes form 80-120 (by nutty) to 380-450 .. now THAT''s an improvement.. any other tricks used?
You should never let your fears become the boundaries of your dreams.
You should never let your fears become the boundaries of your dreams.
nope, just the "power" of the gf2 pixelshaders..
i always said eighter say gf1 and gf2 do have pixelshaders, or gf3/gf4 don''t. :D
i should try to get it working including the alpha test.. should help for the fillrate "problem", by removing.. hm.. how much pixels?... 21.4601836602551690384339154180124%
i love the windows calculator:D
"take a look around" - limp bizkit
www.google.com
i always said eighter say gf1 and gf2 do have pixelshaders, or gf3/gf4 don''t. :D
i should try to get it working including the alpha test.. should help for the fillrate "problem", by removing.. hm.. how much pixels?... 21.4601836602551690384339154180124%
i love the windows calculator:D
"take a look around" - limp bizkit
www.google.com
just one more thing for anyone try to implement davepermens idea. you have to use glColor(xcoord,ycoord, 0.5f ); not glColor(xcoord,ycoord,0); for expand() to work. (since expand(0.5f)=0). I spent last half hour figuring out why it doesn''t work until I found this "bug". Another thing to mention is actual "texture". I prefer using something like color = (1-x*x+y*y)^2 .. it looks a bit better.. personal opinion I guess...
You should never let your fears become the boundaries of your dreams.
You should never let your fears become the boundaries of your dreams.
only one hour..
i remember the days..
guess what? the time i implemented it it took me one hour.. but, as you know, i just implemented it _AGAIN_. i''ve done it before..
*urgh* :D
some pics of (1-x^2-y^2)^2?
"take a look around" - limp bizkit
www.google.com
i remember the days..
guess what? the time i implemented it it took me one hour.. but, as you know, i just implemented it _AGAIN_. i''ve done it before..
*urgh* :D
some pics of (1-x^2-y^2)^2?
"take a look around" - limp bizkit
www.google.com
hm.. i think you mean (1-(x^2+y^2))^2 in your example.. else it would not be a sphere, would it?:D
and.. if i think about this.. thats, in 3d..
(1-(x^2+y^2+z^2))^2, wich is simply (1-dst^2)^2, and, you can find this here on gamedev as well as overthere on opengl.org as proposal for a fast approximation for
attentuation = exp(-dst^2).. and guess why i proposed it? because a) its fast and b) it is a fucking nice attentuation..
heh.. why did i not thought of this again? (i did the first time i implemented it:D)
"take a look around" - limp bizkit
www.google.com
and.. if i think about this.. thats, in 3d..
(1-(x^2+y^2+z^2))^2, wich is simply (1-dst^2)^2, and, you can find this here on gamedev as well as overthere on opengl.org as proposal for a fast approximation for
attentuation = exp(-dst^2).. and guess why i proposed it? because a) its fast and b) it is a fucking nice attentuation..
heh.. why did i not thought of this again? (i did the first time i implemented it:D)
"take a look around" - limp bizkit
www.google.com
ups.. sorry I ment (1-(x^2+y^2))^2
.. I also use something like this for distance attentuation... only in 3D
You should never let your fears become the boundaries of your dreams.
[edited by - _DarkWIng_ on December 11, 2002 4:05:06 AM]
You should never let your fears become the boundaries of your dreams.
[edited by - _DarkWIng_ on December 11, 2002 4:05:06 AM]
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement