C#でツールを作る その10 -ライティング-

影(shadow)ではなく、陰(shade)ですね。
表面の模様はテクスチャを使うので、今回から頂点色は使いません。

マテリアル

Material[] material = new Material[ 1 ];
material[ 0 ].Diffuse = Color.White;
material[ 0 ].Ambient = material[ 0 ].Diffuse;

ライト

  • ライトの配列はデバイスで用意されている
device.Lights[ 0 ].Type = LightType.Directional;
device.Lights[ 0 ].Direction = new Vector3( 0.8f, -0.6f, 0.7f );
device.Lights[ 0 ].Direction.Normalize();
device.Lights[ 0 ].Diffuse = Color.White;
device.Lights[ 0 ].Ambient = Color.FromArgb( 32, 32, 32 );
device.Lights[ 0 ].Enabled = true;
device.Lights[ 0 ].Update();

頂点データ

  • 3D頂点座標、頂点法線
    • CustomVertex.PositionNormal
  • とりあえず、面(四角形)単位で頂点法線を設定
    • 頂点数:24
  • MeshはPrimitiveType.TriangleListで描画される
private Mesh CreateCube()
{
    Mesh mesh = new Mesh( 12, 6 * 4, MeshFlags.SystemMemory, CustomVertex.PositionNormal.Format, device );

    //キューブの8点
    Vector3[] pos = new Vector3[]{
        new Vector3( -0.5f,  0.5f, -0.5f ),
        new Vector3(  0.5f,  0.5f, -0.5f ),
        new Vector3(  0.5f, -0.5f, -0.5f ),
        new Vector3( -0.5f, -0.5f, -0.5f ),
        new Vector3( -0.5f,  0.5f,  0.5f ),
        new Vector3(  0.5f,  0.5f,  0.5f ),
        new Vector3(  0.5f, -0.5f,  0.5f ),
        new Vector3( -0.5f, -0.5f,  0.5f ),
    };

    //各面の頂点法線
    Vector3[] n = new Vector3[]{
        new Vector3( 0.0f, 0.0f, -1.0f ),
        new Vector3( 1.0f, 0.0f, 0.0f ),
        new Vector3( 0.0f, 0.0f, 1.0f ),
        new Vector3( -1.0f, 0.0f, 0.0f ),
        new Vector3( 0.0f, 1.0f, 0.0f ),
        new Vector3( 0.0f, -1.0f, 0.0f ),
    };

    //各面(四角形)の頂点番号
    int[] data = new int[]{
        0, 1, 2, 3,
        1, 5, 6, 2,
        5, 4, 7, 6,
        4, 0, 3, 7,
        4, 5, 1, 0,
        3, 2, 6, 7,
    };
    CustomVertex.PositionNormal[] v = new CustomVertex.PositionNormal[ 6 * 4 ];
    for( int d = 0; d < 6 * 4; d ++ )
    {
        v[ d ] = new CustomVertex.PositionNormal( pos[ data[ d ] ], n[ d / 4 ] );
    }

    //PrimitiveType.TriangleListの時のインデックスデータ
    short[] i = new short[]{
        0, 1, 2,
        0, 2, 3,
        4, 5, 6,
        4, 6, 7,
        8, 9, 10,
        8, 10, 11,
        12, 13, 14,
        12, 14, 15,
        16, 17, 18,
        16, 18, 19,
        20, 21, 22,
        20, 22, 23,
    };

    AttributeRange attr = new AttributeRange();
    attr.AttributeId = 0;
    attr.FaceStart = 0;
    attr.FaceCount = 12;
    attr.VertexStart = 0;
    attr.VertexCount = 6 * 4;

    mesh.VertexBuffer.SetData( v, 0, LockFlags.None );
    mesh.IndexBuffer.SetData( i, 0, LockFlags.None );
    mesh.SetAttributeTable( new AttributeRange[]{ attr } );
    return mesh;
}

描画

  • ライティングを有効にする
  • バイスにセットするマテリアルの番号とDrawSubset()の引数を一致させる
device.RenderState.Lighting = true;
device.Material = material[ 0 ];
mesh.DrawSubset( 0 );