FBX网格,材质和贴图

FBX网格,材质和纹理

  本节介绍FBX SDK中的网格,纹理和材质。

一.网格

  网格由FbxMesh类抽象。 FbxMesh定义了一个控制点列表,在普通文献中也称为顶点。 FbxMesh的单个实例可以绑定到FbxNode的多个实例,以减少内存消耗。这称为实例化。场景几何使用图层和图层元素(FbxLayerElement)的概念来定义法线贴图,材质贴图,纹理贴图等。

1.实例化-共享网格

  为了减少内存需求,可以将FbxMesh的单个实例绑定到FbxNode的多个实例。 想象一下,您需要一个程序,其中所有多维数据集看起来都一样,但是您需要成千上万个多维数据集。 您可以在程序启动时通过创建一个FbxMesh对象来节省内存。 然后,每次需要一个新的多维数据集时,都将创建一个新的FbxNode对象,然后将该节点指向一个网格。 这称为实例化。
  通常,可以通过让许多节点对象共享一个节点属性对象(即,FbxNodeAttribute的任何子类的一个对象)来节省内存。 以下功能说明了如何将FbxMesh绑定到新创建的节点。

// Create a cube instance with the given mesh as node attribute, and add it to the scene.
FbxNode* CreateCubeInstance(FbxScene* pScene, const char* pName, FbxMesh* pFirstCube)
{
    // create a FbxNode
    FbxNode* lNode = FbxNode::Create(pScene,pName);

    // set the node attribute
    lNode->SetNodeAttribute(pFirstCube);

    // rescale the cube
    lNode->LclScaling.Set(FbxVector4(0.3, 0.3, 0.3));

        // Add node to the scene
    pScene->GetRootNode()->AddChild(lNode);

    // return the FbxNode
    return lNode;
}

  每个节点都是网格,NURBS或其他场景元素的一个实例。 如果将场景导出到FBX文件,则实例化还可以减小文件大小。 您还可以通过让多个节点共享纹理,材质,动画曲线等来节省内存。

二.材质

  材质(FbxSurfaceLambert,FbxSurfacePhong)通过FbxNode :: AddMaterial()绑定到FbxNode的实例。材质定义了场景中几何图形的基本渲染特性,例如其漫反射,环境和发光颜色属性。每种材质在FbxNode中占据特定的索引,FbxMesh :: BeginPolygon()可以引用该索引来定义新创建的多边形的材质。

1.使用硬件着色器创建材质

  从2010版开始,FBX SDK支持CGFX和DirectX硬件着色器。您可以使用FbxImplementation类和FbxBindingTable类使用CGFX或DirectX实现来设置材质。

三.贴图

  纹理(FbxFileTexture,FbxLayeredTexture,FbxProceduralTexture)连接到材质通道,以定义如何渲染几何图形。 FbxFileTexture类使用文件中包含的数据(例如.jpg)来定义纹理的值。

1.分层纹理

  在本教程主题中,我们介绍如何使用FbxLayeredTexture来分层FbxFileTexture的四个实例。 我们还扩展了FbxLayerElement的概念,以定义网格的法线和UV坐标。 本主题中的代码是用Python编写的,它直接适用于C ++。

  示例:对四个纹理进行分层
  所需资源:从左到右:“ one.jpg”,“ two.jpg”,“ three.jpg”,“ four.jpg”。 请注意,这些文件的宽度和高度是2的倍数(128x128),建议用于纹理尺寸。
在这里插入图片描述
  示例输出:该屏幕快照是在运行Python程序并将导入的.fbx文件导入Autodesk MotionBuilder之后获得的。
在这里插入图片描述
  程序摘要:下面的Python程序创建一个场景并将其导出到.fbx文件。 该场景包含使用FbxLayeredTexture实例进行纹理处理的平面网格。 FbxLayeredTexture的此实例由FbxFileTexture的四个累加混合实例组成。 FbxLayeredTexture连接到FbxSurfaceLambert实例的diffuse属性。 如下图所示,此FbxSurfaceLambert实例已添加到FbxNode的材料列表中。
在这里插入图片描述
  平面FbxMesh设置为FbxNode的属性。 使用FbxLayerElementNormal和FbxLayerElementUV在该网格的第0个FbxLayer中设置其法线值和UV坐标。 当以“ 0”作为参数调用FbxMesh.BeginPolygon()时,材料将绑定到平面多边形。 此0表示父FbxNode的材料列表中包含的(唯一)材料,即前面提到的FbxSurfaceLambert。

  注意:要成功运行此Python程序,请确保上面的四个.jpg图像在执行时与此Python程序位于同一文件夹中。

'''
layeredTextures.py

    > creates a plane in the scene whose four textures are layered 
      one on top of another.

    > requires texture files: one.jpg, two.jpg, three.jpg, four.jpg
'''

import fbx
import FbxCommon

vertices = [fbx.FbxVector4( -5, -5,  0 ), # 0 - vertex index.
            fbx.FbxVector4(  5, -5,  0 ), # 1
            fbx.FbxVector4(  5,  5,  0 ), # 2
            fbx.FbxVector4( -5,  5,  0 )] # 3

normalPosZ = fbx.FbxVector4( 0, 0, 1 ) # positive-Z normal vector. 

# Define the filename and alpha transparency of each texture.
textureFilenames = [ ( 'one.jpg',   0.2 ), 
                     ( 'two.jpg',   0.5 ), 
                     ( 'three.jpg', 0.4 ),
                     ( 'four.jpg',  1.0 ) ]

saveFilename = 'layeredTextures.fbx'

###############################################################
# Helper Function(s).                                         #
###############################################################
def createPlane(pScene):
    ''' Create a planar polygon as a child to the root node. '''
    
    rootNode = pScene.GetRootNode()
    
    #======================================================
    # Node definition and mesh object creation. 
    #======================================================
    # Create the node.
    newNode = fbx.FbxNode.Create( pScene, 'planeNode' )
    rootNode.AddChild( newNode )
    
    # Create the mesh node attribute.
    newMesh = fbx.FbxMesh.Create( pScene, 'planeMesh' )
    newNode.SetNodeAttribute( newMesh )
    
    # Create a Lambertian material and assign it to the mesh's node.
    applyLambertMaterial( pScene, newNode )
    
    # Create and apply the layered texture.
    applyLayeredTexture( pScene, newNode )
    
    # Set the node's shading mode to view textures.
    newNode.SetShadingMode( fbx.FbxNode.eTextureShading )
    
    #======================================================
    # Control points.
    #======================================================
    # Define the vertices of the polygon.
    global vertices
    newMesh.InitControlPoints( 4 )
    newMesh.SetControlPointAt( vertices[0], 0 )
    newMesh.SetControlPointAt( vertices[1], 1 )
    newMesh.SetControlPointAt( vertices[2], 2 )
    newMesh.SetControlPointAt( vertices[3], 3 )
    
    #======================================================
    # Normals.
    #======================================================
    # For normals and UV coordinates, we will be using the
    # Layer indexed at 0. If it doesn't exist, we will create it.
    layer = newMesh.GetLayer( 0 )
    if( not layer ):
        newMesh.CreateLayer()
        layer = newMesh.GetLayer( 0 )
    
    # Create a normal layer element.
    normalLayerElement = fbx.FbxLayerElementNormal.Create( newMesh, 'normals' )
    
    # We want to have one normal for each vertex (or control point),    # so we set the mapping mode to eByControlPoint
    normalLayerElement.SetMappingMode( fbx.FbxLayerElement.eByControlPoint )
    
    # Set the normal values for every control point.
    normalLayerElement.SetReferenceMode( fbx.FbxLayerElement.eDirect )
    
    global normalPosZ # positive-Z normals.
    normalLayerElement.GetDirectArray().Add( normalPosZ )
    normalLayerElement.GetDirectArray().Add( normalPosZ )
    normalLayerElement.GetDirectArray().Add( normalPosZ )
    normalLayerElement.GetDirectArray().Add( normalPosZ )
    
    # Assign the normal layer element to the mesh's layer 0.
    layer.SetNormals( normalLayerElement )
    
    #======================================================
    # Diffuse Channel UV Coordinates.
    #======================================================
    # Given that we are only dealing with one polygon (a square plane),
    # we can simplify the code and map the uv coordinates directly to the
    # four polygon control points.
    uvDiffuseLayerElement = fbx.FbxLayerElementUV.Create( newMesh, 'diffuseUV' )
    uvDiffuseLayerElement.SetMappingMode( fbx.FbxLayerElement.eByPolygonVertex )
    uvDiffuseLayerElement.SetReferenceMode( fbx.FbxLayerElement.eDirect )
    
    # Populate the direct array.
    uv0 = fbx.FbxVector2( 0, 0 )
    uv1 = fbx.FbxVector2( 1, 0 )
    uv2 = fbx.FbxVector2( 1, 1 )
    uv3 = fbx.FbxVector2( 0, 1 )
    uvDiffuseLayerElement.GetDirectArray().Add( uv0 )
    uvDiffuseLayerElement.GetDirectArray().Add( uv1 )
    uvDiffuseLayerElement.GetDirectArray().Add( uv2 )
    uvDiffuseLayerElement.GetDirectArray().Add( uv3 )
    
    # Assign the uv layer element to the mesh's layer 0.
    layer.SetUVs( uvDiffuseLayerElement, fbx.FbxLayerElement.eTextureDiffuse )
    
    #======================================================
    # Polygon Definition.
    #======================================================
    # Create one planar polygon. 
    #    > The 0 in FbxMesh.BeginPolygon() refers to the index of the material to be 
    #      applied to the polygon. Since we only have one material applied to our FbxNode, 
    #      we use index 0.
    newMesh.BeginPolygon( 0 )
    for i in range( 0, 4 ):
        newMesh.AddPolygon( i )
    newMesh.EndPolygon()
    
    return newNode

def applyLambertMaterial( pScene, pNode ):
    ''' Apply a Lambertian material to the node. '''
        
    black = fbx.FbxDouble3( 0, 0, 0 )
    white = fbx.FbxDouble3( 1, 1, 1 )
    
    material = fbx.FbxSurfaceLambert.Create( pScene, 'myMaterial' )
    material.ShadingModel.Set( 'Lambert' ) # could also use 'Phong' if we were using an instance of FbxSurfacePhong
    material.Emissive.Set( black )
    material.Ambient.Set( white )
    material.Diffuse.Set( white )
    material.TransparencyFactor.Set( 0 )
    
    pNode.AddMaterial( material )
    
    
def applyLayeredTexture( pScene, pNode ):
    ''' Apply a layered texture on the node using the given texture filenames. ''' 
    global textureFilenames
    
    textures = []
    
    # Create the individual texture objects to be layered afterwards.
    for i in range( 0, len( textureFilenames ) ):
        
        textureFilename = textureFilenames[i][0]
        textureAlpha = textureFilenames[i][1]
        
        newTexture = fbx.FbxFileTexture.Create( pScene, 'myFileTexture_' +  str( i ) )
        newTexture.SetFileName( textureFilename )
        
        newTexture.SetTextureUse( fbx.FbxTexture.eStandard )
        newTexture.SetMappingType( fbx.FbxTexture.eUV )
        newTexture.SetMaterialUse( fbx.FbxFileTexture.eModelMaterial )
        newTexture.SetSwapUV( False )
        newTexture.SetTranslation( 0.0, 0.0 )
        newTexture.SetScale( 1.0, 1.0 )
        newTexture.SetRotation( 0.0, 0.0 )
        newTexture.Alpha.Set( textureAlpha )
        
        textures.append( newTexture )
        
    # Create the layered texture object, and layer the textures within it.
    layeredTexture = fbx.FbxLayeredTexture.Create( pScene, 'myLayeredTexture' )
     
    for i in range( 0, len( textures ) ):
        texture = textures[ i ]
        layeredTexture.ConnectSrcObject( texture )
        layeredTexture.SetTextureBlendMode( i, fbx.FbxLayeredTexture.eAdditive )
    
    # Connect the layered texture to the node's material indexed at 0.
    # The layered texture is connected on the material's diffuse channel. 
    material = pNode.GetMaterial( 0 )
    material.Diffuse.ConnectSrcObject( layeredTexture )


###############################################################
# Main.                                                       #
###############################################################
def main():
    ''' Main Program. '''
    fbxManager = fbx.FbxManager.Create()
    fbxScene = fbx.FbxScene.Create( fbxManager, '' )
    
    # Create the textured planar mesh.
    newNode = createPlane( fbxScene )

    # Save the file.
    global saveFilename
    FbxCommon.SaveScene( fbxManager, fbxScene, saveFilename, pEmbedMedia=True )
    
    # Clean up.
    fbxManager.Destroy()
    del fbxManager, fbxScene, newNode
    
if __name__ == '__main__':
    main()

本节中的主题
网格
材质
贴图

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: FBX SDK for Unity是为Unity游戏引擎设计的一种软件开发工具包(SDK)。FBX SDK是由Autodesk开发的一套用于处理和管理FBX文件格式的工具。FBX是一种常见的3D文件格式,用于在不同的3D应用程序之间进行互操作。使用FBX SDK,开发人员可以轻松地将FBX文件导入到Unity中,以便在游戏中使用。 FBX SDK for Unity提供了一些功能,使开发人员能够更好地在Unity中处理和管理FBX文件。首先,它允许开发人员读取和写入FBX文件。开发人员可以使用FBX SDK在Unity中读取FBX文件的内容,例如模型、材质、动画等,并将其转换为Unity能够使用的数据格式。相反地,开发人员还可以使用FBX SDK将Unity中的内容导出为FBX文件,以便在其他应用程序中使用。 其次,FBX SDK for Unity还提供了一些用于编辑和处理FBX文件的工具和函数。开发人员可以使用FBX SDK更改模型的层次结构、材质属性、动画轨迹等。这使得开发人员能够更好地控制和调整FBX文件以适应他们的游戏需求。 此外,FBX SDK for Unity还提供了一些用于导入和导出FBX文件的辅助功能。开发人员可以使用FBX SDK处理FBX文件的单位、坐标系、标记和动画设置等。这些功能可以让开发人员更加方便地与FBX文件进行交互,并确保在不同应用程序之间进行正确的数据转换。 总之,FBX SDK for Unity是一个非常有用的工具包,使开发人员能够更好地在Unity中处理和管理FBX文件,并与其他3D应用程序进行交互和互操作。它为开发人员提供了更多的灵活性和控制权,以实现他们的游戏开发目标。 ### 回答2: FBX SDK for Unity是一款Unity引擎的插件,用于导入和导出FBX文件格式。FBX文件是一种用于在不同3D软件之间交换模型、动画、材质等数据的通用文件格式。 FBX SDK for Unity提供了许多有用的功能和工具,可以帮助开发者更轻松地在Unity中使用FBX文件。通过该插件,开发者可以导入FBX文件,并将其转换为Unity中可用的资源,如3D模型、骨骼动画、材质贴图等。同时,开发者也可以将Unity中的资源导出为FBX文件,以便与其他支持FBX格式的软件进行交流和共享。 FBX SDK for Unity还支持模型的网格优化、纹理压缩和骨骼动画的精细调整。通过可以控制导入和导出设置,开发者可以根据需求对FBX文件进行自定义处理,以获得更好的效果和性能。 除此之外,FBX SDK for Unity还提供了一些扩展工具,用于处理FBX文件中的蒙皮、法线、顶点色等数据,以及支持多个FBX文件的批量操作。 总之,FBX SDK for Unity是一款功能强大的插件,提供了导入和导出FBX文件的功能,以帮助Unity开发者更好地使用FBX文件,并加强与其他3D软件的兼容性和交互性。无论是从外部软件导入资源,还是将Unity资源导出到其他软件使用,FBX SDK for Unity都是一个非常有用的工具。 ### 回答3: FBX SDK for Unity是一种用于Unity开发环境的软件开发工具包,用于处理和加载FBX文件格式。FBX文件是一种常用的3D模型和动画文件格式,广泛用于游戏开发和动画制作等领域。 通过FBX SDK for Unity,开发者可以在Unity中轻松地导入、加载和展示来自于FBX文件的3D模型和动画。这个SDK提供了一系列功能强大的工具和接口,可以处理FBX文件中的各种元素,如网格材质、动画、骨骼等等。开发者可以使用这些工具和接口来编辑、控制和操纵FBX模型和动画,在游戏中实现各种效果和功能。 FBX SDK for Unity还支持多种模型和动画文件的转换和导出功能。这意味着开发者可以将FBX文件转换为其他格式,如Unity支持的模型和动画格式,以便在不同的开发环境中使用。同时,也可以将Unity中创建的模型和动画导出为FBX文件,用于与其他软件或平台进行交互和共享。 FBX SDK for Unity为开发者提供了更多的选择和自由,使他们能够更灵活地使用FBX文件中的资源。通过这个SDK,开发者可以更加高效地创建和操作3D模型和动画,加快开发进度,并实现更具创意和吸引力的游戏效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值