次の方法で共有


HDRCubeMap サンプル

このサンプルは、浮動小数点テクスチャーと高ダイナミック レンジ ライティングを持つ、キューブ環境マッピングの実例を示しています。Direct3D 9 では、浮動小数点形式がテクスチャーで利用できるようになりました。これらの形式は、1.0 以上のカラー値を格納できます。これは、マテリアルがライトを吸収する場合に、環境マップされたメッシュにライティング エフェクトでよりリアリティを与えることができます。

すべてのカードが、環境マッピングおよび高ダイナミック レンジ ライティング テクニックのすべての機能をサポートしている訳ではありません。

Bb173482.Sample_HDRCubeMap_small(ja-jp,VS.85).jpg

Path

ソース : (SDK ルート)\Samples\C++\Direct3D\HDRCubeMap
実行可能ファイル : (SDK ルート)\Samples\C++\Direct3D\Bin\x86 or x64\HDRCubeMap.exe

サンプルの概要

このサンプルでは、キューブ環境マッピングと高ダイナミック レンジ ライティングの 2 つのレンダリング テクニックについて示します。キューブ環境マッピングは、3D オブジェクトの周囲を囲む環境がキューブ テクスチャー マップにレンダリングされるテクニックです。オブジェクトはキューブ マップを使用するため、メモリー負荷の高いライティング計算を行うことなく、複雑なライティング エフェクトを実現できます。高ダイナミック レンジ (HDR) ライティングは、浮動小数点テクスチャーと極度に強い光を使用することによって、非常にリアリティのあるライティング エフェクトをレンダリングするテクニックです。Direct3D 9 には、浮動小数点テクスチャー形式が導入されています。これまでの整数形式テクスチャーとは異なり、浮動小数点テクスチャーはさまざまな範囲のカラー値を格納できます。浮動小数点テクスチャーのカラー値は、実際の多くのライトと同じく [0, 1] にクランプされないため、これらのテクスチャーはよりリアティティを持たせるために使用されます。

HDRCubeMap がレンダリングするシーンは、環境マップされたメッシュであり、メッシュの周辺の環境を構成する複数のその他のオブジェクトを伴っています。このメッシュには、0 から 1 に調節可能な反射力設定があります。ここでは、0 はメッシュがライトを完全に吸収することを示し、1 はライトも反射もすべて吸収しないことを示します。シーンで使用されているライトは、4 つのポイント ライトで構成されています。そのインテンシティはユーザーが調節できます。

実装

サンプルがレンダリングするシーンは、次のオブジェクトで構成されています。

  • 部屋のメッシュ。これには、壁、床、天井が含まれます。
  • 光源を表す 4 つの小さな球のメッシュ。
  • 環境マップを持つ部屋の中央にあるメッシュがこれに適用されます。
  • 2 つの複葉機のメッシュ。これらは環境マップされたメッシュの周囲を軌道を描いて回り、その軌道が環境マップに反映されます。これらは、環境マップに動きを与える視覚的なキューとなり、周辺環境が変化するに連れて変更します。

サンプルがこれを読み込む場合、2 つのキューブ テクスチャーが作られます。1 つは A8R8G8B8 形式で、もう 1 つは A16B16G16R16F 形式です。レンダリング時に、サンプルはこれらのいずれかを使用して、ユーザーの選択をベースに環境マップを作成します。これが実行されると、高ダイナミック レンジ ライティングで使用した時に、整数テクスチャーと浮動小数点テクスチャーの間に視覚的な違いが見られるようになります。キューブ テクスチャー フェイスと同じサイズのステンシル サーフェスも同時に作成されます。このステンシル サーフェスは、サンプルがキューブ テクスチャーでシーンをレンダリングするときに、ステンシル バッファーとして使用されます。また、サンプルは、シーンをレンダリングするのに必要とされるすべてのシェーダーとテクニックを含むエフェクト オブジェクトを作成します。サンプルで使用されているカメラは、CModelViewerCamera です。このカメラは常に、環境マップされたメッシュである原点に向けられています。ユーザーはカメラ位置をメッシュに沿って移動させ、マウス コントロールでメッシュを回転させることができます。カメラ オブジェクトは、レンダリングするビューと射影行列、環境マップされたメッシュのワールド行列を計算します。

レンダリング コード

サンプルのレンダリングは、頂点シェーダーおよびピクセル シェーダーを使用する RenderSceneIntoCubeMap、Render、および RenderScene の 3 つの関数で発生します。

RenderScene は、現在のレンダー ターゲットでシーンを実際にレンダリングする関数です。これは、キューブ テクスチャーおよびデバイス バックバッファーでシーンをレンダリングする場合に呼び出されます。これには、ビュー行列、射影行列、環境マップされたメッシュをレンダリングするかどうかを示すフラグの 3 つのパラメーターがあります。環境マップを作成するときに環境マップされたメッシュは描画されないため、このフラグが必要とされます。残りの関数は難しいものではありません。まず、最新のトランスフォーム行列、およびビュー空間のライト ポジションでエフェクト オブジェクトを更新します。次に、それぞれに適切なテクニックを使用して、シーンにあるすべてのメッシュ オブジェクトをレンダリングします。

RenderSceneIntoCubeMap の仕事は、キューブ テクスチャーにあるすべてのシーンをレンダリングすることです (環境マップされたメッシュを除く)。まず、これは現在のレンダー ターゲットとステンシル バッファーを保存し、次にデバイスのステンシル バッファーとしてキューブ テクスチャーにステンシル サーフェスを設定します。次に、関数はキューブ テクスチャーの 6 つのフェイスに対してこれを繰り返します。各フェイスで、これはレンダー ターゲットとして適切なフェイス サーフェスを設定します。次に、これはキューブ フェイスの方法に向けられた原点にあるカメラを持つ、特定のフェイスで使用されるビュー行列を計算します。次に、これは FALSE に設定された bRenderEnvMappedMesh を持つ RenderScene を呼び出します。計算されたビュー行列と特別な射影行列が渡されます。レンダー ターゲットが四角形であるため、この射影行列には 90° の視野とアスペクト比 1 があります。6 つのフェイスすべてに対してこの処理が行われたら、関数は古いレンダー ターゲットとステンシル バッファーを復元します。これで、環境マップがフレームに対して作成されました。

Render は、DXUT によってフレームごとに 1 回呼び出される上位レベルのレンダリング関数です。これは、まずカメラ オブジェクトの FrameMove を呼び出します。これによって、カメラによって管理されている行列が更新できるようになります。次に、RenderSceneIntoCubeMap を呼び出してキューブ テクスチャーを作成し、そのフレームに環境を反映させます。その後、これはカメラからのビューおよび射影行列を持つ RenderScene、および TRUE に設定された bRenderEnvMappedMesh を呼び出すことでシーンをレンダリングします。

シェーダー

このサンプルにあるすべてのレンダリングは、プログラム可能なシェーダーによって実行されます。 これは、RenderLight、RenderHDREnvMap、および RenderScene の 3 つのエフェクト テクニックに分類されます。

RenderLight テクニックは、光源を表す球をレンダリングするのに使用されます。頂点シェーダーは一般的なワールドビュー射影 トランスフォームを実行するのに使用され、続いて出力ディフューズにインテンシティ値を割り当てます。ピクセル シェーダーは、パイプラインにディフューズを伝達します。

RenderHDREnvMap テクニックは、シーンにある環境マップされたメッシュをレンダリングするのに使用されます。オブジェクト空間からスクリーン空間への位置の変更は別として、頂点シェーダーはビュー空間での視点反射ベクトル (頂点までの視点反射ベクトル) を計算します。このベクトルは、キューブ テクスチャー座標としてピクセル シェーダーに渡されます。ピクセル シェーダーはキューブ テクスチャーのサンプルを抽出し、サンプリングされた値をそれぞれ適用し、 パイプラインに結果を返します。

RenderScene テクニックは、その他のすべてをレンダリングするのに使用されます。このテクニックでレンダリングされるオブジェクトは、ピクセルごとのディフューズ ライティングを使用します。 頂点シェーダーは、オブジェクトからスクリーン空間へと位置を変更します。次に、これはビュー空間での頂点位置と法線を計算し、これらをテクスチャー座標としてピクセル シェーダーに渡します。ピクセル シェーダーはこの情報を使用して、ピクセルごとのライティングを実行します。for-loop は、4 つの光源による光の量を計算するのに使用されます。ピクセルのディフューズ項は、法線の内積とピクセルからライトへの単位ベクトルを取得することで計算されます。減衰項は、ピクセルとライト間の距離を 2 乗して計算されます。これらの 2 つの項は、光源の 1 つからピクセルが受け取る光の量を示すように調節されます。シーンにあるすべてのライトに対してこの処理が行われたら、値が合計され、ライト インテンシティと 出力を形成するテクセルに合わせて調節されます。

高ダイナミック レンジのリアリティ

Direct3D 9 以前は、Direct3D によってサポートされているのは整数テクスチャー形式だけでした。この種類のテクスチャーが使用されていて、カラー値が 1.0 以上の場合、書き込まれる前に 1.0 にクランプされるので、値は 8 ビットの整数に一致するようになります。これは、キューブ テクスチャーが書き込まれるときに、そのテクセル カラー値が最大 1.0 になることを意味します。このテクスチャーは、後で、100 % 反射しない (30 % しか反射しない) マテリアルでの環境マッピングに使用されます。オリジナルのライト インテンシティがどのくらいであったかに関係なく、テクスチャーにある最高に明るいテクセルでも最終的にメッシュでは 0.3 の明るさになります。そのため、リアリティは譲歩せざるを得ません。これは、以下の図に示されています。

Bb173482.HDRCubeMap_WithoutHDR(ja-jp,VS.85).jpg

Direct3D 9 の新しい浮動小数点キューブ テクスチャーがインテンシティが 1 以上のライトで使用される場合、テクスチャーは 1.0 以上のカラー値を格納することができます。そのため、それぞれの計算が行われた後でも、実際の明るさが維持されます。これは、以下の図に示されています。

Bb173482.HDRCubeMap_WithHDR(ja-jp,VS.85).jpg

その他の方法

浮動小数点キューブ テクスチャーを使用しないで、高ダイナミック レンジ ライティング環境でハイレベルなリアリティを実現することもできます。キューブ環境マップを作成するときに、マテリアルを乗算して適用することによってこれが実現されます。次に、レンダリング中に、ピクセル シェーダーがキューブ テクスチャーをサンプリングし、値をパイプラインに戻して出力します。この方法は、クランピング後ではなくクランピング前にスケーリングすることによって、カラー クランピングの前後で実行されます。この方法の欠点は、シーンがそれぞれ異なる場合に複数の環境マップされたオブジェクトを持ち、これらのオブジェクトをレンダリングするのに異なる環境マップが必要となることです。