// 定数バッファのデータ定義@ 変更しないデータ cbuffer cbNeverChanges : register(b0) { // 常にスロット「0」を使う matrix Projection; // 透視変換行列 }; // 定数バッファのデータ定義A 変更頻度の低いデータ cbuffer cbChangesEveryFrame : register(b1) { // 常にスロット「1」を使う matrix View; // ビュー変換行列 float3 Light; // 光源座標(ビュー座標系) }; // 定数バッファのデータ定義B 変更頻度の高いデータ cbuffer cbChangesEveryObject : register(b2) { // 常にスロット「2」を使う matrix World; // ワールド変換行列 }; // 頂点シェーダの入力データ定義 struct VS_INPUT { float3 Pos : POSITION; // 頂点座標(モデル座標系) float3 Col : COLOR; // 頂点色 }; // ジオメトリ シェーダの入力データ定義 struct GS_INPUT { float4 Pos : SV_POSITION; // 頂点座標(ビュー座標系) float4 Col : COLOR; // 頂点色 }; // ピクセル シェーダの入力データ定義 struct PS_INPUT { float4 Pos : SV_POSITION; // 頂点座標(透視座標系) float3 PosView : POSVIEW; // 頂点座標(ビュー座標系) float3 Norm : NORMAL; // 法線ベクトル(ワールド座標系) float4 Col : COLOR; // 頂点色 }; // 頂点シェーダの関数 GS_INPUT VS(VS_INPUT input) { GS_INPUT output; // 頂点座標 モデル座標系→ビュー座標系 float4 pos4 = float4(input.Pos, 1.0); output.Pos = mul(pos4, World); output.Pos = mul(output.Pos, View); // 頂点色 output.Col = float4(input.Col, 1.0); // 出力 return output; } // ジオメトリ シェーダの関数 [maxvertexcount(3)] void GS(triangle GS_INPUT input[3], inout TriangleStream TriStream) { PS_INPUT output; // 法線ベクトルの計算 float3 faceEdge = input[0].Pos.xyz / input[0].Pos.w; float3 faceEdgeA = (input[1].Pos.xyz / input[1].Pos.w) - faceEdge; float3 faceEdgeB = (input[2].Pos.xyz / input[2].Pos.w) - faceEdge; output.Norm = normalize(cross(faceEdgeA, faceEdgeB)); // 各頂点の計算 for (int i=0; i<3; ++i) { // 頂点座標 ビュー座標系 output.PosView = input[i].Pos.xyz / input[i].Pos.w; // 頂点座標 ビュー座標系→射影座標系 output.Pos = mul(input[i].Pos, Projection); // 頂点色 output.Col = input[i].Col; // 出力 TriStream.Append(output); } TriStream.RestartStrip(); } // ピクセル シェーダの関数 float4 PS(PS_INPUT input) : SV_TARGET { // 光源ベクトル float3 light = Light - input.PosView; // 距離 float leng = length(light); // 明るさ float bright = 30 * dot(normalize(light), normalize(input.Norm)) / pow(leng, 2); // 色 return saturate(bright * input.Col); }