図0010a
PSPNInput main(VSPNInput input)
{
PSPNInput result;
//頂点の位置を変換
float4 pos = float4(input.position.xyz, 1.0f);
//ワールド変換
pos = mul(pos, World);
//ビュー変換
pos = mul(pos, View);
//射影変換
pos = mul(pos, Projection);
//ピクセルシェーダに渡す変数に設定
result.position = pos;
//ライティング
result.norm = mul(input.norm, (float3x3)World);
result.norm = normalize(result.norm);
return result;
}
float4 main(PSPNInput input) : SV_TARGET
{
//法線ライティング
float3 lightdir = normalize(LightDir.xyz);
float3 N1 = normalize(input.norm);
float4 Light = saturate(dot(N1, -lightdir) * Diffuse + Emissive);
Light.a = Diffuse.a;
return Light;
}
図0010b
この図は、通常描画(フラットではない)の場合の、ピクセルシェーダに渡される法線と、ライトの関係を示したものです。両方とも正規化されているとします。ピクセルシェーダではその表面の1つの点を処理するので、青い丸のところだけ考えます。
図0010c
この図は前の図から正規化された法線と正規化された光の方向の逆の関係を示したものです。正規化された法線に対して正規化された光の方向の逆の内積を出すと、赤い線の長さが出せるのがわかります。また、それは最高で1.0であり(法線とライトが重なっている場合)、最低で0.0です(法線とライトが90度になってる場合)。
float4 Light = dot(N1, -lightdir);
float4 Light = dot(N1, -lightdir) * Diffuse + Emissive;
void CubeObject::CreateBuffers() { float HelfSize = 0.5f; vector<Vec3> PosVec = { { Vec3(-HelfSize, HelfSize, -HelfSize) }, { Vec3(HelfSize, HelfSize, -HelfSize) }, { Vec3(-HelfSize, -HelfSize, -HelfSize) }, { Vec3(HelfSize, -HelfSize, -HelfSize) }, { Vec3(HelfSize, HelfSize, HelfSize) }, { Vec3(-HelfSize, HelfSize, HelfSize) }, { Vec3(HelfSize, -HelfSize, HelfSize) }, { Vec3(-HelfSize, -HelfSize, HelfSize) }, }; vector<UINT> PosIndeces = { 0, 1, 2, 3, 1, 4, 3, 6, 4, 5, 6, 7, 5, 0, 7, 2, 5, 4, 0, 1, 2, 3, 7, 6, }; vector<Vec3> FaceNormalVec = { { Vec3(0, 0, -1.0f) }, { Vec3(1.0f, 0, 0) }, { Vec3(0, 0, 1.0f) }, { Vec3(-1.0f, 0, 0) }, { Vec3(0, 1.0f, 0) }, { Vec3(0, -1.0f, 0) } }; vector<VertexPositionNormal> vertices; vector<uint16_t> indices; UINT BasePosCount = 0; for (int i = 0; i < 6; i++) { for (int j = 0; j < 4; j++) { VertexPositionNormal Data; Data.position = PosVec[PosIndeces[BasePosCount + j]]; if (m_Flat) { //フラット表示の場合は法線は頂点方向にする Data.normal = Data.position; Data.normal.normalize(); } else { //フラット表示しない場合は、法線は面の向き Data.normal = FaceNormalVec[i]; } vertices.push_back(Data); } indices.push_back((uint16_t)BasePosCount + 0); indices.push_back((uint16_t)BasePosCount + 1); indices.push_back((uint16_t)BasePosCount + 2); indices.push_back((uint16_t)BasePosCount + 1); indices.push_back((uint16_t)BasePosCount + 3); indices.push_back((uint16_t)BasePosCount + 2); BasePosCount += 4; } //メッシュの作成(変更できない) m_CubeMesh = MeshResource::CreateMeshResource(vertices, indices, false); }
float HelfSize = 0.5f; vector<Vec3> PosVec = { { Vec3(-HelfSize, HelfSize, -HelfSize) }, { Vec3(HelfSize, HelfSize, -HelfSize) }, { Vec3(-HelfSize, -HelfSize, -HelfSize) }, { Vec3(HelfSize, -HelfSize, -HelfSize) }, { Vec3(HelfSize, HelfSize, HelfSize) }, { Vec3(-HelfSize, HelfSize, HelfSize) }, { Vec3(HelfSize, -HelfSize, HelfSize) }, { Vec3(-HelfSize, -HelfSize, HelfSize) }, }; vector<UINT> PosIndeces = { 0, 1, 2, 3, 1, 4, 3, 6, 4, 5, 6, 7, 5, 0, 7, 2, 5, 4, 0, 1, 2, 3, 7, 6, };
vector<Vec3> FaceNormalVec = { { Vec3(0, 0, -1.0f) }, { Vec3(1.0f, 0, 0) }, { Vec3(0, 0, 1.0f) }, { Vec3(-1.0f, 0, 0) }, { Vec3(0, 1.0f, 0) }, { Vec3(0, -1.0f, 0) } };
vector<VertexPositionNormal> vertices; vector<uint16_t> indices; UINT BasePosCount = 0; for (int i = 0; i < 6; i++) { for (int j = 0; j < 4; j++) { VertexPositionNormal Data; Data.position = PosVec[PosIndeces[BasePosCount + j]]; if (m_Flat) { //フラット表示の場合は法線は頂点方向にする Data.normal = Data.position; Data.normal.normalize(); } else { //フラット表示しない場合は、法線は面の向き Data.normal = FaceNormalVec[i]; } vertices.push_back(Data); } indices.push_back((uint16_t)BasePosCount + 0); indices.push_back((uint16_t)BasePosCount + 1); indices.push_back((uint16_t)BasePosCount + 2); indices.push_back((uint16_t)BasePosCount + 1); indices.push_back((uint16_t)BasePosCount + 3); indices.push_back((uint16_t)BasePosCount + 2); BasePosCount += 4; } //メッシュの作成(変更できない) m_CubeMesh = MeshResource::CreateMeshResource(vertices, indices, false);
//6つの面のループ for (int i = 0; i < 6; i++) {
for (int j = 0; j < 4; j++) {
VertexPositionNormal Data; Data.position = PosVec[PosIndeces[BasePosCount + j]];
if (m_Flat) { //フラット表示の場合は法線は頂点方向にする Data.normal = Data.position; Data.normal.normalize(); } else { //フラット表示しない場合は、法線は面の向き Data.normal = FaceNormalVec[i]; }
//フラット表示の場合は法線は頂点方向にする Data.normal = Data.position; Data.normal.normalize();
//フラット表示の場合は法線は頂点方向にする Data.normal = Data.position - Vec3(0,0,0);
//メッシュの作成(変更できない) m_CubeMesh = MeshResource::CreateMeshResource(vertices, indices, false);