0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

USDの実践メモ 03 : マテリアルの作成

Posted at

前回に続き、今回はマテリアルを作成します。

マテリアルの作成

マテリアルを作成します。マテリアルとは次に挙げるシェーダーネットワークのコンテナとして機能させるもので,この考えを理解しておくことが重要です。

from pxr import Usd, UsdGeom, UsdShade, Sdf, Gf

def create_material(stage, path):
    material = UsdShade.Material.Define(stage, path)
    return material

シェーダーの作成

シェーダーを作成します。先ほども述べたように,マテリアルはコンテナですからシェーダーはマテリアルの Sdf パスの下に作成するようにします。まず,PBR シェーダー(UsdPreviewSurface)から作成していきます。metallicroughness の両プロパティに加えて,マテリアルの色と透過度も設定してみました(USDPreviewSurface については公式マニュアルのここに詳しい説明があります)。

def create_shader(stage, path):
    shader = UsdShade.Shader.Define(stage, path)
    shader.CreateIdAttr('UsdPreviewSurface')

    # Inputs
    shader.CreateInput('metallic', Sdf.ValueTypeNames.Float).Set(0.0)
    shader.CreateInput('roughness', Sdf.ValueTypeNames.Float).Set(0.4)
    shader.CreateInput('diffuseColor', Sdf.ValueTypeNames.Color3f).Set(Gf.Vec3f(1, 0, 1))  # Magenta
    shader.CreateInput('opacity', Sdf.ValueTypeNames.Float).Set(1)

    return shader

先ほどのマテリアルの定義を書き換えて,シェーダーの surface output に接続するための「ターミナル」を設けるようにします。

def create_material(stage, path):
    material = UsdShade.Material.Define(stage, path)

    # Terminal outputs
    material.CreateSurfaceOutput()
    
    return material

マテリアルと PBR シェーダーをつなぎ,さらにメッシュをマテリアルにバインドします。これらはメインプログラムで行うことにします(ステージ作成からメッシュ作成までは前回までの記事と同じです)。

if __name__ == '__main__':
    # ステージ作成
    stage = create_stage()

    # ルートノード作成
    rootNode = create_node(stage, '/World', is_defaultPrim=True)

    # メッシュ作成
    mesh = create_mesh(stage, rootNode.GetPath().AppendChild('Mesh'))

    # マテリアル作成
    material = create_material(stage, rootNode.GetPath().AppendChild('Material'))

    # シェーダー作成
    shader = create_shader(stage, material.GetPath().AppendChild('PBRShader'))

    # マテリアルとシェーダーの接続
    material.GetSurfaceOutput().ConnectToSource(shader.ConnectableAPI(), 'surface')

    # メッシュとマテリアルのバインド
    api = UsdShade.MaterialBindingAPI(mesh)
    api.Apply(mesh.GetPrim()).Bind(material)

    # USDファイルにエクスポート
    stage.GetRootLayer().Export('./Material.usda')

出力は次のとおりになりました。usdchecker もパスしています。

#usda 1.0
(
    defaultPrim = "World"
    metersPerUnit = 0.01
    upAxis = "Y"
)

def Xform "World"
{
    def Mesh "Mesh" (
        prepend apiSchemas = ["MaterialBindingAPI"]
    )
    {
        uniform bool doubleSided = 0
        int[] faceVertexCounts = [4, 4]
        int[] faceVertexIndices = [0, 1, 4, 3, 1, 2, 5, 4]
        rel material:binding = </World/Material>
        point3f[] points = [(-1, 0, 0), (0, 0, 0), (1, 0, 0), (-1, 1, 0), (0, 1, 0), (1, 1, 0)]
        texCoord2f[] primvars:st = [(0, 0), (1, 0), (1, 1), (0, 1), (0, 0), (1, 0), (1, 1), (0, 1)] (
            interpolation = "faceVarying"
        )
        int[] primvars:st:indices = [0, 1, 2, 3, 5, 4, 7, 6]
    }

    def Material "Material"
    {
        token inputs:frame:stPrimvarName = "st"
        token outputs:surface.connect = </World/Material/PBRShader.outputs:surface>

        def Shader "PBRShader"
        {
            uniform token info:id = "UsdPreviewSurface"
            color3f inputs:diffuseColor = (1, 0, 1)
            float inputs:metalic = 0
            float inputs:opacity = 1
            float inputs:roughness = 0.4
            token outputs:surface
        }
    }
}
$ usdchecker Material.usda 
Success!

マテリアルを表示してみます。前回作成したメッシュがマテリアルの表面にバインドされました。

material_300x151.png

まとめ

マテリアルを作成して,前回作成したメッシュをこの面にバインドすることができました。次回はここに画像を貼り付けていきます。

参考資料

ft-lab (Yutaka Yoshisaka) さん,あんどうめぐみさん による以下のサイトが理解の助けになりました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?