トップページ
ひらく | たたむ | ページトップ
↓マウスで反転選択した文字を検索
OpenGL
   
ページ内検索 ページ外検索
検索したい文字を入力して
ENTERを押すと移動します。
\n
[ トップページ ]
[ ____CommandPrompt ] [ ____JScript ] [ ____MySQL ] [ ____Cygwin ] [ ____Java ] [ ____Emacs ] [ ____Make ] [ ____Perl ] [ ____Python ] [ ____OpenGL ] [ ____C# ] [ ____StyleSheet ] [ ____C++ ] [ ____Winsock ] [ ____Thread ] [ ____VisualStudio ] [ ____C ] [ ____Win32API ] [ ____Lua ] [ ____PhotoShop ]
ヘッダ検索
___

■ ライティング(Lighting)


  SAMPLE
     ライティング計算 
     カメラの移動とライティング計算 
     ワールド座標指定のライティング 



___

■ Lighting

DESC ライティング結果は ライトの設定である glLight() と オブジェクトの材質設定の glMaterial() によって決まる。 計算結果は各頂点の色(プライマリーカラー)となり、 照明がオフの場合は glColor() で指定したカラーが適用される。 テクスチャなどのフラグメント処理は頂点カラーの決定後にされる。 POINT ライトの位置( 向き )の指定も頂点変換と同じように、モデルビュー変換の影響を受ける。 glLight( GL_POSITION ); をコールした時点で指定した座標が変換される。 常に正面から照らす設定は以下になる。
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
    float dir[] = { 0, 0, 1, 0 };
    glLightfv( GL_LIGHT0, GL_POSITION, dir );
ワールド座標で指定するにはカメラ座標系から変換する。
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
    convertCameraSpace( 0, 0, 500, cy, cx );

    // ワールド座標の 0 0 1 の方向から照らす。
    float dir[] = { 0, 0, 1, 0 };
    glLightfv( GL_LIGHT0, GL_POSITION, dir );
ライティング計算のための初期化をする。
    App::onInit() {

      // Lighting 処理を有効化( DEFAULT : オフ )
      glEnable( GL_LIGHTING );

      // ライト数は 少なくとも 8 つ
      // 個別に ON/OFF できる。
      glEnable( GL_LIGHT0 );

      
      // ライトの位置を設定する
      glMatrixMode( GL_MODELVIEW );
      glLoadIdentity();
      float dir [] = { -0.3f, 0, 1, 0 };
      glLightfv( GL_LIGHT0, GL_POSITION, dir );
    }

描画時は法線( glNormal )を設定したモデルを描画する。
    App::onDraw() {    

      // 法線をもつプリミティブを描画
      //    残りの Light の parameter はすべてデフォルトを使う
      drawNormalCube();

      // WARNING
      //  Lighting ON は 不要ならばオフにする。
      //  以下の 頂点処理に影響をうける
      glDisable( GL_LIGHTING );
    }
___

■ ライトの色

ライティングは次の3つの要素で近似する。
    環境光 : 間接光
    拡散光 : 面に対して均等に拡散する面
    鏡面光 : 光沢のある面
ライティングの内部計算。 L : ライト M : マテリアル
     Env * aM +
    aL * aM +
    dL * dM * ( N.L ) +
    sL * sM + ( N.R )
___

■ 法線(Normal)

DESC OpenGL は Normal を見て面の向きを決める。 ライティング計算をするためには、面の向きを指定する必要がある。 WARNING 頂点と同じくモデルビュー行列の影響をうけるため Scale 成分の影響をうける。

    // Normalize を ON
    glEnable( GL_NORMALIZE );

    // Scaling のみの調整をする
    //    Scale Matrix が 等しいなら これで十分
    glEnable( GL_RESCALE_NORMAL );


    // 最も効率的なのは init 時に normal を再計算すること
    recalcNormal();

___

■ LightParameter


    GLInt nr;
    glGetIntegerv( GL_MAX_LIGHTS, &nr );

    // 各 Light を有効化 ( GL_LIGHTi )
    glEnable( GL_LIGHT0 );

    // 各 Light の parameter 設定
    glLightfv( GL_LIGHT0, GL_DIFFUSE, col );
    glLightfv( GL_LIGHT0, GL_POSITION, pos );

___

■ glLight

SYNTAX glLight( GLenum light, GLenum pramName, // GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_POSITION TYPE *val // color | position ) DESC ライトのパラメータ( 色、位置 )を設定する。 DEFAULT GL_AMBIENT : 0, 0, 0 // Ambient とは 間接光 ( N 回 Bounce ) の近似 GL_LIGHT0 GL_DIFFUSE : 1, 1, 1 GL_SPECULAR : 1, 1, 1 GL_LIGHT1 - N GL_DIFFUSE : 0, 0, 0 GL_SPECULAR : 0, 0, 0 DESC ライトの位置の設定も頂点と同じく、glLight() をコールした時点での モデルビュー行列変換の影響を受ける。 平行光( DirectionLight )を利用するには, 位置指定のw成分を 0 にする。 無限遠の 0, 0, 1 の位置に置いたことになり 0, 0, -1 方向への平行光として計算される。
    // 平行光
    float dir [] = { 0, 0, 1, 0 };
    glLightfv( GL_LIGHT0, GL_POSITION, dir );

    // 位置で指定
    float pos [] = { 0, 0, 1, 1 };
    glLightfv( GL_LIGHT0, GL_POSITION, pos );
___

■ glMaterial

SYNTAX glMaterial( GLenum face, // 表裏の指定 GLenum pramName, // GL_AMBIENT | GL_DIFFUSE | GL_SPECULAR | GL_SHININESS const TYPE *val ) DESC オブジェクトの色を指定する。 ライトの各成分と乗算される。 POINT アルファ成分は GL_DIFFUSE で指定したアルファ成分が頂点のアルファ色になる。 GL_AMBIENT, GL_SPECULAR の指定は無視される。
    float col[] = { 0, 1, 0, 1 };
    glMaterialfv( GL_FRONT, GL_AMBIENT, col );
    glMaterialfv( GL_FRONT, GL_DIFFUSE, col );
    glMaterialfv( GL_FRONT, GL_SPECULAR, col );


    // GL_SHININESS [0:128] DEFAULT 0
    glMaterialf( GL_FRONT, GL_SHININESS, 128 );
___

■ レイトレース(RayTrace)

物が見えるのは、レンズに光(レイ)が飛びこんでくる結果なのでこれを逆からトレースするという考え方。 Direct 1 Bound : 通常のライティングモデル ( ) 2 Bound : 照り返し 画素の数だけ、このトレースを繰り返す 2 バウンド
    光源からライトがでる ---> 赤い壁にあたる ---> 白い布を照らす  ---> カメラのレンズに届く 
カメラから画素へ向かってレイをとばす。 何かにあたる その何かは、全方向からの光の影響をうけるので、全方向にライトをとばす これを N 階の深さまで繰り返す。 光源方のみに絞ったは 1 バウンドは、直接の光源のみなので、反対領域は黒くなる。 そこで、1バウンドに限定して、暗い部分は適当にバイアスを足しておく( アンビエント ) 1バウンドも、ライトという光源方向のみに限定する。 これで画素数だけの計算回数になる。 明るさは 面積あたりの光の粒の数( 密度 )なので、距離の2乗に比例する。 しかし、太陽などの十分に長い距離に対しては、100m などは 0m として近似できるため 距離の減衰を無視できる。 反射の割合( 分布 ) ある方向からきた光は、必ず一定方向にだけ反射するわけではない。 そうだとしたら見る方向をかえると、黒く見えてしまう。 そこで、全方向に一様に反射すると仮定する。 これを計算式として表現すると、ディフューズモデルができる
      I = I0 * R * cos(theta),  cos(theta) =  dot(L , N)

      L  : 頂点から光源へのベクトル
      N  : 頂点の法線ベクトル
      I0 : 光源の色
      R  : 反射する割合
___

■ ライティング計算を自前でする

OpenGL にはライティング計算をするための API があるが 自前で計算式から明るさを求めて、頂点カラーとして渡すこともできる。 テクスチャを貼るときは、 GL_MODULATE をつかえばいい。 REFERENCE テクスチャのブレンド方法を指定する






金利比較.COM
NINJAIDX 9