Archived

This topic is now archived and is closed to further replies.

Compressed FVFs

This topic is 5570 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I started thinking about this wrt to my terrain engine but think it would be useful generally. First a couple of questions about the FVF structures: Can you ONLY use the types mentioned in the SDK? No arbitrary structs allowed? Can you have a float member, but load it as a DWORD inside a pixel shader? Do shaders support bit shifting, so I could pack two separate 16bit variables in a 32bit FVF member? Now my thoughts: The FVF structures we use are often needlessly bloated. This is bad because: 1)More memory used which means less data can be used. 2)Larger FVFs take longer to copy to the GPU which means it''s a fair bit slower. So which bits don''t need so much space? 1)Normals: 3 floats means 12 bytes for a normal. That''s a lot. 8bit precision for each of the x,y,z members would often be good enough though a bit crude, but 16bit would give each member accuracy to better than 0.001 which is fine, considering each member should always be -1<0<1. Even 16bit would save 6bytes, which could be over 25% of the FVF size. 2)Texture coords: Again, floats for each u,v member. Since we often use textures <256x256, 8bit precision would often be fine, 16bit nearly always unless you are going to be tiling many many times (ie the texture is tiled 100 times over a surface). For a FVF with 3 textures (main, lightmap, bumpmap) that''s 6 floats we can reduce, saving 12bytes. 3)Coordinates: Again I think we could often have the x,y,z position in 16bit values, especially if we have fixed scaling variables (how big 1 unit is) which could be stored as shader constants. The only real factor I find against this idea is that you need to multiply the values by a scaling factor to get the range D3D requires. But for shaders this is not a factor surely? The other thing is finding space in the FVF members to put this compressed data. An example: struct { float x,y,z; float u1,v1; float u2,v2; float nx,ny,nz; DWORD diffuse; } size=44bytes goes to struct { WORD x,y,z; WORD u1,v1; BYTE u2,v2; WORD nx,ny,nz; DWORD diffuse;//could even get this to a WORD using r5g5b5 } size=22bytes This is completely feasible in my view. Does anyone do this?
Read about my game, project #1 NEW (9th September)diaries for week #5 Also I''m selling a few programming books very useful to games coders. Titles on my site.
John 3:16

Share this post


Link to post
Share on other sites
Well, then it is some tricks in the shader code that "gets the abuse straight". Sure this can be done then - but that is then not a custom FVF but abusing FVF fields to move data into the shader :-)

Now, the book - bad story. Amazon keeps telling me they cant get ahold of it so I cant even order it.


Regards

Thomas Tomiczek
THONA Consulting Ltd.
(Microsoft MVP C#/.NET)

Share this post


Link to post
Share on other sites
I just remembered where I got the info from:
There was a post about this a few weeks back in the Graphics Theory forum. It''s not a very high-frequency forum, so you could go through it manually, if you''re interested. (search is down) I unfortunately can''t remember who started it, I think it was some moderator, but not the moderator of that forum. Good luck!

- JQ
Full Speed Games. Period.

Share this post


Link to post
Share on other sites
Some responses:

1. First of all, you can use/abuse the declaration any way you want. If you want to store color information in a texture coordinate, etc. you can do that.

2. Yes, there are packing techniques, but be fairly careful. It could be that the cost of added unpacking instructions might outweigh whatever bandwidth savings you gain, especially if you manage your buffers well. This isn''t to say that packing is bad, but rather that you should be smart about how you use it. If using a packed normal costs you 10 extra instructions (just making up numbers...), that is probably bad.

In short, trimming the amount of data is good, but not if it causes bottlenecks elsewhere. If your bottleneck is in the memory bandwidth, consider packing. If it''s in vertex processing, it might actually be better to preprocess data into a larger vertex structure. If the bottleneck is in fillrate, this could be a complete nonissue.

Figure out where the bottleneck is *and then* optimize.

Author, "Real Time Rendering Tricks and Techniques in DirectX", "Focus on Curves and Surfaces"

Share this post


Link to post
Share on other sites
I wasn''t primarily doing this for speed but memory savings, though if the FVF was small enough I could avoid having to keep regenerating the vertices which is a BIG speed boost. For a terrain engine you can store a vertex in 4 bytes.

The simple packing techniques would be very quick, requiring just a multiply probably. Having to unpack 3 vars from the diffuse would be a bit slow but all cards with shaders are so damn quick anyway I think the memory advantage is a bonus. Especially for a terrain engine where you will have millions of vertices - every byte you shave of the FVF is multiple megabytes!

I did mean abusing the FVF, wondered if it was possible to pack two WORDs into a float and get them out the other end - is it and which shader ops would you need?



Read about my game, project #1
NEW (9th September)diaries for week #5

Also I''m selling a few programming books very useful to games coders. Titles on my site.


John 3:16

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Check out this Thread:
http://www.gamedev.net/community/forums/topic.asp?topic_id=103910

The person who started the thread had successfully implemented it about half way down. Maybe you could ask them what they did or have them send you a sample.

Share this post


Link to post
Share on other sites