初めてOpenGLでライティングを使おうとしたときに、
GL_AMBIRNTやらGL_DIFFUSEって何のことだかよくわからなくて、
適当に値を指定して不自然な描画結果になって、
首ををかしげていたものです。
ここでは、ライトやマテリアルの色を設定する際の、
私なりのコツを書いておこうと思います。
まずは光源のほうから。
glLight*関数でいろいろとライトの設定をするわけですが、
光源の色に関するパラメータは以下の3つ。
GL_SPECULAR |
反射光。 光源から放射された光が、物体の表面で反射したときの色。 一般に、たいていは光が物体で反射する前と後で色が変わることは無いので、 実質上、光源が放射する光の色そのものだと思ってよいと思います。 |
GL_DIFFUSE |
拡散光。 光源から放射された光が、物体に当たって拡散(乱反射)したときの色。 拡散=乱反射されるだけで、光源からの光の色が変わるわけではないので、 反射光と同じく、実質上、光源が放射する光の色と同じ。 しかし、色は同じでも、拡散されてしまうので、反射光よりも暗い。 |
GL_AMBIENT |
環境光。 光源から直接放射されるのではなく、周囲(環境)から一様に照らす光。 普通は、光源から放射された光が、周囲の物体に当たって拡散して、 その拡散された光が対象の物体に当たるのが、環境光。 なので、拡散光よりもさらに暗い。 |
さて、これらの3つのパラメータの特徴をふまえた上で、
たとえば、普通の白色の光源を設定したい場合の設定について述べます。
まず、白色の光源なので、光源が放射する光の色は、
(R,G,B,A) = (1.0, 1.0, 1.0, 1.0)
で良いでしょう。
(RGBAのAは、色ではなくて不透明度ですが、たいていの場合は1.0にしておくのが無難です。)
で、上記の表にあるとおり、反射光は、実質上、光源が放射する光の色そのものだと思ってよいので、
GL_SPECULARに設定するのは、そのまんま、
(R,G,B,A) = (1.0, 1.0, 1.0, 1.0)
です。
続いて、拡散光。
同じく、上記の表より、
反射光と同じ色ですが、反射光よりも暗めに設定します。
同じ色で暗め、というのは、色の(R,G,B)の各値に同じ値を掛け算してやればOKです。
今回の、普通の「白色の光源」の場合は、
だいたい、(反射光)×0.7~0.8ぐらいが適当かと思います。
つまり、GL_DIFFUSEに設定する色は、
(R,G,B,A) = (0.7, 0.7, 0.7, 1.0)
です。
Aは1.0のままにしておきます。
環境光。
普通は、光源からの光が周囲で拡散されてから対象の物体に当たるものなので、
拡散光よりもさらに暗く設定します。
だいたい、(反射光)×0.2ぐらいが適当かと思います。
つまり、GL_AMBIENTに設定する色は、
(R,G,B,A) = (0.2, 0.2, 0.2, 1.0)
です。
今度はマテリアルの設定。
マテリアルの「色」というのは、
入射光が物体表面で色によってどのぐらい反射されるか、
というものなので、光源の色とは、ちょっと意味合いが異なります。
つまり、マテリアルの色を表す(R,G,B,A)は、
各色成分の反射率を表しています。
なので、マテリアルに関しては、
「色」=「反射率」、だと思って良いでしょう。
たとえば、白色の光源の元で、
どの色もそのまま反射する材質=白いマテリアルなら、白く見え、
赤だけ反射してそのほかの色は反射しない材質=赤いマテリアルならば、赤く見える、
という具合です。
マテリアルの色に関するパラメータは以下の通り。
GL_SPECULAR |
反射光。 光源から放射された光が、物体の表面で反射したときの色。 普通は、物体表で光が反射する場合は、面に入射した光(入射光)は、 そのまま反射光としてはね返っていくだけ。 |
GL_DIFFUSE |
拡散光。 光源から放射された光が、物体に当たって拡散(乱反射)されるときの色。 これが、もっぱら「物体の色」として見えている色。 |
GL_AMBIENT |
環境光。 光源からの環境光が物体に当たって拡散されたときの色。 なので、光源と物体の位置関係にかかわらず一定の明るさで、普通は、拡散光よりも暗い。 |
GL_EMISSION |
放射光。 物体が自ら放射している光の色。 なので、上記の反射・拡散・環境光とは、性質が異なる。 自ら光を放射しているので、光源の色の影響を受けない。 |
反射光については、たいていの場合は光源からの光がそのまま反射するので、
マテリアルの反射光、すなわち、GL_SPECULARに設定する値は、
(R,G,B,A) = (1.0, 1.0, 1.0, 1.0)
で良いと思います。
ただし、「A」は、色ではなくて材質の不透明度なので、
ガラスのように透明でよく光を反射するならば、1.0、
透明であまり反射がなければより小さい値、
と、材質によって適切な値に決められるべきです。
拡散光は、もっぱら「物体の色」として見えている色なので、
主にこの拡散光として設定した色で、基本的な材質の色が決まります。
なので、GL_DIFFUSEには、材質の基本的な色を指定します。
環境光は、上記の表の通りなので、
(拡散光の色の各成分)×0.4~0.6ぐらいの値を設定します。
つまり、拡散光の色を(R,G,B,A)としたとき、GL_AMBIENTには、
(R*0.5, G*0.5, B*0.5, A)
を設定すると良いと思います。
Aについては、色ではなくて材質の透明度を表す値なので、
GL_DIFFUSEで指定する値と同じにしておくのが良いです。
放射光については、材質が自ら光を発しているようなものの場合に設定します。
つまり、光源を表示したい場合などです。
そうでない場合は、(R,G,B,A) = (0, 0, 0, 0)にしておけば、放射光は無くなります。
(OpenGLでは、デフォルトでは(0, 0, 0, 0)に設定されています。)
さて、以上でライティングの色に関する設定は一通りだと思います。
ただし、これは一般的に自然な感じに見えるようにしたい場合であって、
また、私がいろいろいじってみて、こうしたら良いだろうと考えたことなので、
あくまでも一例に過ぎません。
思い切って値を変えてみると、
(実用性はともかく、)見た目は結構おもしろい絵になったりするので、
実際に自分でいろいろと試してみるのが良いでしょう。