質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
3DCG

コンピュータの演算により、3次元空間の仮想物体を、2次元平面上で表現する手法である。

DXライブラリ

DXライブラリとは、DirectXを使ったWindowsソフトの開発に必ず付いて回るDirectXやWindows関連のプログラムを使い易くまとめた形で利用できるようにしたC++言語用のゲームライブラリです。

Q&A

解決済

1回答

950閲覧

複数の面と共有している頂点の法線を設定したいが上手くいかない理由が知りたい

退会済みユーザー

退会済みユーザー

総合スコア0

3DCG

コンピュータの演算により、3次元空間の仮想物体を、2次元平面上で表現する手法である。

DXライブラリ

DXライブラリとは、DirectXを使ったWindowsソフトの開発に必ず付いて回るDirectXやWindows関連のプログラムを使い易くまとめた形で利用できるようにしたC++言語用のゲームライブラリです。

0グッド

0クリップ

投稿2020/05/03 04:01

編集2020/05/03 04:35

###やりたいこと
[頂点法線を設定してライトの当たり方を試したい。のために頂点法線を設定したい]

###困っていること
[
面法線を算出してその求めたい頂点が共有している面法線を全部足して正規化してその頂点の頂点法線を算出するコードなのですが
VECTOR Game::Surface_normal(const VERTEX3D result, const VERTEX3D v1, const VERTEX3D v2, const bool n);

ofs <<"ああああああ"部のresultの値であああああ -nan(ind) , -nan(ind) , -nan(ind)と出力されているので
そのコード以前の場所で問題が起きていると思われるのですがこれはなぜなのでしょうか?

また頂点法線の算出法は正しいのでしょうか?]

試したこと

頂点座標は上手前から右、奥、奥右、
そして下左のように回転しています、インデックスも正しいです。(Index配列)
テクスチャをオン、オフ切替ましたが正しい位置で頂点座標も正しいため正方形が画面の真ん中に設定されています。]

###起きている問題
表示されたキューブが真っ黒になる。しかしライトやテクチャは正しいいです。確認済みなので頂点法線が正しく設定されていないためと推測

イメージ説明

#include "DxLib.h" #include "Game.hpp" #include "Input.hpp" #include "Frame.hpp" #include "Vector.hpp" const char* filename = "Log.txt"; std::ofstream ofs(filename); /*boolは正規化するかどうか?*/ /*面法線を返す関数 result から伸びてるv1,v2*/ VECTOR Game::Surface_normal(const VERTEX3D result, const VERTEX3D v1, const VERTEX3D v2, const bool n) { VECTOR a, b; VECTOR p; //p2, p3;//それぞれの面法線を入れる // VECTOR result;//頂点法線 a.x = v1.pos.x - result.pos.x; a.y = v1.pos.y - result.pos.y; a.z = v1.pos.z - result.pos.z; b.x = v2.pos.x - result.pos.x; b.y = v2.pos.y - result.pos.y; b.z = v2.pos.z - result.pos.z; p = Vector::cross(a, b);//面法線 // result = VAdd(VAdd(p1, p2), p3); if (n == true) { normalize(&p);//正規化 return p; } else { return p; } } //頂点法線を設定する void Game::Vertex_Norm(){ /*頂点を法線を算出*/ VECTOR a, b; VECTOR s1, s2, s3;//それぞれの面法線を入れる VECTOR result;//頂点法線 a = Surface_normal(Vertex[0], Vertex[4], Vertex[5], true); b = Surface_normal(Vertex[0], Vertex[1], Vertex[5], true); ofs << "a " << a.x << " , " << a.y << " , " << a.z << std::endl; ofs << "b " << b.x << " , " << b.y << " , " << b.z << std::endl; s1 = VAdd(a, b); ofs << "s1 " << s1.x << " , " << s1.y << " , " << s1.z << std::endl; // ofs << "正規化後 s1 " << s1.x << " , " << s1.y << " , " << s1.z << std::endl; a = Surface_normal(Vertex[0], Vertex[4], Vertex[7], true); b = Surface_normal(Vertex[0], Vertex[3], Vertex[7],true); s2 = VAdd(a, b); a = Surface_normal(Vertex[0], Vertex[3], Vertex[2], true); b = Surface_normal(Vertex[0], Vertex[1], Vertex[2], true); s3 = VAdd(a, b); result = VAdd(VAdd(s1, s2), s3); ofs << "あああああ " << result.x << " , " << result.y << " , " << result.z << std::endl; normalize(&result); // ofs << "いいいいい" << result.x << " , " << result.y << " , " << result.z << std::endl; Vertex[0].norm = result; // ofs<< "うううううう" << Vertex[0].norm.x <<" , " << Vertex[0].norm.y << " , " << Vertex[0].norm.z <<std::endl; a = Surface_normal(Vertex[1], Vertex[5], Vertex[4], false); b = Surface_normal(Vertex[1], Vertex[0], Vertex[4], false); s1 = VAdd(a, b); a = Surface_normal(Vertex[1], Vertex[5], Vertex[6], false); b = Surface_normal(Vertex[1], Vertex[2], Vertex[6], false); s2 = VAdd(a, b); a = Surface_normal(Vertex[1], Vertex[0], Vertex[3], false); b = Surface_normal(Vertex[1], Vertex[2], Vertex[3], false); s3 = VAdd(a, b); result = VAdd(VAdd(s1, s2), s3); normalize(&result); Vertex[1].norm = result; a = Surface_normal(Vertex[2], Vertex[1], Vertex[6], false); b = Surface_normal(Vertex[2], Vertex[5], Vertex[6], false); s1 = VAdd(a, b); a = Surface_normal(Vertex[2], Vertex[3], Vertex[7], false); b = Surface_normal(Vertex[2], Vertex[6], Vertex[7], false); s2 = VAdd(a, b); a = Surface_normal(Vertex[2], Vertex[3], Vertex[0], false); b = Surface_normal(Vertex[2], Vertex[1], Vertex[0], false); s3 = VAdd(a, b); result = VAdd(VAdd(s1, s2), s3); normalize(&result); Vertex[2].norm = result; a = Surface_normal(Vertex[3], Vertex[2], Vertex[6], false); b = Surface_normal(Vertex[3], Vertex[7], Vertex[6], false); s1 = VAdd(a, b); a = Surface_normal(Vertex[3], Vertex[0], Vertex[4], false); b = Surface_normal(Vertex[3], Vertex[7], Vertex[4], false); s2 = VAdd(a, b); a = Surface_normal(Vertex[3], Vertex[0], Vertex[1], false); b = Surface_normal(Vertex[3], Vertex[2], Vertex[1], false); s3 = VAdd(a, b); result = VAdd(VAdd(s1, s2), s3); normalize(&result); Vertex[3].norm = result; a = Surface_normal(Vertex[4], Vertex[5], Vertex[6], false); b = Surface_normal(Vertex[4], Vertex[7], Vertex[6], false); s1 = VAdd(a, b); a = Surface_normal(Vertex[4], Vertex[0], Vertex[3], false); b = Surface_normal(Vertex[4], Vertex[7], Vertex[3], false); s2 = VAdd(a, b); a = Surface_normal(Vertex[4], Vertex[5], Vertex[1], false); b = Surface_normal(Vertex[4], Vertex[0], Vertex[1], false); s3 = VAdd(a, b); result = VAdd(VAdd(s1, s2), s3); normalize(&result); Vertex[4].norm = result; a = Surface_normal(Vertex[5], Vertex[4], Vertex[7], false); b = Surface_normal(Vertex[5], Vertex[6], Vertex[7], false); s1 = VAdd(a, b); a = Surface_normal(Vertex[5], Vertex[4], Vertex[0], false); b = Surface_normal(Vertex[5], Vertex[1], Vertex[0], false); s2 = VAdd(a, b); a = Surface_normal(Vertex[5], Vertex[1], Vertex[2], false); b = Surface_normal(Vertex[5], Vertex[6], Vertex[2], false); s3 = VAdd(a, b); result = VAdd(VAdd(s1, s2), s3); normalize(&result); Vertex[5].norm = result; a = Surface_normal(Vertex[6], Vertex[7], Vertex[4], false); b = Surface_normal(Vertex[6], Vertex[5], Vertex[4], false); s1 = VAdd(a, b); a = Surface_normal(Vertex[6], Vertex[7], Vertex[3], false); b = Surface_normal(Vertex[6], Vertex[2], Vertex[3], false); s2 = VAdd(a, b); a = Surface_normal(Vertex[6], Vertex[2], Vertex[1], false); b = Surface_normal(Vertex[6], Vertex[5], Vertex[1], false); s3 = VAdd(a, b); result = VAdd(VAdd(s1, s2), s3); normalize(&result); Vertex[6].norm = result; a = Surface_normal(Vertex[7], Vertex[3], Vertex[2], false); b = Surface_normal(Vertex[7], Vertex[6], Vertex[2], false); s1 = VAdd(a, b); a = Surface_normal(Vertex[7], Vertex[3], Vertex[0], false); b = Surface_normal(Vertex[7], Vertex[4], Vertex[0], false); s2 = VAdd(a, b); a = Surface_normal(Vertex[7], Vertex[4], Vertex[5], false); b = Surface_normal(Vertex[7], Vertex[6], Vertex[5], false); s3 = VAdd(a, b); result = VAdd(VAdd(s1, s2), s3); normalize(&result); Vertex[7].norm = result; } /*コンストラクタ 初期化*/ Game::Game() { /*操作切替*/ mc = ModeChange::rotate; /*ライト設定*/ LightHandle = CreateDirLightHandle(VGet(0, -1, 0)); if(LightHandle == -1) { exit(1); } SetLightEnable(true); //標準ライトを有効にするかどうか? // SetLightEnable(false);//標準ライトを有効にするかどうか? SetUseLighting(true); //SetUseLighting(false); SetUseZBuffer3D(true); SetWriteZBuffer3D(true); handle = LoadGraph("assets/resource/texturePos.png"); cameraPos.x = 0; cameraPos.y = 20; cameraPos.z = -40; targetV.x = 0; targetV.y = 0; targetV.z = 0; /*上 手前から右回りで 回ったら下で手前から右回り*/ ////////////////////////////////////////////////////////////////////////////////上の面の頂点 Vertex[0].pos = VGet(targetV.x - RANGE, targetV.y + RANGE, targetV.z - RANGE); Vertex[0].norm = VGet(0.0f, 0.0f, -1.0f); Vertex[0].dif = color_dif; Vertex[0].spc = color_spc; Vertex[0].u = 0.0f; Vertex[0].v = 0.0f; Vertex[1].pos = VGet(targetV.x + RANGE, targetV.y + RANGE, targetV.z - RANGE); Vertex[1].norm = VGet(0.0f, 0.0f, -1.0f); Vertex[1].dif = color_dif; Vertex[1].spc = color_spc; Vertex[1].u = 0.0f; Vertex[1].v = 0.0f; Vertex[2].pos = VGet(targetV.x + RANGE, targetV.y + RANGE, targetV.z + RANGE); Vertex[2].norm = VGet(0.0f, 0.0f, -1.0f); Vertex[2].dif = color_dif; Vertex[2].spc = color_spc; Vertex[2].u = 0.0f; Vertex[2].v = 0.0f; Vertex[3].pos = VGet(targetV.x - RANGE, targetV.y + RANGE, targetV.z + RANGE); Vertex[3].norm = VGet(0.0f, 0.0f, -1.0f); Vertex[3].dif = color_dif; Vertex[3].spc = color_spc; Vertex[3].u = 0.0f; Vertex[3].v = 0.0f; ////////////////////////////////////////////////////////////////////////////////下の面の頂点 Vertex[4].pos = VGet(targetV.x - RANGE, targetV.y - RANGE, targetV.z - RANGE); Vertex[4].norm = VGet(0.0f, 0.0f, -1.0f); Vertex[4].dif = color_dif; Vertex[4].spc = color_spc; Vertex[4].u = 0.0f; Vertex[4].v = 0.0f; Vertex[5].pos = VGet(targetV.x + RANGE, targetV.y - RANGE, targetV.z - RANGE); Vertex[5].norm = VGet(0.0f, 0.0f, -1.0f); Vertex[5].dif = color_dif; Vertex[5].spc = color_spc; Vertex[5].u = 0.0f; Vertex[5].v = 0.0f; Vertex[6].pos = VGet(targetV.x + RANGE, targetV.y - RANGE, targetV.z + RANGE); Vertex[6].norm = VGet(0.0f, 0.0f, -1.0f); Vertex[6].dif = color_dif; Vertex[6].spc = color_spc; Vertex[6].u = 0.0f; Vertex[6].v = 0.0f; Vertex[7].pos = VGet(targetV.x - RANGE, targetV.y - RANGE, targetV.z + RANGE); Vertex[7].norm = VGet(0.0f, 0.0f, -1.0f); Vertex[7].dif = color_dif; Vertex[7].spc = color_spc; Vertex[7].u = 0.0f; Vertex[7].v = 0.0f; /*手前*/ Index[0][0] = 0; Index[0][1] = 4; Index[0][2] = 5; Index[0][3] = 0; Index[0][4] = 5; Index[0][5] = 1; /*右*/ Index[1][0] = 1; Index[1][1] = 6; Index[1][2] = 2; Index[1][3] = 1; Index[1][4] = 6; Index[1][5] = 5; /*奥*/ Index[2][0] = 3; Index[2][1] = 6; Index[2][2] = 7; Index[2][3] = 3; Index[2][4] = 2; Index[2][5] = 6; /*左*/ Index[3][0] = 0; Index[3][1] = 3; Index[3][2] = 7; Index[3][3] = 0; Index[3][4] = 4; Index[3][5] = 7; /*上*/ Index[4][0] = 0; Index[4][1] = 3; Index[4][2] = 2; Index[4][3] = 0; Index[4][4] = 1; Index[4][5] = 2; /*下*/ Index[5][0] = 4; Index[5][1] = 5; Index[5][2] = 6; Index[5][3] = 4; Index[5][4] = 7; Index[5][5] = 6; Vertex_Norm(); }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

とりあえずa,bで頂点の指定が逆周りなので法線が逆方向を向いていそうです。
ただそれだけでは0になるはずなので-nanになっている理由が分かりません。
もうちょっと問題が起きていそうな前後の値を頻繁に出してください。

投稿2020/05/03 13:56

ikadzuchi

総合スコア3047

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/05/04 06:35

質問ですが 関数 VECTOR Game::Surface_normal(const VERTEX3D result, const VERTEX3D v1, const VERTEX3D v2, const bool n); の定義内のa,bでしょうか?
ikadzuchi

2020/05/04 09:31

ああ、すいませんa,bは複数ありましたね。void Game::Vertex_Norm()内の a = Surface_normal(Vertex[0], Vertex[4], Vertex[5], true); b = Surface_normal(Vertex[0], Vertex[1], Vertex[5], true); などのことです。
退会済みユーザー

退会済みユーザー

2020/05/04 11:09

質問ですが頂点の指定が逆回りなのでという説明がありますがどのような意味なのでしょうか? 自分はこのURLを参考にしましたがhttps://wgld.org/d/contribution/a002.html
ikadzuchi

2020/05/07 16:39

すいません返答を忘れていました。逆回りとは例えばaがVertexの0,4,5の順、bが0,1,5の順に指定されていて、aが左回りならbが右回りというように逆方向の指定になっています。これでは結果の正負が逆に出ます。
退会済みユーザー

退会済みユーザー

2020/05/08 01:06

なるほど。自分の調べて指定向きについて知りました。頂点座標を回転したあともこのやり方でまた頂点法線をその都度再設定すればいいのでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問