Share via


ProceduralMaterials サンプル

Cc308054.d3d10_sample_ProceduralMaterials(ja-jp,VS.85).jpg

Path

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

サンプルが動作するしくみ

このサンプルでは、単純な繰り返し型の関数をビルディング ブロックとして使用して、プロシージャ マテリアルを作成します。プロシージャ テクスチャーは、解像度に依存せずに 3D のどの位置にも存在する、UV マッピング座標が不要なテクスチャーです。このサンプルは、ノイズのオクターブ、グリッド関数、およびその他の非常に巧妙なコードを組み合わせることにより、テクスチャーを使用しなくても広範な種類のマテリアルを作成できることを示しています。

ノイズ

このサンプルでは、2 種類のノイズを使用して、プロシージャ テクスチャーを作成します。1 つ目は、シンプレックス ノイズです。これは、Perlin ノイズと同様に格子を使用したノイズ関数です。詳細については、[3,5] を参照してください。このノイズは、乱数値の小さな 256×256 のテクスチャーをサンプリングします。

このサンプルで使用するもう一種類のノイズは、Voronoi ノイズです。このノイズは、Worley ノイズまたは Cellular ノイズ [1,2,4] とも呼ばれます。パラメーター次第で、大量の泡を表現したり、切りくずのような外観を作成したりできます。このノイズは、ランダム ベクトルの小さな 1D のテクスチャーをサンプリングします。

その他の関数

ノイズ関数は、通常の合成パターンには適しません。その良い例が、レンガの壁です。ノイズ関数には、このようなサーフェスに欠かせないレンガやモルタルのパターンを生成する適切なものがありません。そのため、サンプルでは、通常の格子、互い違いの格子、規則的に配列された球などをシミュレートするために、他のヘルパー関数を追加しています。これらをノイズ関数と組み合わせると、解像度に依存せずに 3D 空間に存在する、UV マッピングが不要な結果を生成して、さまざまな実世界のマテリアルをシミュレートできます。

サンプルの使用方法

このサンプルでは、各種のプロシージャ エフェクト テクニックが含まれるエフェクト ファイルを読み込みます。デフォルトでは、これらは単純なキューブに適用されます。ジオメトリの別の部分を読み込むには、[Load Mesh] ボタンを使用します。

テクニックのドロップダウン コントロールには、エフェクト ファイルに含まれるすべてのテクニックが表示されます。

[Reload Effect] ボタンをクリックすると、エフェクト ファイルがディスクから再度読み込まれます。このボタンは、エフェクト ファイルに変更を加えたり、変更内容をエフェクトの再コンパイル後すぐにサンプルに表示したりする場合に便利です。

4 つの汎用スライダーがあります。これらは、シェーダー定数としてすべてのテクニックに渡されます。渡されたスライダーは各テクニックで自由に使用できます。たとえば、Y 方向のメッシュのスケーリングを変更する場合、ほとんどのテクニックでスライダー 3 が使用されます。

プロシージャ マテリアルの法線の取得

プロシージャを組み合わせてアルベド テクスチャーやディフューズ テクスチャーを作成することは簡単です。ビルディング ブロックの簡単なブレンディングで、適切な結果を得ることができます。しかし、プロシージャを使用する法線の摂動はそう簡単ではありません。ほとんどのリアルタイム アプリケーションは、法線マップを使用してサーフェス全体のライティングを変更します。この法線マップは事前に摂動されたサーフェスであり、UV 座標を使ってオブジェクトに適合されます。しかし、プロシージャ マテリアルは動的でなければなりません。したがって、事前に摂動された法線サーフェスは適用外となります。さらに、これらのテクニックの多くはさまざまなプロシージャの任意の組み合わせを使用するため、サーフェスの法線の作成には分析に基づく派生は使用できません。

1 つの解決策として、シェーダーを何度か実行し、各サンプル点の高さの差を計算する方法があります。現在ラスター化しているピクセルの 1 つ右のピクセルと 1 つ上のピクセルの高さを計算すると、中心のピクセルに対する接線ベクトルと複接線ベクトルを計算できます。これらの外積を実行すれば、その点の法線を得ることができます。あいにく、この方法は負荷が大きく、シェーダーを何度も実行することになります。しかし、幸いにも、この演算のほとんどはビデオ ハードウェアで実行できます。スクリーン空間でシェーダーが計算したすべての値の変化が ddx 命令と ddy 命令により計算されます。たとえば、ddx は、水平に関する値の変化を計算します。この処理を実行するコードは、次のとおりです。

float3 FindNormal( float3 Value )
{
    float3 dWorldX = ddx(Value);
    float3 dWorldY = ddy(Value);
    float3 bumpNorm = normalize( cross( dWorldX, dWorldY ) );
    return bumpNorm;
}

ddx と ddy は高速である一方、制限もあります。これらの命令は、スクリーン ピクセルの粒度では動作しません。最近のビデオ ハードウェアは、ピクセル クワッドと呼ばれるピクセル グループ全体を通してピクセル シェーダーを実行します。クワッド内のピクセルはすべて一度に計算されます。ddx 命令と ddy 命令は、ピクセル クワッド全体における変数の変化を計算します。したがって、法線は、スクリーン ピクセルよりもかなり低い解像度で計算されます。その結果、ブロッキング アーティファクトが発生する可能性があります。これをテストするには、テクニックのドロップダウン リストの下にある [Use DDX/DDY] ボタンをクリックします。フレームレートが増加する一方で、法線の摂動を使用するテクニックにブロッキング アーティファクトが出現するのがわかります。

このサンプルでデフォルトで使用されている解決策は、シーン内のオブジェクトの高さの摂動をオフスクリーン レンダー ターゲットにレンダリングする方法です。その後、このレンダー ターゲットを別のパスで読み戻します。スクリーン上のピクセルごとに、右側と上に隣接するピクセルをサンプリングします。これらの隣接するピクセルから中心のピクセルに対して接線ベクトルと複接線ベクトルが作成されます。その外積を実行すると、法線が計算されます。この方法は、プロシージャ シェーダーをさまざまなサンプル点で何度も実行する方法の利点と、ddx および ddy 命令を使用する方法の利点を組み合わせたものです。スクリーン上の各ピクセルには、プロシージャ シェーダーが 1 回しか実行されず、法線の計算はクワッド レベルではなくピクセル レベルで行われます。ただし、この方法には、もう 1 つのレンダリング パスが必要になります。

参考文献

[1] Chan、Bryan、Michael McCool 著『Worley Cellular Textures in Sh』ACM SIGGRAPH 2004 Posters、p.18、2004 年 8 月。

[2] Ebert、David S.、F. Kenton Musgrave、Darwyn Peachey、Ken Perlin、Steven Worley 著『Texturing and Modeling:A Procedural Approach』(Academic Press Professional, Inc.、カリフォルニア州サンディエゴ、1994 年)

[3] Gustavson、Stefan 著『Simplex noise demystified』。http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf、2005 年 3 月。

[4] Worley、Steven 著『A cellular texture basis function』(23rd Annual Conference on Computer Graphics and Interactive Techniques 議事録、 p.291 ~ 294、1996 年 8 月)。

[5] Tatarinov、Andrei 著『Perlin Fire』。http://developer.download.nvidia.com/whitepapers/2007/SDK10/PerlinFire.pdf、2007 年 2 月。