チュートリアル ライト、カメラ、マテリアル

ライト、カメラ、マテリアル

By Dave Pagurek, Austin Lee Slominski, Adam Ferriss

3Dでの創作は、単なるジオメトリ以上のものです。カメラ、ライト、マテリアルは、視覚的に興味深い3Dシーンを作成する上で重要な要素です。p5.jsには、ジオメトリの外観を変換するためのさまざまなツールがあります。

カメラとビュー

カメラは3Dシーンの重要な要素です。空間と次元の感覚を与え、コンテンツをフレーミングするのに役立ちます。WebGLモードではデフォルトでパースペクティブカメラが提供されますが、perspective()またはortho()関数を使用してこれを変更できます。

パースペクティブとオーソグラフィックのカメラタイプの違いを示すイラスト。オーソグラフィックビューでは、線が互いに平行に移動しますが、パースペクティブビューでは、線が収束します。

パースペクティブとオーソグラフィックのカメラタイプの違いを示すイラスト。オーソグラフィックビューでは、線が互いに平行に移動しますが、パースペクティブビューでは、線が収束します。

パースペクティブカメラは、オブジェクトが遠ざかるにつれて小さく見えるように歪め、遠くの一点で消失します。これはオーソグラフィックカメラとは対照的で、オーソグラフィックカメラではジオメトリが遠ざかっても同じサイズのままで、消失点がありません。以下の例で両方のオプションを試してみることができます。

視野角、または FOV は、カメラがどれだけ見えるかを角度で表した用語です。単純な例では、ズームのような効果に見えるかもしれませんが、より大きな FOV 角度では形状がより遠近法的に歪むことになります。時には、この効果は芸術的な目的で使用されます。

3Dでカメラを扱う際に理解すべきもう一つの重要な用語は、カメラのフラスタムです。カメラのフラスタムは、カメラの視界の形状です。それは、ジオメトリが表示される錐体のような形状です。フラスタムにはニアプレーンファープレーンの2つの要素が含まれます。ニアプレーンは、ジオメトリがレンダリングされるためにカメラからの最小距離を定義します。ファープレーンは、ジオメトリがカメラから見える最大距離を定義します。これらはそれぞれ変更して、カメラがどれだけ近くまたは遠くまで見えるかに影響を与えることができます。ジオメトリを選択的に含めるこのプロセスは、時に「クリッピング」と呼ばれます。以下のようにperspective()を使用してこれらを設定できます:

perspective(
  fieldOfViewY, // 角度(ラジアン)
  aspectRatio, // 幅 / 高さ
  nearPlaneDistance, // カメラからの最小距離
  farPlaneDistance // カメラからの最大距離
);

紫色のカメラフラスタムを示すイラスト。カメラの近くに黄色の長方形で表されるニアプレーン、フラスタムの反対側の端に緑色の長方形で表されるファープレーンがあります。

紫色のカメラフラスタムを示すイラスト。カメラの近くに黄色の長方形で表されるニアプレーン、フラスタムの反対側の端に緑色の長方形で表されるファープレーンがあります。

camera()に引数を渡してカメラを移動できますが、コードでカメラを常に移動させたり調整したりするのは面倒です。orbitControl()を使用すると、マウスを使用してカメラをズーム、パン、位置決めできます。draw()関数の先頭で、push()pop()の呼び出しの外側で呼び出すことで使用できます:

試してみよう!

立方体を使って、一方から見ると一つのものに見えるが、別の側に軌道を移動すると別のものに見える彫刻を作ってみてください。

照明

光は3Dシーンのもう一つの重要な要素で、形状と奥行きを伝えるのに役立ちます。p5.jsにはスケッチで使用できるいくつかの異なるタイプの光があります:

  • ambientLight(): アンビエントライトは、光の位置や方向を考慮せずに、すべてをわずかに明るく表示します。
  • directionalLight(): ディレクショナルライトは、位置を持たず、単一の角度から照らす光で、シーンの奥行きを伝えるのに特に有用であり、シーンに「太陽」光が必要な場合に便利です。この関数は色と方向の引数を受け取ります。
  • pointLight(): ポイントライトは、電球のように単一の点からあらゆる方向に光を放射します。この関数は色と位置の引数を受け取ります。
  • spotLight(): スポットライトは、単一の点から単一の方向に光を放射します。この光は円錐形に投射され、その半径と集中度を調整できます。
  • imageLight(): 画像を光源として使用することは、シーンをその画像でテクスチャ処理された巨大な球体の中に置き、シーンに光を送り込むようなものです。
  • noLights(): 後続のすべてのジオメトリが照明なしでレンダリングされるようにします。これは、フラットで陰影のないジオメトリが必要な場合に便利です。

これらのライトはdraw()内で使用する必要があります。1つの画像ライトと他の種類のライトをそれぞれ最大5つまで同時に使用でき、多様で複雑な光源でシーンを構成できます。また、push()pop()内に光関数を含めることで、光をコードの一部分だけに限定し、別の形状に別の光のセットを使用することができます。照明は形状ごとに行われるため、シーン内の各オブジェクトは他のオブジェクトに影を落とすことはありません。

以下のインタラクティブな例で、チェックボックスをオンまたはオフにして、照明がどのようにブレンドされるかを確認してみてください。アクティブな各光源には、その位置や方向を視覚的に示す指標がありますが、これらは説明のためのものであることに注意してください!

試してみよう!

各ライトをコメントアウトしたりコメントを外したりして、それぞれのパラメータを実験してみてください。

マテリアルとテクスチャ

オブジェクトは、そのマテリアルプロパティに基づいて異なる外観を持つことができます。マテリアルは、光がジオメトリとどのように相互作用するか、そして色(またはテクスチャ)がオブジェクトにどのように適用されるかを決定します。マテリアルは多様で、オブジェクトを光沢のある、粗い、またはテクスチャのある状態にすることができます。

p5.jsには、オブジェクトの外観を制御する5つのマテリアルプロパティがあります:

  • fill():これは、シーンに光がない場合に使用される色です。光が追加されると、この色は光の拡散成分と混ざります:光が直接当たることによる表面の明るい部分と暗い部分です。
  • ambientMaterial():これは、シーンで設定されたambientLight()と混ざる色です。設定されていない場合、これはfillカラーと同じになります。
  • specularMaterial():これは、光の鏡面成分と混ざる色です:形状の表面に反射されたハイライトです。これが設定されていない場合、形状にはハイライトがありません。
  • shininess():この数値は、鏡面ハイライトがどれだけシャープであるかを表します。値が1の場合、広がったぼやけたハイライトになります。光沢が高くなるほど、ハイライトはよりシャープで小さくなります。これは、鏡面マテリアルが設定されている場合にのみ違いが出ます。
  • emissiveMaterial():これは、形状に追加される色です。形状が自ら生成する光を表すため、シーン内の他の光源に基づいて変化しません。

各ピクセルの色を決定するために、各マテリアルコンポーネントはシーンの光と相互作用してから合計されます。

normalMaterial()と呼ばれる別のマテリアル設定もあります。これが設定されると、他のすべてのマテリアル設定は無視され、形状の色はその表面の角度に基づいて決定されます。表面が水平方向に角度がついている場合、より赤く見えます。垂直方向に角度がついている場合、より緑色に見えます。カメラに向かって角度がついている場合、より青く見えます。これは形状のデバッグに役立つことがよくあります。

以下のインタラクティブな例では、それぞれの異なるマテリアルを選択して、それらがジオメトリの外観にどのように影響するかを確認してみてください。

試してみよう!

この例で異なる光をコメントアウトしたりコメントを外したりして、それらがマテリアルとどのように相互作用するかを確認してください:

WebGLモードでは、形状全体に単一のfill()値を持つ必要はありません:各頂点に異なるfillカラーを適用できます。三角形の頂点が異なるfillカラーを持つ場合、三角形は角の色の間をスムーズにブレンドします。これは、以下の例のように、形状全体にスムーズなグラデーションを作成するのに便利な方法です。キャンバスをクリックして押し続けると、形状のエッジが見えるので、WebGLが中間部分をどのように埋めているかがわかります。

より高度なカスタムマテリアルは、texture()関数を使用することで実現できます。これにより、画像をジオメトリの表面にマッピングすることができます。これらのテクスチャは画像からインポートすることができ、シェーダーを使用してコード内で生成することもできます。ジオメトリにテクスチャをマッピングするには、preload()内でloadImage()を使用し、その後、形状を描画する前にtexture()を呼び出します。

カスタムジオメトリを作成する際、各3D位置の後に各頂点のテクスチャ座標を指定できます。デフォルトでは、これらの座標は適用されたテクスチャに対する相対的なピクセル単位ですが、textureMode(NORMAL)を設定して0-1の範囲を使用することができます。これは画像の寸法の割合を表し、任意の画像で動作するモデルを作成するのに役立ちます。

頂点のテクスチャ座標は、その3D位置が変化しても同じままにすることができます。これを使用して画像を歪ませたりアニメーション化したりすることができます。以下の例では、テクスチャ座標を同じに保ちながら頂点位置を変更して、描画をくねらせています。キャンバスをクリックして押し続けると、描画されている頂点のグリッドのエッジが見えます。

試してみよう!

頂点位置を歪ませることで、キャラクターの画像をジャンプしているように見せたり、手を振っているように見せたり、歩いているように見せたりできますか?

まとめ

カメラ、ライティング、マテリアルを制御することで、スケッチの外観を変更する柔軟性が高まり、3Dスケッチに独自のスタイルを導入する可能性が開かれます。

形状のためのさらに高度なマテリアルを作成するために、アーティストはしばしばシェーダーを書きます。さらに多くの可能性を探求する準備ができたら、シェーダー入門チュートリアルをチェックしてください!

用語集

カメラ

3Dシーンの視点

パースペクティブ

遠くのオブジェクトを小さく見せることで、奥行きの外観を与えるカメラ投影。

正投影

直交で奥行きの影響を受けないカメラ投影。2次元的な外観を与えます。

視野角

カメラが見ることができる範囲を表す角度。

フラスタム

カメラで見ることができる全領域を表す幾何学的形状。

ニアプレーンとファープレーン

ニアプレーンはジオメトリがカメラから表示されるために必要な最小距離を表し、ファープレーンは最大距離を表します。

クリッピング

ジオメトリがカメラのフラスタムの外側に落ちる場合など、一部のジオメトリを選択的に表示し、他を表示しないこと。

拡散光

マットな材質に対する光の効果。マットな材質は全方向に均等に光を反射するため、視点に関係なく同じ色に見えます。

鏡面光

光沢のある材質に対する光の効果で、反射したハイライトとして見えます。反射角が変わるため、オブジェクトの周りを移動するとハイライトの位置が変化します。

光沢度

オブジェクトの鏡面反射がどれだけシャープであるか。この特性は、オブジェクトの表面で反射した光がどれだけ広がるかによって決まります:広がりが少ないほど反射はシャープになり、オブジェクトはより光沢があるように見えます;広がりが大きいほど反射はぼやけ、オブジェクトの光沢は少なくなります。

発光

オブジェクトの表面から放出される光で、外部光源からの光に加算されます。

環境光

あたかもシーンが光を放出する大きな球体の中にあるかのように、全方向から均一に来る光の量。