IDEA: Textured Index Buffers for D3D
cbxOK, so I have been aware of this problem/dilemma for years now but have not seen any head way being made. I am also writing this because I have been watching some of the GDC 2004 ATI presentations at ATI's web site, and they reiterate some thing I have heard on occasion. Things like not bothering to try and figure out what parts of a terrain are visible and render them, but rather to just passing the whole terrain and render the whole thing, because the typical card can handle it, etc etc. See "Richard Huddy - Save The Nanosecond" under the "ATI Sponsored sessions" category at http://www.ati.com/developer/gdc_video.html (NOTE: link current as of May 12, 2004.) So I am going to try to describe my idea to you as best I can. Hope fully my meaning will not be lost one you. We all know DrawPrimitive calls, device state changes, render to texture, setting a new texture on the device etc etc, can be costly, And I don't have any real complaints about that whole process except this... We have vertex buffers, we have index buffers, why not TexturedIndex buffers? Here is what I mean... A TexturedIndex buffer contains... 1 integer = Index into a index buffer (IE: a triangle/mesh face) 2 integers or 1 long or 8 bytes = Each of the 8 bytes stores the index to a texture stage to use when we render. Example 1: FaceIndex as integer TextureStage0 as byte TextureStage1 as byte TextureStage2 as byte TextureStage3 as byte TextureStage4 as byte TextureStage5 as byte TextureStage6 as byte TextureStage7 as byte or Example 2: FaceIndex as integer TextureStages03 as integer ' each byte = stages 0 to 3 TextureStages47 as integer ' each byte = stages 4 to 7 or Example 3: FaceIndex as integer TextureStages as long ' each byte = stages 0 to 7 For example if my vertexes in by vertex buffer contain 3 texture coordinates and if I want to render the face's that uses those 3 textures, a base texture set at stage 0, a bump texture set at stage 5, and a environment texture set at stage 6, a entry for a TexturedIndex for a face would look some thing like this when stored in a TexturedIndex buffer... [code]'Face 1 TexIndex(0).FaceIndex = 231 ' index to a face inside of the index buffer TexIndex(0).TextureStage0 = 0 ' Specifies that the location of the stage 0 texture is actually stored in stage 0 TexIndex(0).TextureStage1 = 5 ' Specifies that the location of the stage 1 texture is actually stored in stage 5 TexIndex(0).TextureStage2 = 6 ' Specifies that the location of the stage 2 texture is actually stored in stage 6 'Face 2 TexIndex(1).FaceIndex = 179 TexIndex(2).TextureStage0 = 4 ' Specifies that the location of the stage 0 texture is actually stored in stage 4 TexIndex(3).TextureStage1 = 7 ' Specifies that the location of the stage 1 texture is actually stored in stage 7 TexIndex(4).TextureStage2 = 3 ' Specifies that the location of the stage 2 texture is actually stored in stage 3 ... and so on ...[/code] "TexIndex(2).TextureStage0 = 4" basically means that we are telling the video card that the texture stored in stage 0 is actually stored in stage 4. This is because our vertexes stored in our vertex buffer are stored as tU1, tV1, tU2, tV2, etc and they don't specify that tU1, tV1, refers to texture coordinates of a texture stored in texture stage 5, there just RAW texture coordinates. Now I know generally we should render geometry sorted by texture, to reduce texture state changes, but instead of having to pass in a texture at stage 0 (Dirt.png) then render all parts of the terrain that use that texture, then set a new texture in stage 0 (Concrete.png) and render the building. Instead of doing that we could set a texture for each of the 8 texture stages, and use in combination with index buffers, a TexturedIndex buffer to render the geometry. That way we can render more geometry in one draw call and we don't have to make as many texture state changes with the Device.SetTexture method. The most commonly used textures could stay permanently stored in specific texture stage slots, and we only need to change out a texture in a specific stage when and as we need to. For example a environment map texture could be stored in stage 7, while a common detail texture could be stored in stage 6. This would also allow us to batch groups of 8 textures together and create TexturedIndex buffers to render geometry in large groups. By it's very nature I don't assume that there would be allot involved in adding this kind of functionality to DirectX or video cards, because it's is based on the IndexBuffer, and vertexbuffer paradigms. The TexturedIndex buffer does produce some tantalizing ideas, but I'm no expert, so If you have heard of similar ideas that have been put fourth would you let me know? Also what do you think about this idea?
Sr. Guapowhoa... so basically you are asking why directX doesn't have a TexturedIndex buffer object/class/whatever? Could you make your own Type in VB? [code] Type TexturedIndex ' index Buffer ' Texture Stages ' ... End Type [/code] Don't know if that is what you mean. I try not to dwelve into the very low level stuff in DX... [;)] Also, I do think it is a good idea,
cbx
quote:
Originally posted by Sr. Guapo
whoa... so basically you are asking why directX doesn't have a TexturedIndex buffer object/class/whatever? Could you make your own Type in VB?
Actually it would have to be a hardware implementation the same as a vertex or index buffer is, that would be exposed to us developers in the Direct3D API. The way the system works now is that say you have a vertex format with 3 sets of texture coordanants tU1, tV1, tU2, tV2, tU3, tV3. (You can have up to 8 texture coordanants per vertex) Each texture coordanant reflects a texture stage. For example tU1, tV1 refer to a texture that has been set in stage 0 (Device.SetTexture(0, TextureReference)) Basically the TexturedIndex.TextureStage0 thru TexturedIndex.TextureStage7 instruct the video card as to the location of the texture stage to use when rendering the vertex geometry. It's basically Texture stage mapping. This would allow you to tell the video card that tU1, tV1 refers to a texture in a different stage other than 0. Now because vertex formats are flexable, YES, you could also specify the TexturedIndex format. for example... [code]public const TexturedIndex_FVF as integer = TexturedIndex.Index or TexturedIndex.Stage2 or TexturedIndex.Stage4 or TexturedIndex.Stage5 Public Structure TexturedIndex Index as integer TextureStage2 as Byte TextureStage4 as Byte TextureStage5 as Byte End Structure[/code] ... would specify that we only concerned with mapping texture stages 2,4,5. I just decided to put fourth the idea and see what kind of responce I got back. I also e-mailed microsoft at directx@microsoft.com and am awaiting a responce. Basically we use index buffers to categorize what vertexes we want to render, but as it is today we can't create/specify a "Material" like buffer that would allow us to render geometry based on the material it uses. Even though when we create game engines that is exactly what we try to do, is sort out visible geometry by what material/texture is applied to it, and then set the material info to the device and render the geometry. The most commonly used textures could stay permanently stored in specific texture stage slots, and we only need to change out a texture in a specific stage when and as we need to. For example a commonly used environment map texture could be stored in stage 7, while a common detail texture could be stored in stage 6. This would allow for less texture state changes between rendering calls as well as reduce the number of Draw calls.
quote:
Rockoon replied: Just one thought.. could this be implimented by yourself with vertex or pixel shaders?
See the whole thread at [url]http://www.xtremevbtalk.com/showthread.php?p=744334#post744334[/url] Now as for trying to implement this functionality using vertex or pixel shaders, I'm not sure that you can, not unless you can instruct the video card to use a different texture stage when rendering a vertex as described in the above paragraph. Even then you have the performance problem of storing a TexturedIndex buffer manually "off the card" kinda like using user managed vertexes and calling DrawUserPrimitives. It would be more optimal to store the TexturedIndex buffer on the card just like you can with a index or vertex buffer. But my gut instinct tells me that it would have to be implemented as a hardware feature, the same was a index or vertex buffer is.
VBBRYou e-mailed microsoft about this? Are you crazy? If the ideia is really good they will of course claim it as theirs... Unless you don't mind, of course.
cbx
quote:
Originally posted by VBBR
You e-mailed microsoft about this? Are you crazy? If the ideia is really good they will of course claim it as theirs... Unless you don't mind, of course.
As i said in my previous posts TexturedIndex buffers would probably have to be implemented in hardware (IE: the view card) and exposed thru the D3D and opengl API's. So it does not matter if I give microsft the idea in the end it's the video card manufactures that need to build the functionality into there cards. Microsoft, does not manufacture hardware.
Eric ColemanThis doesn't make much sense to me. You seem to be using ideas for vertex data optimization for textures, and unfortunately they don't apply. First, a "vertex buffer" is memory managed by the directx API. This allows the API and video card drivers to optimize that data so that it doesn't have to be copied from system memory to video memory every time the geometry is being rendered and/or from system memory to system memory to video memory. Since textures are already stored on the video card, creating a buffer for them is redundant. They already are buffered. As for an indexing system, it allows you to miminize redundant data. Since textures are already reused for multiple geometry, this doesn't really help. In fact, passing pointers or indices to textures per triangle face or vertex increases redundant data and increases the amount of data that has to be sent from system memory to the video card, or in the case of the index data being buffered, takes up more video memory than is needed. Texture stages aren't some type of buffering or indexing system. Texture stages are a method of combining textures for special effects. Using them as an indexing method defeats their purpose.