Jump to content
  • Advertisement
Sign in to follow this  
Joeydenhaag

Fbx SDK Importer issue (texture / uv related)

This topic is 582 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

Hello everyone!
 
I am using the "2016.1.1" autodesk FBX Importer SDK, but whatever I do, I am unable to get the uvs right. Some parts are textured properly while others are not.
 
I am using Direct3D9 and Direct3D11 (same result in both).
 
Image:
 
 
3AE6R.png
 
The model uses a single texture and a single material shared among 4 meshes.
 
Is there someone who sees immediately what the problem could be? Or is there someone who can replicate the issue for me and figure out what I am missing?
 
 
My UV reading method:
int vertexCounter = 0;
for (int j = 0; j < nbPolygons; j++) {
    
    for (int k = 0; k < 3; k++) {

        int vertexIndex = pFbxMesh->GetPolygonVertex(j, k);
    
        Vector2 uv;
        _readUV(pFbxMesh, vertexIndex, pFbxMesh->GetTextureUVIndex(j, k), uv);
    
        pVertices[vertexIndex].uv.x = uv.x;
        pVertices[vertexIndex].uv.y = 1.0 - uv.y;
        vertexCounter++;
    }
}
   
void _readUV(fbxsdk::FbxMesh* pFbxMesh, int vertexIndex, int uvIndex, Vector2& uv) {
    
    fbxsdk::FbxLayerElementUV *pFbxLayerElementUV = pFbxMesh->GetLayer(0)->GetUVs();
    
    if (pFbxLayerElementUV == nullptr) {
        return;
    }
    
    switch (pFbxLayerElementUV->GetMappingMode()) {
    
        case FbxLayerElementUV::eByControlPoint:
        {
            switch (pFbxLayerElementUV->GetReferenceMode()) {
    
                case FbxLayerElementUV::eDirect:
                {
                    fbxsdk::FbxVector2 fbxUv = pFbxLayerElementUV->GetDirectArray().GetAt(vertexIndex);
    
                    uv.x = fbxUv.mData[0];
                    uv.y = fbxUv.mData[1];
    
                    break;
                }
    
                case FbxLayerElementUV::eIndexToDirect:
                {
                    int id = pFbxLayerElementUV->GetIndexArray().GetAt(vertexIndex);
                    fbxsdk::FbxVector2 fbxUv = pFbxLayerElementUV->GetDirectArray().GetAt(id);
    
                    uv.x = fbxUv.mData[0];
                    uv.y = fbxUv.mData[1];
    
                    break;
                }
            }
    
            break;
        }
    
            
         case FbxLayerElementUV::eByPolygonVertex:
         {
    
                
             switch (pFbxLayerElementUV->GetReferenceMode()) {
                    
                 // Always enters this part for the example model
                 case FbxLayerElementUV::eDirect:
                 case FbxLayerElementUV::eIndexToDirect:
                 {
    
                     uv.x = pFbxLayerElementUV->GetDirectArray().GetAt(uvIndex).mData[0];
                     uv.y = pFbxLayerElementUV->GetDirectArray().GetAt(uvIndex).mData[1];
    
                    break;
                 }
             }
    
             break;
         }
    }  
}
 
 
I am doing V = 1.0 - uv.y because I am using Direct3D11.
 
NOTE: the MappingMode is always eByPolygonVertex and ReferenceMode is always eIndexToDirect
 
Rendering Info:
- Rendered as a Triangle List
- Uv wrapping mode: Wrap (Repeat)
- Culling: None
 
 
For more code or info please ask! I've been trying to fix this frustrating issue for a few days now..   ^_^
Edited by Konjoey

Share this post


Link to post
Share on other sites
Advertisement

Update: I was just playing with the code and adding the extra if in the loop to sort of check if the uv's were unitialized fixed the eyes.. but ruined the arms..

 

dd7d813728c31a669f9191ea0b5edf6e.png

for (int j = 0; j < nbPolygons; j++) {
    
    for (int k = 0; k < 3; k++) {

        int vertexIndex = pFbxMesh->GetPolygonVertex(j, k);
    
        Vector2 uv;
        _readUV(pFbxMesh, vertexIndex, pFbxMesh->GetTextureUVIndex(j, k), uv);
    
        if (pVertices[vertexIndex].uv.x == 0.0f && pVertices[vertexIndex].uv.y == 0.0f) {

	    pVertices[vertexIndex].uv.x = uv.x;
	    pVertices[vertexIndex].uv.y = 1.0 - uv.y;
	}
        vertexCounter++;
    }
}
Edited by Konjoey

Share this post


Link to post
Share on other sites

Probably due to not splitting vertices that have multiple texture coordinates along uv face seams.

 

Thanks for your reply!

 

Could you give an example on how to do this? I mean, I assume the FBX SDK has a function to do this automatically.

Edited by Konjoey

Share this post


Link to post
Share on other sites

Kind of weird an sdk doesn't do that by default. Did they have an API call to take care of the split?

 

I haven't found it yet, but I don't think it should be too hard to do it manually. For this quick fix I just checked the option "Split Per-Vertex Normals" for the model in 3dsMax when exporting.

Share this post


Link to post
Share on other sites

Kind of weird an sdk doesn't do that by default. Did they have an API call to take care of the split?

It’s too trivial to encourage automation. It’s normally the default pass over the model.
You by-default split vertices based on a pool and indices and then should always reconstruct your own vertices and pools, which again is trivial.
You shouldn’t have to rely on 3DS Max to do this for you. This indicates a flaw in your FBX converter which will manifest many times in the future.


L. Spiro

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!