Multiple texture coordinates in Ogre::Mesh Topic is solved

Problems building or running the engine, queries about how to use features etc.
User avatar
bishopnator
Goblin
Posts: 299
Joined: Thu Apr 26, 2007 11:43 am
Location: Slovakia / Switzerland
x 11

Multiple texture coordinates in Ogre::Mesh

Post by bishopnator »

Ogre Version: 3.0
Operating System: Win11
Render System: d3d11 / gl3+

Is it possible to create Ogre::Mesh with e.g. 2 texture coordinates which are mapped to TEXCOORD0 and TEXCOORD5 in HLSL and using layout(location=7) and layout(location=11) in GLSL for input attributes?

It seems that in both render systems technically there is no restriction, however in Hlms::calculateHashForSemantic only VES_TEXTURE_COORDINATES is checked (and not those values +1, +2, etc. for other texture coordinates). Also the local variable semIndex in Hlms::calculateHashForV2 gets out of bounds.

I didn't try to create vertex buffer for Ogre::Mesh using 2 VES_TEXTURE_COORDINATES, but I suppose, if it works, internally it assigns texture coordinates to the channels 0 and 1 (TEXCOORD0 and TEXCOORD1 in HLSL, and locations 7 and 8 in GLSL), right?

I would like to store in higher texture coordinate channel my custom values for each mesh - I know that all input meshes will use either 1 or 2 texture coordinates and I would like to store my custom data in a fixed channel. I know that I can store them in TEXCOORD0 and those optional uv coordinates in following, but I would like to use those lower 0 and 1 for the standard usage - mapping the textures.

User avatar
bishopnator
Goblin
Posts: 299
Joined: Thu Apr 26, 2007 11:43 am
Location: Slovakia / Switzerland
x 11

Re: Multiple texture coordinates in Ogre::Mesh

Post by bishopnator »

In Ogre::v1::VertexElement, there is mIndex through which it is possible to explicitly define also multiple colors and texture coordinates and bind them to desired slots.

The Ogre::VertexElementSemantic is missing this member. To keep the same size of the struct, it is possible to add VES_TEXTURE_COORDINATESn (0-7) which can be properly processed in GL3PlusVaoManager::createVao and in D3D11HLSLProgram::getLayoutForPso where the automatic counter can be then avoided - the semantic implicitly defines the binding in D3D11 and in GL3Plus.

What was the reason to remove such arbitrary mapping?

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5433
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1341

Re: Multiple texture coordinates in Ogre::Mesh

Post by dark_sylinc »

Hi!

V2 attributes assume attributes are correlative.

So you just push two VES_TEXTURE_COORDINATES into a vector, they become uv0 and uv1.
So the answer is no.

What was the reason to remove such arbitrary mapping?

Because the arbitrariness was adding unnecessary complexity. An O(1) vector becomes an std::map. And it is no longer possible to easily guess the offset & size of an element.

What happens if the user defines TEXCOORD0, TEXCOORD5, TEXCOORD1?

  • 5 comes before 1, but after 0.
  • There's 3 UVs, but the max element index used is 5.

This causes the need to handle lots of edge cases & extra indirections when generating shader as one cannot simply do:

Code: Select all

@foreach( num_uvs, n )
   uv@n;
@end

The Ogre::VertexElementSemantic is missing this member. To keep the same size of the struct, it is possible to add VES_TEXTURE_COORDINATESn (0-7) which can be properly processed in GL3PlusVaoManager::createVao and in D3D11HLSLProgram::getLayoutForPso where the automatic counter can be then avoided - the semantic implicitly defines the binding in D3D11 and in GL3Plus.

The cost of tracking in createVao/getLayoutForPso is a negligible cost (that happens once: when constructing a PSO or VAO and then never again) compared to the extra mental load users need to do to process, construct and/or maintain vertex declarations; because otherwise one could not simply assume that if I have 3 UVs, then I always have uv0 -> uv1 -> uv2.

It also causes debugging nightmares because everything seems alright, but it doesn't render correctly, until one notices a vertex declaration was using index 4 but the shader expected index 5 (or viceversa).

It just creates another point of failure that is an easy mistake to make and hard to spot.

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5433
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1341

Re: Multiple texture coordinates in Ogre::Mesh

Post by dark_sylinc »

Another problem I forgot to mention is that we'd need to handle validation.

Because a declaration "TEXCOORD0, TEXCOORD0" is invalid. The index cannot be repeated.

Ideally this error should be spotted as early as possible. But often by the time OgreNext spots the invalid declaration, it is late enough that the error looks like some cryptic OgreNext bug instead of an invalid parameter that originated from the user.

This type of mistake would be quite common during mesh manipulation (e.g like merging two meshes into one, or splicing a mesh in two) ; as one would simply copy declarations around, forgetting to update the index value.

For example a mesh that contains uv0 and uv1; gets spliced into two meshes with only uv0; but the second mesh contains uv1 (yet the user intended uv1 to become uv0).
A splice tool would also need to handle the opposite (very unlikely) case: the user wants to splice the meshes but for some reason wants the 2nd mesh to keep only uv1 but to stay as uv1.

OgreNext simply removed all that complexity. One set of TEXCOORD always means it's uv0. Two sets of TEXCOORD always means it's uv0 and uv1. No further thinking about it.

User avatar
bishopnator
Goblin
Posts: 299
Joined: Thu Apr 26, 2007 11:43 am
Location: Slovakia / Switzerland
x 11

Re: Multiple texture coordinates in Ogre::Mesh

Post by bishopnator »

Fair enough. I thought that something like that is in the background, but I rather asked to be 100% sure and that I need to rethink my approach of storing the custom parameters (e.g. in all type of shaders in uv0 and use uv1 for real texture coordinates). With the HLMS it is also quite easy to make it more dynamic so it is not a big deal.