以下コード類です
----------------------頂点シェーダー----------------------
// 頂点シェーダーの入力
struct VS_INPUT
{
float3 Position : POSITION ; // 座標( ローカル空間 )
float3 Normal : NORMAL ; // 法線( ローカル空間 )
float4 Diffuse : COLOR0 ; // ディフューズカラー
float4 Specular : COLOR1 ; // スペキュラカラー
float4 TexCoords0 : TEXCOORD0 ; // テクスチャ座標
float4 TexCoords1 : TEXCOORD1 ; // サブテクスチャ座標
} ;
struct GS_INPUT
{
float4 pos : SV_POSITION;
float3 norm : TEXCOORD0;
};
// 頂点シェーダ
GS_INPUT main(VS_INPUT VSInput)
{
// ローカル位置をそのままジオメトリシェーダへ
GS_INPUT GSOutput;
GSOutput.pos = float4(VSInput.Position, 1.0);
GSOutput.norm = VSInput.Normal;
return GSOutput;
}
----------------------ジオメトリシェーダー----------------------
// 立方体の面法線
float3 sqFaceNorm[6] =
{
float3(0.0, 0.0, -1.0),
float3(1.0, 0.0, 0.0),
float3(0.0, 0.0, 1.0),
float3(-1.0, 0.0, 0.0),
float3(0.0, 1.0, 0.0),
float3(0.0, -1.0, 0.0)
};
// 立方体の頂点座標
float3 sqVtx[8] =
{
float3(-1.0, -1.0, -1.0),
float3(1.0, -1.0, -1.0),
float3(-1.0, 1.0, -1.0),
float3(1.0, 1.0, -1.0),
float3(-1.0, -1.0, 1.0),
float3(1.0, -1.0, 1.0),
float3(-1.0, 1.0, 1.0),
float3(1.0, 1.0, 1.0)
};
// 立方体のインデックス
int sqIdx[36] =
{
0, 2, 1,
1, 2, 3,
1, 3, 5,
5, 3, 7,
5, 7, 4,
4, 7, 6,
4, 6, 0,
0, 6, 2,
2, 6, 3,
3, 6, 7,
0, 1, 5,
0, 5, 4
};
struct GS_INPUT
{
float4 pos : SV_POSITION;
float3 norm : TEXCOORD0;
};
struct PS_INPUT
{
float4 pos : SV_POSITION;
float3 norm : TEXCOORD0;
};
struct LIGHTCAMERA_MATRIX {
matrix WorldMatrix;
matrix ViewMatrix;
matrix ProjectionMatrix;
};
// 基本パラメータ
cbuffer cbD3D11_LIGHTCAMERA_MATRIX : register(b4)
{
LIGHTCAMERA_MATRIX g_Base;
};
// ジオメトリシェーダ
[MaxVertexCount(108)]
void main(triangle GS_INPUT In[3], inout TriangleStream<PS_INPUT> triStream)
{
// 各頂点に配置する立方体の大きさを何となく算出
float L01 = length(In[1].pos.xyz - In[0].pos.xyz);
float L12 = length(In[2].pos.xyz - In[1].pos.xyz);
float L02 = length(In[0].pos.xyz - In[2].pos.xyz);
float sqScale[3] =
{
min(L01, L02),
min(L01, L12),
min(L12, L02)
};
float4 lLocalPosition;
float4 lWorldPosition;
float4 lViewPosition;
float3 lWorldNrm;
float3 lViewNrm;
float4 LPPosition; // ライトからみた座標( xとyはライトの射影座標、zはビュー座標 )
float4 lLViewPosition;
// 頂点の位置に立方体を配置しWVP変換を
// 法線はWVで
int faceId = 0;
for (int v = 0; v < 3; ++v)
{
for (int p = 0; p < 12; ++p)
{
faceId = p / 2;
for (int i = 0; i < 3; ++i)
{
PS_INPUT Out;
int idx = sqIdx[p * 3 + i];
float3 localP = sqVtx[idx] * sqScale[v] * 1.f + In[v].pos.xyz;
// ローカル座標のセット
lLocalPosition.xyz = localP;
lLocalPosition.w = 1.0f;
lWorldPosition = mul(g_Base.WorldMatrix, lLocalPosition);
lViewPosition = mul(g_Base.ViewMatrix, lWorldPosition);
Out.pos = mul(g_Base.ProjectionMatrix, lViewPosition);
// 法線をビュー空間の角度に変換 =========================================( 開始 )
// ローカルベクトルをワールドベクトルに変換
lWorldNrm = mul(g_Base.WorldMatrix, sqFaceNorm[faceId]);
// ワールドベクトルをビューベクトルに変換
Out.norm = mul(g_Base.ViewMatrix, lWorldNrm);
// 法線をビュー空間の角度に変換 =========================================( 終了 )
triStream.Append(Out);
}
triStream.RestartStrip();
}
}
}