Raymarching	
  Tutorial	
Tokyo	
  Demo	
  Fest	
  2012	
  
	
  
@gyabo
■自己紹介	
■HN	
  
 @gyabo	
  
■DEMOとの遭遇	
  
 某掲示板の356byte以下でテトリス作れ!からリンク飛んで	
  
 どこかの板でexe踏んで奇麗な映像とBGMが…	
  
	
  
■本業	
  
 組み込み屋さん(MemoryDevice(SDとか)周り)	
  
	
  
	
  
■目次	
・有名な4k	
  introの紹介	
  
・Raymarchingとは	
  
・大まかな手順	
  
・distance	
  funcOon	
  
・実装	
  
・テクニック	
  
・参考文献	
  
	
  
※	
  
前知識としてHLSL(GLSL)少し知っていると良いかもです。	
  
	
  
有名な4k	
  introその1	
receptor	
  	
  by	
  TBC	
  	
  (NVScene	
  2008)	
  
有名な4k	
  introその2	
cdak	
  	
  by	
  Quite	
  &	
  orenge	
  	
  (Chaos	
  ConstrucOon	
  2010)	
  
Raymarchingとは	
  
なんでしょ?
■Volume	
  Renderingをする際の一手法	
[Raymarching]	
  
視点座標をレイの方向に少しずつ進めて、	
  
描画する形(shape)を見つける	
  
→形が分かるまでひたすら再計算を行う	
  
(再計算の回数上限はあります)	
  
	
  
[Raytracing]	
  
レイの方程式を解いて描画する形を	
  
見つける	
  
→方程式が解ければ一発で形が分かる	
  
解けないと形が分からない	
  
(事前に解き方が分かっている必要がある)	
  
■手順(1/7)	
1)  画面に描画する形状を決める関数を作る(関数fとします)	
  
※distance	
  funcOonと言って3次元での形状の表面までの距離を返します(後述)	
  
■手順(2/7)	
2)	
  視点座標Pを決めて、向いている方向のレイを作る	
  
■手順(3/7)	
3)	
  視点位置Pを関数fで計算する(距離dを得る)	
  
■手順(4/7)	
4)	
  距離dだけ視点位置Pを進める	
  
■手順(5/7)	
手順3),	
  4)をひたすら繰り返すと1)で定義した形状の表面に近い位置まで	
  
視点位置を移動できる(レイが衝突している位置が「大体」分かる)	
  
	
  
■手順(6/7)	
手順3),	
  4)をひたすら繰り返すと1)で定義した形状の表面に近い位置まで	
  
視点位置を移動できる(レイが衝突している位置が「大体」分かる)	
  
	
  
■手順(7/7)	
	
  
	
  
	
  
	
  
	
  
	
  
	
  
	
  
	
  
	
  
この座標を使って、Color,	
  法線情報などを計算して	
  
1Pixel描画して終わり。	
  
手順をひたすら繰り返してスクリーン全体を	
  
描画する。	
  
	
  
	
  
■手順(まとめ)	
1)  画面に描画する形状を決める関数を作る	
  
※distance	
  funcOonと言って3次元での形状の表面までの距離を返します(後述)	
  
2)  視点座標Pを決める	
  
3)  1)で決めた視点位置Pを関数で計算する(dを得る)	
  
4)  3)得た距離分視点位置を進める	
  
5)  3),	
  4)を十分に繰り返すと1)で定義した形状の表面に近い位置まで移動できる
(☆レイが衝突している位置が分かる)	
  
この座標を使って、Color,	
  法線情報などを計算して	
  
1Pixel描画して終わり	
  
	
  
	
  
※ひたすら繰り返してスクリーン全体を描画する	
  
■distance	
  funcOon	
•  描画形状を決める	
  
関数の事	
  
•  ものすごくざっくり言うと、	
  
形状の表面までの距離を	
  
関数で表現する。	
  
■distance	
  funcOon(球 :	
  sphere)	
	
  
x
2
+y
2
+z
2
–	
  r
2
	
  
=	
  0	
  
↓HLSLで表記すると…	
  
length(p)	
  –	
  r	
  
	
  
pは視点位置、rは半径です	
  
■distance	
  funcOon(平面 :	
  plane)	
HLSLで表記すると…	
  
dot(p,	
  normalize(N))	
  
	
  
pは視点位置、Nは平面の法線です	
  
	
  
N
■distance	
  funcOon(箱 :	
  box)	
HLSLで表記すると…	
  
length(max(p	
  -­‐	
  l,	
  0))	
  
	
  
pは視点位置、lは直径/2です。	
  
	
  
▲	
  
上の式で描画すると	
  
箱の表面がごま塩になります。	
  
※形状の境界判定がシビア…	
  
	
  
以下のようにちょっとだけバイアス	
  
引いて衝突している箇所を浮かせて	
  
やります。	
  
	
  
length(max(p	
  –	
  l,	
  0))	
  –	
  bias;	
  
※参考文献より	
  
実装	
  HLSL(もしくはGLSL)を使います
■板ポリが命	
   板ポリを描画してShaderとつなげる!	
  
あとはPixelShaderを適用できればやりたい放題(のはず…)	
  
■Cソース側は…	
これだけ!!エラーチェック抜いたりすればもっと小さくなる…	
  
■描画例(floorとbox)	
  1/4
■描画例(floorとbox)	
  2/4	
Source(HLSL)	
  
■描画例(floorとbox)	
  3/4	
Source(HLSL)	
  
■描画例(floorとbox)	
  4/4	
30Line	
  程度。コンパクト!	
  
※もっと小さくできるはず…	
Source(HLSL)	
  
実演
参考1	
hgp://www.iquilezles.org/www/material/nvscene2008/nvscene2008.htm	
Rendering	
  Worlds	
  With	
  Two	
  Triangles	
hgp://www.pouet.net/topic.php?which=7920&page=1&x=15&y=12	
Raymarching	
  Beginners'	
  Thread	
hgp://www.pouet.net/topic.php?which=8177&page=1&x=17&y=16	
Raymarching	
  Tutorial	
  	
  
hgp://www.iquilezles.org/www/arOcles/dismuncOons/dismuncOons.htm	
  
modeling	
  with	
  distance	
  func9ons
参考2	
  :	
  便利なツール	
hgp://tokyo-­‐demo-­‐fest.jpn.org/2012/?page=event#livecoding	
LiveCoder	
  (by	
  h0le氏)	
hgp://glsl.heroku.com/	
  
	
  
GLSL	
  SandBox
QuesOon?	
ご清聴ありがとうございました

TokyoDemoFest2012 Raymarching Tutorial