bate's blog

調べたこと実装したことなどを取りとめもなく書きます。

ジオメトリシェーダーで点から四角形を作成

ジオメトリシェーダーで点から四角形を作成するシェーダーを作った。
テスト環境のフレームワークを作ったのでちょっとしたサンプルを作るのが楽。


//--------------------------------------------------------------------------------------
// Constant Buffer Variables
//--------------------------------------------------------------------------------------
cbuffer cb : register( b0 )
{
	matrix World;
    matrix View;
    matrix Projection;
};

struct VS_INPUT
{
	float4 Pos : POSITION;
	float4 Col : COLOR;
};

struct GS_INPUT
{
	float4 Pos : POSITION;
	float4 Col : COLOR;
};

typedef GS_INPUT VS_OUTPUT;

struct PS_INPUT
{
	float4 Pos : SV_POSITION;
	float4 Col : COLOR;
};

typedef PS_INPUT GS_OUTPUT;

//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
VS_OUTPUT VS( VS_INPUT input )
{
	VS_OUTPUT output = (VS_OUTPUT)0;
    output.Pos = input.Pos;
    output.Col = input.Col;
    
    return output;
}

//--------------------------------------------------------------------------------------
// Geometry Shader
//--------------------------------------------------------------------------------------
[maxvertexcount(6)]
void GS( point GS_INPUT input[1], inout TriangleStream<PS_INPUT> stream )
{
	GS_OUTPUT output = (GS_OUTPUT)0;
	
	output.Pos = input[0].Pos;
	output.Pos = mul(output.Pos, World);
	output.Pos = mul(output.Pos, View);
	output.Pos = mul(output.Pos, Projection);
	output.Col = input[0].Col;
	stream.Append(output);
	
	output.Pos = input[0].Pos + float4(1.0f, 0.0f, 0.0f, 0.0f);
	output.Pos = mul(output.Pos, World);
	output.Pos = mul(output.Pos, View);
	output.Pos = mul(output.Pos, Projection);
    output.Col = input[0].Col;
    stream.Append(output);
	
	output.Pos = input[0].Pos + float4(1.0f, -1.0f, 0.0f, 0.0f);
	output.Pos = mul(output.Pos, World);
	output.Pos = mul(output.Pos, View);
	output.Pos = mul(output.Pos, Projection);
    output.Col = input[0].Col;
    stream.Append(output);
    
    stream.RestartStrip();
    
    output.Pos = input[0].Pos;
	output.Pos = mul(output.Pos, World);
	output.Pos = mul(output.Pos, View);
	output.Pos = mul(output.Pos, Projection);
	output.Col = input[0].Col;
	stream.Append(output);
	
	output.Pos = input[0].Pos + float4(1.0f, -1.0f, 0.0f, 0.0f);
	output.Pos = mul(output.Pos, World);
	output.Pos = mul(output.Pos, View);
	output.Pos = mul(output.Pos, Projection);
    output.Col = input[0].Col;
    stream.Append(output);
	
	output.Pos = input[0].Pos + float4(0.0f, -1.0f, 0.0f, 0.0f);
	output.Pos = mul(output.Pos, World);
	output.Pos = mul(output.Pos, View);
	output.Pos = mul(output.Pos, Projection);
    output.Col = input[0].Col;
    stream.Append(output);
    
    stream.RestartStrip();
}

//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PS( PS_INPUT input ) : SV_Target
{
    return input.Col;
}