0

シーンにポイント ライトがあります。カメラで照明されたオブジェクトをさまざまな角度から見てテストし、明るい領域がメッシュ上を移動することを発見するまで(私の場合は単純な平面)、正しく機能すると思いました。典型的な ADS Phong ライティング アプローチを使用しています。クライアント側でライトの位置をカメラ空間に変換してから、モデル ビュー マトリックスを使用して頂点シェーダーで補間された頂点を変換します。

私の頂点シェーダーは次のようになります。

#version 420 

layout(location = 0)  in vec4 position;
layout(location = 1)  in vec2 uvs;
layout(location = 2)  in vec3 normal;

uniform mat4 MVP_MATRIX;
uniform mat4 MODEL_VIEW_MATRIX;
uniform mat4 VIEW_MATRIX;
uniform mat3 NORMAL_MATRIX;

uniform vec4 DIFFUSE_COLOR;

//=======  OUTS  ============//
out smooth  vec2 uvsOut;
out flat  vec4 diffuseOut;

out  vec3 Position;
out smooth vec3 Normal;


out gl_PerVertex
{
   vec4 gl_Position;
};

void main()
{
    uvsOut = uvs;
    diffuseOut  =  DIFFUSE_COLOR;
    Normal = normal;
    Position = vec3(MODEL_VIEW_MATRIX * position);

    gl_Position = MVP_MATRIX * position;
}

フラグメント シェーダー:

//====================  Uniforms  ===============================
struct LightInfo{

 vec4 Lp;///light position
 vec3 Li;///light intensity
 vec3 Lc;///light color
 int  Lt;///light type

};

const int MAX_LIGHTS=5;

uniform LightInfo lights[1];


// material props:
uniform vec3 KD;
uniform vec3 KA;
uniform vec3 KS;
uniform float SHININESS;
uniform int num_lights;

////ADS lighting method :

vec3 pointlightType( int lightIndex,vec3 position , vec3 normal) {

    vec3 n = normalize(normal);
    vec4 lMVPos = lights[0].Lp ;  //
    vec3 s = normalize(vec3(lMVPos.xyz) - position); //surf to light
    vec3 v = normalize(vec3(-position)); //
    vec3 r = normalize(- reflect(s , n));
    vec3 h = normalize(v+s);

    float sDotN = max( 0.0 , dot(s, n) );

    vec3 diff = KD *  lights[0].Lc * sDotN ;
    diff = clamp(diff ,0.0 ,1.0);

    vec3 spec = vec3(0,0,0);

    if (sDotN > 0.0) {
        spec = KS * pow( max( 0.0 ,dot(n,h) ) ,  SHININESS);
        spec = clamp(spec ,0.0 ,1.0);
    }

    return lights[0].Li *  ( spec+diff);
}

私は多くのチュートリアルを研究しましたが、空間の変換に関しては、プロセス全体について完全な説明を提供するものはありません.光と頂点の位置を変換するカメラ空間と関係があると思われます.私の場合、ビューマトリックスはで作成

  glm::lookAt()

これは常に「目」ベクトルを無効にするため、シェーダーのビュー マトリックスが変換部分を無効にしていることになります。プログラム可能なパイプラインでどのように正しい方法で行われるかを誰かが詳細に説明できますか? 私のシェーダーは、本「OpenGL 4.0 Shading language cookbook」に基づいて実装されています。作者はカメラ空間も使用しているようです。しかし、それが機能する方法でない限り、正しく機能しません...

計算をワールド スペースに移動したところです。これで、ポイント ライトはその場にとどまります。しかし、カメラ スペースを使用して同じことを行うにはどうすればよいでしょうか。

4

1 に答える 1

1

私はバグを突き止めましたが、それはかなりばかげたものでした.しかし、「数学に親しみやすい」他の人には役立つかもしれません.シェーダーでの私の光の位置は vec3 で定義されています.今、クライアント側では vec4 で表されます.ビューマトリックスで変換する前に、vec4の.wコンポーネントを毎回ゼロに等しく設定していました。そうすると、ライト位置ベクトルが正しく変換されず、これからすべてのライト位置の問題が発生すると思います解決策は、ライト位置ベクトルの w コンポーネントを常に 1 に保つことです。

于 2013-04-28T09:24:56.500 に答える