-1

openGL でのコーディングがどのように機能するかを理解しようとしています。インターネットでこのコードを見つけたので、明確に理解したいと思います。

私の頂点シェーダーには、次のものがあります。

バーテックス

uniform vec3 fvLightPosition;
    varying vec2 Texcoord;
    varying vec2 Texcoordcut;
    varying vec3 ViewDirection;
    varying vec3 LightDirection;
    uniform mat4 extra;

    attribute vec3 rm_Binormal;
    attribute vec3 rm_Tangent;

    uniform float fSinTime0_X;
    uniform float fCosTime0_X;

    void main( void )
    {
       gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex * extra;
       Texcoord    = gl_MultiTexCoord0.xy;
       Texcoordcut   = gl_MultiTexCoord0.xy;

       vec4 fvObjectPosition = gl_ModelViewMatrix * gl_Vertex;

       vec3 rotationLight = vec3(fCosTime0_X,0, fSinTime0_X);
       ViewDirection  =  - fvObjectPosition.xyz;
       LightDirection = (-rotationLight ) * (gl_NormalMatrix); 
    }

Fragment シェーダでは、画像に白い色を作成して穴を作成しました。:

uniform vec4 fvAmbient;
uniform vec4 fvSpecular;
uniform vec4 fvDiffuse;
uniform float fSpecularPower;

uniform sampler2D baseMap;
uniform sampler2D bumpMap;

varying vec2 Texcoord;
varying vec2 Texcoordcut;
varying vec3 ViewDirection;
varying vec3 LightDirection;

void main( void )
{
   vec3  fvLightDirection = normalize( LightDirection );
   vec3  fvNormal         = normalize( ( texture2D( bumpMap, Texcoord ).xyz * 2.0 ) - 1.0 );
   float fNDotL           = dot( fvNormal, fvLightDirection ); 
   vec3  fvReflection     = normalize( ( ( 2.0 * fvNormal ) * fNDotL ) - fvLightDirection ); 
   vec3  fvViewDirection  = normalize( ViewDirection );
   float fRDotV           = max( 0.0, dot( fvReflection, fvViewDirection ) );
   vec4  fvBaseColor      = texture2D( baseMap, Texcoord );

   vec4  fvTotalAmbient   = fvAmbient * fvBaseColor; 
   vec4  fvTotalDiffuse   = fvDiffuse * fNDotL * fvBaseColor; 
   vec4  fvTotalSpecular  = fvSpecular * ( pow( fRDotV, fSpecularPower ) );


   if(fvBaseColor == vec4(1,1,1,1)){ 
      discard;
   }else{ 
     gl_FragColor = ( fvTotalDiffuse + fvTotalSpecular );
   }



}

すべてが何をしているのか、私に説明できる人はいますか? その基本的な考え方は理解しています。しかし、なぜそれが必要なのか、他の変数を使用するとどうなるのかということはあまりありません。何が起こるかというと、ティーポットの周りの光が来て、そのうちに消えていきます. これは、cosinus 変数と sinus 変数とどのように正しく関連付けられていますか? 光が上から来てティーポットの底に行きたい場合はどうすればよいですか?

また、

  • この行はどういう意味ですか?

    vec4 fvObjectPosition = gl_ModelViewMatrix * gl_Vertex;

  • そして、なぜここで変数の前にマイナスがあるのですか?

    ViewDirection = - fvObjectPosition.xyz;

  • なぜ負のrotationLightを使用するのですか?

    LightDirection = (-rotationLight ) * (gl_NormalMatrix);

  • 法線ベクトルの計算に *2.0 ) - 1.0 を使用するのはなぜですか? Normal = normalize( gl_NormalMatrix * gl_Normal);ではそれは不可能ではありませんか? ?

    vec3 fvNormal = normalize( ( texture2D( バンプマップ, Texcoord ).xyz * 2.0 ) - 1.0 );

4

2 に答える 2

2

シェーダーに送信している内容の適切なコンテキストなしでコードを完全に分析するには怠惰すぎます...しかし、サブ質問は十分に簡単です:

  1. この行はどういう意味ですか? vec4 fvObjectPosition = gl_ModelViewMatrix * gl_Vertex;

    これによりgl_Vertex、オブジェクト/モデル座標系からカメラ座標系に (ポリゴン エッジ ポイント) が変換されます。つまり、頂点のすべての回転と平行移動が適用されます。z軸は、スクリーンを指す、またはスクリーンから指すカメラ ビュー軸であり、軸はスクリーンと同じx,yです。プロジェクション/クリッピング/クランプはまだ適用されていません!!! 結果のポイントはfvObjectPosition4D ベクトルに格納されます。4x4 同種変換行列の理解(x,y,z,w)を読むことを強くお勧めします。そこにあるサブリンクも参照する価値があります。

  2. そして、なぜここで変数の前にマイナスがあるのですか? ViewDirection = - fvObjectPosition.xyz;

    おそらく、表面からカメラへの方向が必要なため、direction_from_surface=camera_pos-surface_posすでにsurface_posカメラ座標系にある(0,0,0)ため、同じ座標内のカメラ位置が結果になるdirection_from_surface=(0,0,0)-surface_pos=-surface_posか、負Zの軸のビュー方向が得られるためです(行列の形式によって異なります)。背景情報なしで判断するのは困難です。

  3. なぜ負のrotationLightを使用するのですか? LightDirection = (-rotationLight ) * (gl_NormalMatrix);

    箇条書き 2 と同じ理由である可能性が最も高い

  4. なぜ*2.0)-1.0法線ベクトルの計算に使用するのですか?

    シェーダーは法線/バンプ マッピングを使用します。これは、RGB としてエンコードされた法線ベクトルを持つテクスチャを取得したことを意味します。RGB テクスチャは範囲にクランプされ<0,1>、法線ベクトル座標は範囲内<-1,+1>にあるため、テクセルを再スケーリングする必要があります。

    • RGB*2.0範囲内です<0,2>
    • RGB*2.0-1.0範囲内です<-1,+1>

    これにより、ポリゴン座標系で法線ベクトルが取得されるため、方程式で使用する座標系に変換する必要があります。通常はグローバル ワールド空間またはカメラ空間です。法線/バンプ マップが既に正規化されている場合、正規化は必要ありません。通常のテクスチャは色で特徴的です...

    • 平らな面がnormal=(0.0,0.0,+1.0)あるので、RGBでは(0.5,0.5,1.0)

    これは、テクスチャでよく見られる一般的な青みがかった/マゼンタの色です (上記のリンクを参照)。

    しかし、はい、使用できますNormal = normalize( gl_NormalMatrix * gl_Normal);

    しかし、それはバンプ/法線マップを排除し、代わりに平らな表面だけを得るでしょう. このようなもの:

  5. vec3(fCosTime0_X,0, fSinTime0_X)光の方向に見えます。これはy軸を中心に回転しています。光の方向を別のものに変更したい場合は、それを均一にして、代わりにシェーダーに直接渡します。fCosTime0_X,fSinTime0_X

于 2015-08-17T09:34:56.213 に答える
0

これは、cosinus 変数と sinus 変数とどのように正しく関連付けられていますか?

glUniform 関数を使用して、データをシェーダー ユニフォーム変数に送信できます。たとえば、頂点シェーダーには 2 つの float 値があるため、glUniform1f を毎回異なる場所と異なる値で 2 回呼び出します。
または、float 変数を次のように 1 つの vec2 変数に貼り付けることができます
uniform vec2 fSinValues;glUniform2f(location, sinVal, cosVal);

光が上から来てティーポットの底に行きたい場合はどうすればよいですか?

光を別の方向に回転させたい場合は、ここで sin 値と cos 値を別の空間座標に渡すだけです。vec3 rotationLight = vec3(fCosTime0_X,fSinTime0_X, 0);

于 2015-08-13T16:59:58.550 に答える