Sign in to follow this  
Koobazaur

[CPP/DX9] Hmmm... well, that seems illogical.

Recommended Posts

Koobazaur    1264
I've noticed something rather bizarre about my level geometry which consists of some 5,000 polygons (~10,000 triangles). Simply put, the closer I am to it (i.e. the less thare is to draw), the lower the frame rate. Now, if I am staring at a single wall with nothing else visible, I get some 100 fps. But if I fly out all the way where I can see my entire level.... it's at 300 fps? Huh? I haven't done anything fancy like lod or any sort of culling. It's just a standard fixed pipeline with DrawIndexedPrimitives. The only logical explanation for this that I could think of was the textures (the further away I am the smaller they get, obviously), but my settings don't seem like anything that would cause it.
 //set filtering to linear
 D3D9Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
 D3D9Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);

 //set mipmaps to linear
 D3D9Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);

 //set address mode to wrap
 D3D9Device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
 D3D9Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);

 //set texture stage state for color operation so that it multiplies the texture's
 //color and the light's diffuse
 D3D9Device->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 );     //sets texture coordinates
 

 D3D9Device->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE);
 D3D9Device->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE);
 D3D9Device->SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_DIFFUSE);   

(I won't post the full code as it is pretty complicated, dividing my geometry into a KD-Tree and all) Any thoughts?

Share this post


Link to post
Share on other sites
KulSeran    3267
Quote:
I haven't done anything fancy like lod or any sort of culling.

makes me think that you are fillrate limited in the sense, that you are drawing the entire level (posibly covering
the screen several times before the final wall is drawn). So while nothing else seems visible,
you still drew it, even if it was covered by the front wall. So you need some sort of spatial culling,
be it octtree, BSP, or a portal system, so that you have less overdraw on your level.

... and when you are zoomed all the way out, you are drawing the same amount of stuff, but it fills less total pixel
requests on the graphics card, and so is drawing faster.

Another thing you can try, though this is often only usefull with lots of shaders, is a depth-only stage
where you draw everything, only to the depth buffer. Then redraw with a depthtest <= and thus only pixel
process objects that are actually visible on the screen. (but note that spatial partitioning is the
solution you are looking for on this problem. Later on though this depth-only pass may become something you want to consider)

[Edited by - KulSeran on May 5, 2007 3:25:08 AM]

Share this post


Link to post
Share on other sites
Koobazaur    1264
KulSeran, thanks for your reply but that's not it. I did check for that, by positioning myself so that the wall I am looking at is at the edge of my map, i.e. there is nothing behind it.

On the other hand, what exactly is fill-rate limitation? I haven't heard of that...

Share this post


Link to post
Share on other sites
A video card is only fast enough to process a certain amount of vertices per second, and a certain amount of pixels per second. They can also only read and write a certain amount of memory per second. They can also only perform so many shader operations per second.

Most apps are not vertex limited, so we can ignore that.

Most apps are either memory or fillrate limited, and the two are somewhat tied together. Drawing more may read more data (textures), and will write more data. Many card list their peak (maximum theoretical value) fillrate in AA samples per second. When using say 16X AA, you really only shade once, but that value may be written up to 16 times (less on edges of polygons). If a card that supports 16XAA claims to draw 20 billion samples/sec. That really only covers 1.25 billions pixels / sec, which at 60Hz, is ~21 million pixels per frame. At 1280x1024, you have about 1.3 million pixels on screen, which means you can draw each pixel on screen about 16 times maximum an still get 60Hz. Enabling textures, complex lighting, using alpha blending, anything other than a flat colored polygon drives this down lower. Increasing the resolution drives it down lower too.

So, depending on your video card's fillrate, and way too many factors to list, there is a maximum number of pixels you can draw per second. If a mesh runs at 60Hz when filling the screen (16.6 milliseconds per frame), when it's a quarter of the screen it will take a quarter of the time to draw (4.17ms/frame), which will be 240FPS. Simply by moving the camera, we see a change of 180FPS.

Share this post


Link to post
Share on other sites
Rompa    307
If you are texture thrashing/bound then zooming way out will use smaller mipmaps and hence be much more texture cache friendly and therefore run a lot faster. Do you use DXT textures? If not, definitely try it especially DXT1 if you can as its only 4 bits per texel.

The other thing it may be is that when you can see the whole level, you're not delving too deep into your spatial hierarchy but when your camera is right down into the scene you'll need to recurse down a lot more. You may be CPU limited - perhaps try a CPU profile and see if you are indeed CPU bound.

HTH,
rompa.

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