雲ノード"Functionタブ"のチュートリアル

「雲ノード"Functionタブ"のチュートリアル」の編集履歴(バックアップ)一覧に戻る

雲ノード"Functionタブ"のチュートリアル - (2018/04/01 (日) 02:21:40) のソース

Planetside公式Wiki、&bold(){Guides}の[[Clouds Following Terrain Tutorial(by Martin Huisman)>http://www.planetside.co.uk/wiki/index.php?title=Clouds_Following_Terrain_Tutorial]]からの転用です

**&bold(){目次}
-&link_anchor(概要){概要}
-&link_anchor(1章){1章 雲シェーダノードについてを学ぶ}
--&link_anchor(1章-1){雲の高度と深さの関係}
--&link_anchor(1章-2){“Localise”機能について}
-&link_anchor(2章){2章 "Functions"タブ}
-&link_anchor(3章){3章 高度と深さの調整を組み合わせる}
--&link_anchor(3章-1){地形に沿った雲}
-&link_anchor(4章){4章 "Function"の限界事項}
-&link_anchor(5章){5章 プロシージャル地形からイメージマップを生成}
--&link_anchor(5章-1){「Terraconv」を使って".ter"ファイルを画像変換}
--&link_anchor(5章-2){Terragenにイメージマップをインポートして適合}
-&link_anchor(6章){6章 最終密度モジュレータ}

----
***&aname(概要,option=nolink){概要}
このチュートリアルは雲機能の中でも、雲の高度と外観を調整する2つの機能について記述します。アニメーションと画像で補いながら雲の機能について説明します。最終的にはこれらの機能を使って、あなたが取り組むシーンで活用出来る方法を紹介します。

このチュートリアルは、手順と事例を再現するためにTerragenのプロジェクトファイルと地形画像ファイルを用意しています。あなたがアニメーション機能を備えるTerragenを使用している場合は、キー入力されたパラメータを確認し、例えば開始値と終了値とで比較する事が出来ます。
[[雲ノード"Functionタブ"のチュートリアルのパッケージファイル>http://planetside.co.uk/docs/tg2/cloud_function_tutorial_resources.zip]](3.5MBのZipファイル)

----
***&aname(1章,option=nolink){1章 雲シェーダノードについて学ぶ}
&bold(){&aname(1章-1,option=nolink){雲の高度と深さの関係}}
画像1:シーンに含まれた雲ノードのメイン設定の概観
#image(Cloud_tutorial01.jpg)
雲の深さと高度がどのように連動して働くかを理解する事が重要です。

「Cloud Functions Explained.tgd」ファイルを開き、レンダリングして下さい。以下の画像と同じように見えます:
#image(Cloud_scr01.jpg,width=750,height=306)
(元ファイルを開いた状態から、『Cumulus layer 01』ノードの"Altitude offset function"の入力端子と、"Depth modulator"の入力端子につながっているそれぞれのノードを切断して下さい。)

画像2:レンダーの出力画像
#image(Cloud_tutorial02.jpg,width=350,height=191)
地形は1 x 1188px画像によって生成されています。1ピクセル幅をディスプレースメントによって地形のような横断面を得るために引き延ばしています。ディスプレースメント係数は、地形の最高峰100メートル(グレースケール値が100%の白)を意味する100になっています。(『Displacement shader』の「Displacement multiplier」値を参照)。この画像2のように、基本的な2Dの平面のような地形を用意したので、数値による働きが分かりやすくなります。

では、雲ノードの設定に戻りましょう。雲の高度と深さはどのように関連するか?

画像3:雲の高度と深さ間の関係
#image(Cloud_tutorial03.jpg)
画像1から"Cloud altitude(雲の高度)"が100メートル、"Cloud depth(雲の深さ)"が200メートルである事を覚えていて下さい。高度は雲の中心値を定義します。深さは雲が雲底から両方向で存在する事が出来る垂直範囲を定義します。よって、この場合、200メートルの深さにより最終的な深さは以下の通りになります:

雲の最低高度 = Cloud altitude - (Cloud depth / 2) = 100 - (200 / 2)= 0メートル(Cloud base altitude)
雲の最高高度 = Cloud altitude + (Cloud depth / 2) = 100 + (200 / 2)= 200メートル

この事から、最終的な雲層の範囲は高度100メートルを中心に0メートルから200メートルになります。雲は常にこの定義された範囲で制限される事を覚えておく事が重要です!ただし、『Easy cloud』ノードの場合は、"Cloud altitude"を設定するのではなく、"Cloud base altitude(雲底高度)"を設定する事に注意して下さい。

&bold(){&aname(1章-2,option=nolink){“Localise”機能について}}
通常、ユーザーが雲を地形の特定の部分に限定したい場合、雲のノイズ機能をマスキングするために、『Distance Shader』などの何らかのシェーダによるマスクを使用する必要がありました。これを行う時、ノイズ機能だけが制限されるので、雲層自体は"グローバル(広範囲)"なままです。ローカライズ(局地化)された雲を使用する利点は、ローカライズされた雲を使用する利点は、雲層が"グローバル"から"ローカル"に変更される事で、雲の計算が必要な領域が制限されレンダリングが遙かに高速になります。

雲ノードのローカライズ設定によって雲のサイズは定義されます。
-&bold(){Centre}: 雲の定位置を定義します。XYZ座標を手動で入力するか、3Dプレビュー上でハンドル付きの雲層をドラッグする事が出来ます。ローカライズ機能のY座標は、雲の高度設定に論理的に連動します。
-&bold(){Radius}: 上記"Centre"で設定した中心からのローカライズされた雲の半径(単位:m)
-&bold(){Falloff (0..1)}: ローカライズされた雲層のエッジの柔らかさを定義します。'0..1'は使用できる範囲を示しますが、通常通り1以上の設定も可能です。この値を'X'とした場合、[ 1-X * 半径 ]でエッジが雲の終端に向かって徐々にフェードアウト始める事を意味します。従って、1000mの半径と0.25のフォールオフでは、エッジは[ 1 - 0.25 * 1000 = 750m ]からフェードアウトします。つまり、雲の減少は中心から750mの位置から1000mに適用されます。
-&bold(){Value at radius}: 制限領域の境界で『Density Shader』の値を置き換えます。フォールオフ領域では、『Density Shader』の値は元の値と"Value at radius(半径の値)"のマスクに置き換えられます。マスキングは、境界から制限領域の中心に向かって行われます。

画像4:"Falloff"は、下記の画像ではすべて1に設定しています。
#image(Cloud_tutorial04.jpg,width=800,height=160)
見て分かる通り、1の値を使うと、制限領域の半径まで雲が一杯になります。また、『Density Shader』の負の部分から得るであろう雲の隙間は現在雲で完全に満たされます。これは、『Density Shader』の値が"Value at radius"の値で完全に置き換えられているためです。0の値は雲の覆いには影響せず、雲が際立つほど密度が高くない限り、制限領域の境界は柔らかな先細り効果を提供します。負の値(デフォルトでは0.5)は、境界に向かって雲の覆いを減少させます。

----
***&aname(2章,option=nolink){2章 "Functions"タブ}
#image(Cloud_tutorial05.jpg)
"Altitude offset function(高度オフセット機能)"は、雲固有の垂直縦断面を相殺するために3D空間内で多様化する事の出来る関数やカラーシェーダを取り入れます。関数はFunctionのノードで作成された高度に基づく関数であったり、カラーシェーダとしては『Power fractal shader』や、『Constant colour』ノードを使用します。入力単位はメートルです。"Function multiplier"の入力フィールドに乗算する数値を入力する事が出来ます。

例えば、『Constant colour』ノードを"Altitude offset function"として使用し、"Function multiplier"の値を1に設定すると、雲の高度はわずか1メートルでオフセットされます。レンダリングではこの違いに気付かないでしょう。次に100を設定すると、オフセットは100mになります。

このチュートリアルの第1章で、雲の高度と深さの設定で定義された境界の外側に雲が存在しない事を念頭に、高度のオフセット値の設定に注意して下さい。

"Depth modulator"は、雲固有の垂直縦断面の高さを増減させて3D空間内で変化させる機能またはカラーシェーダを必要とします。基本的には"Altitude offset function"と同様に設定して使用する事が出来ます。
この機能を雲の深さの乗数として考えるのが適切です。例えば、『Constant colour』ノードを「X」の値を持つ雲ノードの"Depth modulator"の入力端子に接続した場合、雲層の深さは次のようになります:
[ X * cloud depth ]
0.1の値を設定した場合、深さは0.1倍になるので10倍薄くなります。このチュートリアルのプロジェクトファイルでは、雲の層は[ 0.1 * 200 = 20m ]の厚さになります。

"Center (0..1)"の設定は、この極薄の雲層が定義された雲の範囲内で、深さを乗算する軸位置を設定してどこに雲を出現させるかを定義します。

チュートリアルのプロジェクトファイルに戻りましょう:
+Terrainグループの『Compute Terrain』の出力端子を『Base colours』ノードから切断して下さい。これで地形情報は無効になります。
+Atmosphereグループの『Constant colour 01』の"Colour"に0.1の値を設定します。
+『Cumulus layer 01』の「Function」タブにある"Centre (0..1)"に0の値を設定します。
+レンダリングを実行し、続いて"Centre (0..1)"の値を0.5の場合と1の場合のレンダリングも行います。『Constant colour 01』の"Colour"の値は変更しません。

#image(Cloud_scr02.jpg,width=750,height=306)
(元ファイルを開いた状態から、『Cumulus layer 01』ノードの"Altitude offset function"の入力端子につながっている『Image map shader 01』ノードを切断して下さい。)
3つのレンダリング結果は以下のようになります:
画像5:Depth modulatorが0.1の場合のCenter (0..1)の値を変化させた結果
#image(Cloud_tutorial06.jpg,width=800,height=200)
雲層の深さを "画像2"または "画像3"と比較すると、深さが10倍になっている事がわかります。雲の境界内で深さがどこに位置するかを中心値でコントロールする事が出来ます。底=0、中間=0.5、頂点=1。
もう一度、これらの境界線が「Main」タブで雲の高度と深さによって定義されている事を思い出して下さい。

下記youtube動画をご覧下さい。雲が次第に細く低く変化するのが分かります。
&youtube(https://www.youtube.com/watch?feature=player_profilepage&v=vZI31bHrVjQ){350,196}

----
***&aname(3章,option=nolink){3章 高度と深さの調整を組み合わせる}
&bold(){&aname(3章-1,option=nolink){地形に沿った雲}}
さて、これまでの退屈な前置きを読み終えて、最終的に最も制作における関連性の高いこの3章で学んで行きましょう。これらを使って素晴らしいシーンを作るにはどうすればいいでしょう?

プロジェクトファイル"Cloud Functions Explained.tgd"に戻り、Terrainグループの『Compute Terrain』の出力端子を『Base colours』ノードの入力端子に接続して下さい。これで再度地形情報が有効になります。地形の高度が100mである事を覚えておいて下さい。

次に、『Image map shader』ノードを『Cumulus layer』ノードの"Altitude offset function"の入力端子に接続し、『Constant colour 01』の"Colour"が0.1に設定されている事を確認します。

イメージマップファイルの"1px_4px_blur_b.sgi"は、0から1の範囲のグレースケール値を使用して地形の形状を定義しています。
"Altitude offset function"の入力単位はメートルなので、このイメージマップの入力は値を増加させない限り目立った効果はありません。

『Displacement shader』ノードで"Displacement multiplier"が100に設定されているので地形の最高峰は100mです。従って、高度オフセットの"Function multiplier"も100に設定し、レンダリングします。"Function multiplier"を、150と200の値についてもレンダリングを繰り返します。
以下の結果が得られるはずです:
画像6:『Constant colour』の"Depth modulator"はすべて0.1に設定。
#image(Cloud_tutorial07.jpg,width=800,height=200)
左端の画像サンプルで分かるように、変位値と同じ乗数を使用しているため、厚み20m(0.1 * 200)の雲層は地形に正確に沿っています。これは、変位と高度オフセットの情報源がイメージマップから生じるため正確に一致します。

右端の画像サンプルでは、雲層が境界にほとんど到達している事が分かります。見たところ地形の最高峰は正確に100mではないため、オフセットもプラス100mではありません。

雲の高度のオフセットが100から150に増加する下記の動画を参照して下さい。その間、"Depth modulation"も最初は0.1から最終0.5に増加しています。
&youtube(https://www.youtube.com/watch?feature=player_profilepage&v=d-X8jImO6Wo){350,196}
見て分かるように、雲は地形を舞い初めてどんどん厚く(雲の深さが大きく)なります!

----
***&aname(4章,option=nolink){4章 "Function"の限界事項}
このチュートリアルでは、地形を生成するためにイメージマップを使用し、雲の高度オフセットを入力しました。その理由は、地形の高度をノードネットワークから直接計算し、その結果を高度オフセットの値として使用するにはあまりに処理に時間が掛かるためです。そのため、このチュートリアルを高速で明確な数値によって理解が得られるようイメージマップを使用する方法をとりました。イメージマップの欠点は、効果を適用出来るエリアが一部に限られている事です。もちろん大規模なエリアマップを使用する事も出来ますが、多くの事と同様に限界があります。

イメージマップに非常に急勾配な容貌を備えていると、明度の違いが多すぎるため、雲が急勾配な容貌に沿っているように見えません。動画ではっきりと表れているように、まるで雲が地形から湧き出てくるように見えます。

これの解決策は、イメージマップをぼかしてトランジション(形や状態などの推移)を少なくする事ですが、大きなコントラストをぼかしても限界があります。一般的には、雲がより滑らかに地形に沿うには、イメージマップをぼかす必要があります。

下記の短編動画では、限界がかなり明確に示されています。中央左寄りの背景では雲は地形をかなり適切に沿えていますが、右側では岩石から出現しているように見えます。実際には雲は岩石から出現しておらず、高度のオフセットによって急激に下方移動しています! しかしながら、動画ではその様には見えません。
&youtube(https://www.youtube.com/watch?v=pMBQnOaxP-w&feature=player_profilepage){350,196}

----
***&aname(5章,option=nolink){5章 プロシージャル地形からイメージマップを生成}
『[[World Machine>http://www.world-machine.com/]]』や『[[World Creator2(旧 Geocontrol>https://www.world-creator.com/]]』などで生成された地形を持っている場合、地形を画像として簡単にエクスポートしてTGですぐに使用する事が出来ます。しかし、適切な高度オフセットの乗数の値を見いだすにはいくつかの研究が必要な場合があります。これを克服するために、『Displacement shader』の入力として『Image map shader』を使用して地形の変位を生成する事が出来ます。ディスプレースメント値と同じ高度オフセットを使用した場合、それは正確に完全一致しています。このチュートリアルでは、すでにプロジェクトファイルのサンプルを用意しています。

#image(Cloud_tutorial12.jpg,width=600,Height=345)
もし[[The Foundry社のNuke>https://www.foundry.com/products/nuke]]をお持ちなら、下記で紹介するTerraConvを使って.terを32bitのtiffファイルでエクスポートし、それをNukeにインポートします。そして「CurveTool」の"Max luma pixel"で測定する事で最大輝度、すなわち地形の最高峰を知る事が出来ます。

あなたがこれらの地形生成アプリケーションを持っていない場合は?

「Image map tutorial.tgd」を開き、ノードネットワーク中の"Terrain"グループを見て下さい。『Fractal terrain』ノードと『Heightfield generate』がある事に気付くでしょう。

『Heightfield generate』の「Use shader」タブに移動します。
画像7:プロシージャル地形のハイトフィールドを生成する事の出来る「Use shader」タブ。
#image(Cloud_tutorial08.jpg)
見て分かるように、『Heightfield generate』はハイトフィールドを生成するために『Compute terrain 』ノードの計算を使用します。

非常に重要なのは、使用する配置タイプと座標です。後でイメージマップを作成したら、同じ座標と配置タイプを使用する必要があります。
[Generate Now]ボタンをクリックして地形を生成し終えたら、ノードネットワーク上の『Heightfield generate 01』のアイコンを右クリックでポップアップメニューから"Save file as..."を選択して、"任意のファイル名 + .ter"ファイルを保存します。

画像8:『Heightfield generate 01』のアイコンを右クリックし、"Save file as..."を選択してエクスポートします。
#image(Cloud_tutorial09.jpg)

&bold(){&aname(5章-1,option=nolink){「Terraconv」を使って".ter"ファイルを画像変換}}
TerraConvをここからダウンロードして下さい:[[TerraConv>http://koti.mbnet.fi/pkl/tg/TerraConv.htm]]

#image(Cloud_tutorial10.jpg)
+TerraConvを起動し、「Load Terrain」ボタンからエクスポートした地形を開きます。
+読込後、「Export」ボタンをクリックする事で、"Export Option"ウインドウが開きます。
+"16 bit Binary"を選択して".tiff"ファイルとして出力します。(このチュートリアルが作られた当時はTerragenは16bitファイルに未対応でしたが、現在はこのままの出力ファイルで読み込む事が出来ます。)
Photoshoで".sgi"ファイルに対応する場合は、ここから手に入れて下さい:[[SGI plugin for Photoshop>http://www.telegraphics.com.au/sw/product/SGIFormat#sgiformat]]

Photoshopで".tiff"ファイルを開き、フィルタ機能でぼかしを適用します。
#image(Cloud_tutorial11.jpg,width=400,height=353)
通常、ここでは"ぼかし(ガウス)"を使い、4~8ピクセルの範囲で調整します。フィルタを適用後、上書き保存します。Photoshopがない場合、無料の[[Gimp>https://www.gimp.org/]]などを使って行います。

&bold(){&aname(5章-2,option=nolink){Terragenにイメージマップをインポートして適合}}
『Image map shader』を作成し、上記で保存した画像ファイルを読み込みます。『Heightfield generate』と同じ座標、同じサイズを入力して下さい。このサンプルファイルでは以下の設定となります:
Coordinates: 0、0、0、Position lower left、Size: 10000 × 10000m
『Cloud layer v2 01(Cumulus layer 01)』を作成し、画像の高度範囲全体をカバー出来るだけの雲の高度と深さを一致させて下さい。3Dプレビューのレンダリングが完了したら、マウスを地形の最高峰に移動して3Dプレビューの下部にある高度(Y:)を読み取って下さい。およそ1900メートルぐらいだと読み取る事が出来ます。

画像9:3Dプレビュー上でマウスを使って最高峰にカーソルを合わせると、3Dプレビューの下部にある高度を読み取る事が出来ます。
#image(Cloud_tutorial14.jpg)

この結果から、雲の高度を約1000m、深さを2000mに設定します。しかし、この設定では雲の境界が地形の最高峰が届いてしまい、その箇所の雲が切り離されるため、余裕を取って高度を1400、深さを2800値に少し上げて下さい。

『Image map shader』の出力端子を『Cumulus layer』の"Altitude offset function"の入力端子に接続して下さい。
#image(Cloud_tutorial15.jpg)

現在少し扱いにくい部分に遭遇しています。3Dプレビューの右上を確認して下さい。右の高度オフセットがカバー出来ていない事に気付きます。これには少々試行錯誤が必要ですが、少なくとも少しは簡単にする方法があります。まず、密度シェーダとして接続している『Density fractal』を新しく作成した『Constant colour』の関数ノードに取り替え、"Colour"の値を1に設定します。これによって雲はどこにでも存在ます。この方法を使って雲の密度を少し上げる事で、雲が確認しやすくなります。
#image(Cloud_tutorial16.jpg)

この画像から今やるべき事は、より薄い雲層が必要な事です。では、『Constant colour』を作成し、Colour"の値を0.15に設定します。それを"Depth modulation"の入力端子に接続します。
#image(Cloud_tutorial17.jpg)


地形の最高峰が約1900mである事が分かっているので、高度は約2000mで始めるのは理にかなっています。そのオフセットは十分に大きくない事に気付くでしょう。納得のいく結果が得られるまで100mずつ増やして下さい。高度の設定に納得が出来たら、密度シェーダの機能を代用していた『Constant colour』から、切断した『Density fractal』に置き換えます。

雲層の厚さを変更したい場合は、高度オフセットを再調整する必要があるかもしれないことに留意して下さい。

画像10: プロシージャル地形に沿って局地的に雲を作成したレンダリング結果。
#image(Cloud_tutorial18.jpg)

----
***&aname(6章,option=nolink){6章 最終的密度モジュレータ}
"Final density modulator"は、3D空間内で多様化する雲の最終密度を増減する事が出来る関数やカラーシェーダをまたはカラーシェーダを取り入れます。これは、他のビルドインのクリッピングやカットオフが適用された後に計算されます(他の雲の関数など)。

この機能は、例えば高度または距離に応じて雲の密度を変化させる事を可能にします。また、この機能に『Power/Cloud fractal shader』を関連付ける事で、密度のバリエーションを追加する事も出来ます。クランプを外された関数/フラクタルの場合、最終密度は、雲ノードの「Main」タブで実際に設定された密度よりも高く調整する事が出来る事を心に留めておいて下さい。

以下にサンプルを上げます。これらのプロジェクトファイルも含まれています。