Implementing Phong tessellation at DirectX11 ( DirectX11 での PhongTessellation の実装 )

At 20101016, I implemented a very simple Phong Tessellation using Geometry Shader.

去年, 単純な Phong Tessellation をジオメトリシェーダで実装してみました.

GeometryShader で, Phong Tessellation を実装してみました - OLD hanecci’s blog : 旧 はねっちブログ


This time, I have implemented Phong Tessellation at DirectX11 using Thinkpad W520.

今回は DirectX11 対応の Thikpad W520 を使い, DirectX11 で PhongTessellation を実装してみました.



// No tessellation


// Phong tessellation ( tessellation factor = 5.2 )


// Phong tessellation ( tessellation factor = 30.4 )


At Phong tessellation, it projects the barycentric interpolated position to TBN plane of each triangle vertices, and recalculates the barycentric interopolated position from them. The domain shader code is most important for this algorithm, so I will show the souce code of it.


Phong Tessellation ではリニアなテッセレーション後に, 位置座標を各三角形の TBN 平面に射影し, 位置座標を再計算しています. 位置座標を再計算している Phong Tessellation では ドメインシェーダ部分のソースコードが重要なので, その部分だけを貼り付けます.

//////////////////////////////////////////////////
//
// Domain shader for Phong Tessellation 
//                                   hanecci
//
//////////////////////////////////////////////////


// Project position to TBN space.
float3
ProjectPositionToTangentSpace( float3 position,
                               float3 plane_position,
			       float3 plane_normal )
{
	float projectValue = 
		dot( ( position - plane_position ), 
			  plane_normal );

	return ( position - projectValue * plane_normal );
}

struct HS_OUTPUT
{
    float3 vPosition           : POSITION;
    float3 vNormal             : NORMAL;
};

struct DS_OUTPUT
{
    float4 vPosition        : SV_POSITION;
    float4 vColor           : COLOR0;
};

[domain("tri")]
DS_OUTPUT
DS( HS_CONSTANT_DATA_OUTPUT input,     
    float3 uvw : SV_DomainLocation,
    const OutputPatch<HS_OUTPUT, 3> tri )
{
    DS_OUTPUT output;

    float3 interpPos = uvw.x * tri[0].vPosition + 
                       uvw.y * tri[1].vPosition +
                       uvw.z * tri[2].vPosition;
   
    float3 phongPos = float3( 0.0f, 0.0f, 0.0f );
    for ( int index = 0; index < 3; index++ )
    {
        phongPos += ( uvw[ index ] * 
                      ProjectPositionToTangentSpace( interpPos,
                                                     tri[ index ].vPosition, 
                                                     tri[ index ].vNormal ) );
    }

    float3 finalPos  = phongPos;
    output.vPosition = float4( finalPos, 1 );

    float3 finalNormal = uvw.x * tri[0].vNormal + 
                         uvw.y * tri[1].vNormal +
                         uvw.z * tri[2].vNormal;

    // Convert normal to color
    float3 normalColor = normalize( finalNormal );
    normalColor       *= 0.5f;
    normalColor       += 0.5f;

    float4 color       = float4( normalColor, 1.0f );
	output.vColor  = color;

    return output;    
}