サンプル7


  今回は、OpenGLにおける、ライトの使い方と、ポリゴンの質感の設定方法についでです。


目次

質感について

   OpenGLの質感パラメタには、次の5つがあります。(いい加減な説明だけど)
 
Ambient   環境光に対する照らされかた。環境光とは、空気による乱反射などによる光のこと。実際には、環境光が一定などということは無いが、わざわざ計算するととんでもない計算量になるし、一定にしてもたいして問題にはならないので、OpenGLでの環境光はどの物体も一定の明るさに照らすようになっている。
  この値を大きくすると、環境光に対して明るく照らされるようになる。あまり大きくするとのっぺりして、立体感がなくなるので注意。
Diffuse   拡散光に対する照らされかた。拡散光とは、点光源から全方位に向かって放たれる光のこと。ポリゴンの向や、光源からの距離によって明るさが変わってくる。
Specular   鏡面反射のようなテカテカ感を出す。この値を大きくすると、光源が映り込むような感じとなり、ポリゴン表面が金属光沢があるように見える。
Shiniess   この値を大きくすると、光源の映り込みがより鋭くなり、表面がよりツルツルに見える。
Emission   この値を0以上にすると、自ら発光し、光源がなくても物体が見える。ただし、見えるのはその物体自信だけであり、周りの物体がこれによって照らされることはない。


質感の例

Ambient=0.0
Diffuse=1.0

  環境光がないので、宇宙空間の様な感じになる。

0.0:1.0
Ambient=0.1
Diffuse=0.9

  Ambient=0.1〜0.2ぐらいが自然に見える。

0.1:0.9
Ambient=0.5
Diffuse=0.5

  環境光が多すぎる。全体が明るくなってしまって、立体感がない。これではわざわざ光源を設定をする意味がない。

0.5:0.5

Ambient=0.1
Diffuse=0.6
Specular=0.0
Shiniess=20.0

  光沢なし。色のついた物体のSpecular値を大きくすると、プラスティックみたいになってしまうので、普通はSpecularは0.0〜0.2ぐらいにしておいた方が良いように思う。

Ambient=0.1
Diffuse=0.6
Specular=1.0
Shiniess=20.0

  光沢あり。ただ、悲しいことに、OpenGLでは(他のリアルタイム3Dライブラリもそうだが)、明るさをポリゴンの頂点でしか計算しないため、あまりきれいなテカテカがでないのだ。

Ambient=0.1
Diffuse=0.6
Specular=1.0
Shiniess=60.0

  Shinessをあげると、テカテカがより鋭くなり、光沢感がでる。


質感の設定

 OpenGLで質感を設定するときは、通常glMaterialfv()を使います。いままで使ってきた、glColor3fv()と同様に、図形を描く前に質感を設定するという手順をとります。

void glMaterialfv(GLenum face, GLenum pname, const GLfloat *params)

  OpenGLのポリゴンには、表と裏という概念があって、faceはそのどちらの面の質感を設定するかを指定する。GL_FRONT(表)、GL_BACK(裏)、GL_FRONT_AND_BACK(両方)のうちのいずれか。今回は、ひとまずGL_FRONT_AND_BACKを指定しておいた。ポリゴンの表裏に関しては、他の機会に説明する。
  pnameは、質感のどのパラメタを設定するかを指定する。GL_AMBIENT、GL_DIFFUSE、GL_SPECULAR、GL_EMISSION、GL_SHININESSなどがあり、このうちの1つを選んで設定する。それぞれ、質感についてで解説した通り。
  paramsには、実際に設定する値の入った配列を渡す。GL_AMBIENT、GL_DIFFUSE、GL_SPECULAR、GL_EMISSIONの場合は、RGBA形式である。それぞれ、─1から1の範囲の値を入れる。GL_SHININESSの場合は、渡す値は1つで、0から128の範囲の値である。GL_SHINESSを設定するだけなら、glMaterialf()を使うこともできる。

光源について

  今度は、光源についてです。OpenGLで使える光源には、環境光、点光源(拡散光を出す)、平行光、スポットライトがありますが、平行光は点光源と同じような扱いになっています。ここでは環境光、点光源、平行光の使い方についてのみ解説します。
  光源を方法としては、光源の設定を、glLightfv()で行い、glEnable()で光源を使用するようにする。

glEnable(GL_LIGHTING)

  ライティングを有効にする。ポリゴンの向きや光源からの距離に応じてポリゴンの明るさを計算するようになる。これをやらないと、光源や質感の設定をやっても全く反映されない。
glEnable(GL_LIGHT0)
  0番の光源を使うようにする。OpenGLでは、GL_LIGHT0〜GL_LIGHT7の8つの光源は最低使え、環境によってはそれ以上の数の光源を使うこともできる。でも普通は多くても2〜3個しか使わないと思うけど。
void glLightfv(GLenum light, GLenum pname, const GLfloat *params )
  光源の設定をする。glMaterialfv()と同じような感じで設定する。
  lightには、GL_LIGHT0など、どの光源を設定するかを指定する。
  pnameには、どのパラメタを設定するかを指定する。GL_AMBIENT、GL_DIFFUSE、GL_SPECULAR、GL_POSITIONなど。
  paramsには、設定する値の入った配列を渡す。pnameがGL_AMBIENTの時は、環境光の強さを、GL_DIFFUSEの時は、拡散光もしくは平行光の強さを、GL_SPECULARの時は、テカテカの強さを、それぞれRGBA形式で─1から1の範囲で設定する。
  GL_POSITIONの時は、光源の位置をXYZW形式で指定する。W(サンプルプログラムでは、lit_pos[3])が0の場合は、光源は拡散光ではなく平行光となり、光源がXYZ方向の無限遠にあることになる。Wが0以外の場合、点光源が、XYZの位置にあることになる。このGL_POSITIONの設定も、glTranslatef()やglRotatef()の影響を受ける。


  上手に質感を設定して、ライティングをすれば、リアルタイム表示でも、かなりきれいな絵ができるはずです。サンプルプログラムのパラメタをいろいろ変えてみて、どんな感じになるか試してみてください。


戻る