Japanese memo of Inigo Quilez's "Elevated" demo

概要

  • 2009 年に Inigo Quilez (通称 iq) さんが作った "Elevated" というプログラムサイズが 4k のデモ(下の動画を参照)があります.


  • これの資料を読んでいて, 内容的に面白かったので部分的にメモを書こうと思います.

参照 URL

メモ

レイマーチと 三角メッシュによるラスタライズについて
  • (A) レイマーチの特徴
    • × 興味深いジオメトリを作るのが苦手(プリミティブを改造したものになりがち)
    • ○ レイマーチベースのシェーディング(リフレクションや AO)は簡単. 詳しくは iq さんの web 記事を参照.
  • (B) 三角形メッシュによるジオメトリの特徴
    • ○ 今までとおり, 興味深いジオメトリを作るのが得意
    • × リフレクションや SSAO といったシェーディングは苦手
  • (C) Elevated デモの場合
    • 明らかに CG っぽいものを脱したかった
    • (カメラからの)プライマリレイのヒット判定はラスタライザと Z バッファを使って行う
    • その後, 画面全体へのプロシージャルテクスチャとシェーディングを適用 (ディファード・シェーディング)

Elevated の狙い



  • カメラの動きも本物っぽくする
    • × シンプルな sin, cos カーブ
    • カメラの重みや慣性, 揺れを考慮
ノイズ
  • ShaderToy 版の Elevated では 山用のハイトマップの高さ, 法線を計算するといった箇所にノイズ関数を使っています.
  • もう少し詳しく言うと, 使用しているノイズ関数とその箇所によって以下のように分類できます.
    • 改良型の fBm : 山用のハイトマップの高さ, 法線
    • 通常の fBm : 雪のマテリアル, 空の雲
  • 3D の Perlin Noise は格子点(a,b,c,d,e,f,g,h)のそれぞれに与えられた乱数を, トライリニア補間した結果を返します.
  • このときに使う補間の方法としては主に cubic 補間 か quintic 補間を使います.
    • リニア補間 : u(x) = x
    • cubic 補間 : u(x) = 3 * x^2 - 2 * x^3
    • qunitic 補間 : u(x) = 6 * x^5 - 15 * x^4 + 10 * x^3
  • 通常の fBm は 入力 x,z に対して, Perlin ノイズを重ね合わせた和である n(x,z)を返します.
  • 一方で, 改良型の fBm では入力 x,z に対して, 上の n(x,z) だけでなく, x 方向の微分値 dn(x,z) / dx と z 方向の微分値 dn(x,z) / dz を返します.
  • この微分値(ノイズの勾配)を考慮した場合, 通常の fBm よりも良い結果が得られます.

  • Elevated の ShaderToy 版のソースコードを読むと, ホワイトノイズのテクスチャ(256x256)から改良型 fBm を noised() という関数で計算しています.
    • またこの中で使用している補間関数は cubic 補間( u(x) = 3 * x^2 - 2 * x^3 )です.
マテリアル
  • マテリアルについてはワールドの XYZ 座標, 法線の向き に応じて, 山の色, 山の濃い色, 緑地, 雪の 4 種類に分類しています.


フェイクによるシャドウ
  • 細かい山の高さ(16 オクターブ)から作った法線と, 粗い山の高さ(5オクターブ)から作った滑らかな法線の向きを比較して, シャドウをフェイクで計算しています.