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

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

ただいまの
回答率

88.19%

GLSL 平行光源の光の当たり方がおかしいのか?正しいのか知りたい。

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 313

syoshinsya_

score 226

提示画像ですが平行光源を使ったフォングの反射モデルですが黒い部分は光当たっていない面の色だと思うのですがこれはシェーダーが間違えているためのバグなのでしょうか?平行光源の向きを画面に表示させるには難易度が高すぎて出来ないの質問でしました。

イメージ説明

/*****************************************************************************************************************
* ライティング  .vert
******************************************************************************************************************/

#version 400

//************ layout 
layout(location = 0) in vec3 in_Position;    //頂点座標
layout(location = 1) in vec2 in_TexCoord;    //テクスチャ座標
layout(location = 2) in vec3 in_Normal;        //法線

//************ uniform 
uniform mat4 worldMatrix;    //ワールド行列
uniform mat4 viewMatrix;    //ビュー行列

//************ フラグメントの送る
out vec2 fragTexCoord;    //UV
out vec3 fragNormal;    //法線
out vec3 fragWorldPos;    //ワールド空間(位置)

///////////////////////////////////////////////////////
void main()
{
    //同次元座標に変換してワールド座標に変換
    vec4 pos = vec4(in_Position, 1.0);    
    pos = worldMatrix * pos;
    fragWorldPos = pos.xyz;


    vec4 p = vec4(in_Position, 1.0);
    gl_Position = viewMatrix  * pos;

    //fragNormal = (vec4(inNormal, 0.0f) * worldMatrix).xyz;
    fragNormal = in_Normal;

    fragTexCoord = in_TexCoord;
}
///////////////////////////////////////////////////////
/*****************************************************************************************************************
* ライティング  .frag
******************************************************************************************************************/
#version 400

//並行光源用の構造体
struct DirectionalLight
{    
    vec3 mDirection;    //光の方向
    vec3 mDiffuseColor;    //拡散反射色
    vec3 mSpecColor;    //鏡面反射色
};

//************ .vertexから来た
in vec2 fragTexCoord;    //UV
in vec3 fragNormal;        //法線
in vec3 fragWorldPos;    //ワールド空間(位置)

//************ uniform
uniform sampler2D uTexture;    //テクスチャ画像

uniform vec3 CameraPos;        //カメラ位置
uniform vec3 AmbientLight;    //環境光の強さ
uniform float SpecPower;    //表面の鏡反射指数

uniform DirectionalLight DirLight;    //平行光源

//************ 画面に出力
out vec4 out_color;    //色

///////////////////////////////////////////////////////
void main()
{
    //表面法線 N
    //vec3 N = normalize(fragNormal);
    vec3 N = fragNormal;

    //表面から光源へのベクトル L 
    vec3 L = normalize(-DirLight.mDirection);

    //表面からカメラへのベクトル V
    vec3 V = normalize(CameraPos - fragWorldPos);

    //Nに関する -L の反射 R 
    vec3 R = normalize(reflect(-L, N));

    //フォンの反射を計算する
    vec3 Phong = AmbientLight;
    float NdotL = dot(N, L);
    if (NdotL >= 0)
    {
        vec3 Diffuse = DirLight.mDiffuseColor * NdotL;
        vec3 Specular = DirLight.mSpecColor * pow(max(0.0, dot(R, V)), SpecPower);
        Phong += Diffuse + Specular;
    }

    //最終的な色はテクスチャの色 x フォンの光(alpha  = 1)

    out_color = texture(uTexture, fragTexCoord) * vec4(Phong, 1.0);

//    out_color = texture(uTexture, fragTexCoord);

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

+1

バーテックスシェーダ側のコードをぱっと見した感じ,
法線に何の演算もされていないのがおかしいように思います.

法線のデータはモデルのローカルな座標系で与えられているのだと思うので,
pos = worldMatrix * pos;
なる変換によってオブジェクトが回転しているのだとすれば,法線も相応に回転させないとダメでしょう.

※念のため記しておくが,「単に法線にもworldMatrixを乗じればよい」という話ではない:法線とは「向き」であるから,法線を平行移動とかスケーリングするのは間違っているから.回転だけを適用する.

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/11/24 21:08

    とりあえず回転マトリクスをuniformにして持っててみれば良いかと.

    キャンセル

  • 2020/11/24 21:12 編集

    //fragNormal = ( RotateMatrix * vec4(in_Normal, 0.0f)).xyz;
    fragNormal = ( vec4(in_Normal, 0.0f) * RotateMatrix ).xyz;
    両方試しましたがうまく動作しません提示画像ようなおかしな?感じになってしまうのですがこれはなぜでしょうか?

    キャンセル

  • 2020/11/25 12:03

    (1)
    その絵での,色がある場所と真っ黒な場所の境界 に何か心当たりはありませんか?
    例えば,立方体の1個の面をたくさんの三角形で構成していてポリゴンの境界である,とか.

    (2)
    提示の絵では3面が見えてますが,全てが同じ明るさ?であるように見えるのも謎です.
    まずはテクスチャみたいな余計な要素を省いて確認すべきではないでしょうか.
    シェーディングも,最初はdiffuseだけにするとか.

    (3) > 両方試しましたが
    マトリクスを乗じる方向があやふやなのようであれば,復習が必要に思います.
    行き当たりばったりになってしまいます.

    キャンセル

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

  • ただいまの回答率 88.19%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る