// 定数バッファのデータ定義 cbuffer cbCBuffer : register(b0) { // 常にスロット「0」を使う matrix World; // ワールド変換行列 matrix View; // ビュー変換行列 matrix Projection; // 透視変換行列 float3 Light; // 光源座標(ビュー座標系) }; // ************************************************** // 立方体の描画 // ************************************************** // ピクセル シェーダの入力データ定義 struct PS_INPUT { float4 Pos : SV_POSITION; // 頂点座標(透視座標系) float3 PosView : POSVIEW; // 頂点座標(ビュー座標系) float3 Norm : NORMAL; // 法線ベクトル(ワールド座標系) float4 Col : COLOR; // 頂点色 }; // 頂点シェーダの関数 float4 VS(uint vID : SV_VertexID) : SV_POSITION { float4 pos; // 頂点座標(モデル座標系)の生成 static const uint pID[36] = { 0,1,3, 1,2,3, 1,5,2, 5,6,2, 5,4,6, 4,7,6, 4,5,0, 5,1,0, 4,0,7, 0,3,7, 3,2,7, 2,6,7 }; switch (pID[vID]) { case 0: pos = float4(-1.0, 1.0, -1.0, 1.0); break; case 1: pos = float4( 1.0, 1.0, -1.0, 1.0); break; case 2: pos = float4( 1.0, -1.0, -1.0, 1.0); break; case 3: pos = float4(-1.0, -1.0, -1.0, 1.0); break; case 4: pos = float4(-1.0, 1.0, 1.0, 1.0); break; case 5: pos = float4( 1.0, 1.0, 1.0, 1.0); break; case 6: pos = float4( 1.0, -1.0, 1.0, 1.0); break; case 7: pos = float4(-1.0, -1.0, 1.0, 1.0); break; } // 頂点座標 モデル座標系→ビュー座標系 pos = mul(pos, World); pos = mul(pos, View); // 出力 return pos; } // ジオメトリ シェーダの関数 [maxvertexcount(3)] void GS(triangle float4 input[3] : SV_POSITION, uint pID : SV_PrimitiveID, inout TriangleStream TriStream) { PS_INPUT output; // 頂点色の生成 output.Col.r = (pID & 0x01) ? 1.0 : 0.3; output.Col.g = (pID & 0x02) ? 1.0 : 0.3; output.Col.b = (pID & 0x04) ? 1.0 : 0.3; output.Col.a = 1.0; // 法線ベクトルの計算 float3 faceEdge = input[0].xyz / input[0].w; float3 faceEdgeA = (input[1].xyz / input[1].w) - faceEdge; float3 faceEdgeB = (input[2].xyz / input[2].w) - faceEdge; output.Norm = normalize(cross(faceEdgeA, faceEdgeB)); // 各頂点の計算 for (int i=0; i<3; ++i) { // 頂点座標 ビュー座標系 output.PosView = input[i].xyz / input[i].w; // 頂点座標 ビュー座標系→射影座標系 output.Pos = mul(input[i], Projection); // 出力 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); }