1
\$\begingroup\$

The models my artists are making in maya have multiple different texture coordinates per vertex depending on what face the vertex happens to be a part of.

Originally, to fix this problem, I duplicated each vert every time it appears in a face so each vert can have its own texture coordinates / face normals. This worked out well for a while until I started working on skinned skeletal animation.

I could not seem to get skinned skeletal animation working with this duplicate vertex method. There would be serious gaps in the mesh as it animated. In order to try and fix this, I switched back to indexed drawing, where faces share verts instead of each face having its own unique copy of a vert.

This fixed my skinned animation but now I'm at a loss as how to encode the multiple texture coordinates / face normals that are associated with verts. I was hoping there might be a way to use the index buffer and an array of face normals / uvs to fix this issue. Basically, I figure I can easily add an array of normals/tex coords to each vert but I have no idea how to instruct the gpu to properly index into it.

\$\endgroup\$
  • 1
    \$\begingroup\$ Splitting instances of the same vertex position with different texture coordinates into distinct vertices is pretty standard. It sounds like you didn't have the skinning weights set correctly on each copy of the vertex. If every copy of the vertex has identical skinning information, then it will be transformed identically under animation and you will have no gaps. You may want to share a sample of how you're preparing and using skinning information for each vertex, as this could be where the problem is originating. \$\endgroup\$ – DMGregory Oct 24 '16 at 19:23
  • \$\begingroup\$ So youre saying it probably more reasonable to duplicate verts with different tex coords and fix the skinning issues with that than to use this system of drawing and find some kind of uv work around? \$\endgroup\$ – red_always_mafia Oct 24 '16 at 20:04
  • 1
    \$\begingroup\$ Yes. Splitting vertices at UV seams is standard practice. I'd only depart from that if you're trying to do something exotic, but that doesn't sound like it's the case. \$\endgroup\$ – DMGregory Oct 24 '16 at 20:10
  • \$\begingroup\$ I would spend the time fixing your skinning instead of building a custom hybrid UV system, if two verts at exactly the same position are giving different outputs then that will be a big bug later when you attach one mesh to another and the coincident points drift apart... \$\endgroup\$ – Patrick Hughes Oct 24 '16 at 21:00
2
\$\begingroup\$

Duplicating vertices is probably the wrong way to go for this particular use case.

If all you have is an extra set of UVs, just send in an extra set of UVs. D3D has attributes named TEXCOORD0, TEXCOORD1, ... for a reason. :)

Accessing them is just part of the shader. Bind your attributes in your shader and use different sets of UVs for your sample calls. In shader pseudo code:

// vertex shader
main(vert_input in) {
  out.pos = transform(in.pos);
  out.texcoord0 = in.texcoord0;
  out.texcoord1 = in.texcoord1; // pass second set of UVs through to pixel shader
}

// pixel shader
main (pixel_input in) {
  diffuse0 = sample(tex0, in.texcoord0);
  diffuse1 = sample(tex1, in.texcoord1); // sample second texture using second set of UVs
  return diffuse0 * diffuse1;
}

Duplicate the vertices only when core attributes need to vary. For example, if you need different normals. You mentioned different normals in your post, but odds are you really don't need those; it makes little sense to have different normals for different textures in the vast majority of cases. You'd only really duplicate verts with different normals on hard edges, which has nothing to do with multi-texturing.

You can require that the art uses textures which share a UV space. Needing multiple UVs is something that should be relatively rare outside of particular techniques. If your artists are making content that requires multiple UVs for most content, the problem might be that your artists are doing something questionable that you should not try to support; instead you should educate them how to achieve the same visual effect using a more efficient and less hacky method. (A joke that applies: a man walks into a doctor's office and says, "every time I bend my finger backwards it hurts!" and the doctor replies, "then stop bending your finger backwards.")

The skinning bugs you mention is unrelated to your primary question. It's just a bug. If that's your primary problem, fix your skinning code.

\$\endgroup\$
  • \$\begingroup\$ That makes sense for multiple textures, But I have multiple uvs per vertex to index into the same texture. I would want the ability to change which uv i'm using based on which face the vert is currently being considered to be a part of. Ie. Vert uses uv1 when the pixel shader considers it part of one face, but that same vert could use uv2 when the pixel shader is considering it part of a different face \$\endgroup\$ – red_always_mafia Oct 24 '16 at 20:02
  • \$\begingroup\$ @red_always_mafia In all honesty, that's not a sanitary way of creating 3D assets, you may want to see if the assets could be fixed. \$\endgroup\$ – JonBee Oct 24 '16 at 21:01
  • 1
    \$\begingroup\$ @red_always_mafia: the good use of what you describe is for hard edges, as I described (e.g., different normals and other data). I'm using the term hard edges intentionally (if these faces aren't forming hard edges, your artists are probably doing something weird). The other exception is certain special effects, particularly animated texture techniques. The duplicated verts should absolutely still work with skinning and require no special skinning technique; you just have a skinning bug and need to fix it. \$\endgroup\$ – Sean Middleditch Oct 24 '16 at 21:07
  • \$\begingroup\$ I think there may be a misunderstanding here of what kind of UV data is being used. Multiple UVs for a single vertex position commonly occurs along texturing seams — even an object with no hard edges like a sphere will necessarily have a seam in its UVs somewhere (as long as the mapping has no inversion), where faces that are contiguous in 3D space are not contiguous in UV space. The presence of multiple UV coordinates for one vertex position is not unusual, and is usually handled by splitting it into two coincident vertices which, as Sean Middleditch notes, should still animate identically \$\endgroup\$ – DMGregory Oct 24 '16 at 23:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.