シェーダだけで世界を創る!three.jsによるレイマーチング
TRANSCRIPT
![Page 1: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/1.jpg)
シェーダだけで世界を創る!three.jsによるレイマーチング
2016/02/14
GPU の熱でチョコも溶けちゃう!?
GLSL シェーダテクニック勉強会
@gam0022
![Page 2: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/2.jpg)
自己紹介
細田 翔
去年まで筑波大学のCGの研究室
KLab 新卒 1年目
three.js 歴 3年目
2
@gam0022(がむ)
![Page 5: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/5.jpg)
自己紹介
細田 翔
去年まで筑波大学のCGの研究室
KLab 新卒 1年目
three.js 歴 3年目
5
@gam0022(がむ)レイマーチングのおかげで、three.js に PRがマージされた
http://threejs.org/examples/#webgl_raymarching_reflect
![Page 6: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/6.jpg)
レイマーチング?
レイマーチング
||
レイトレーシングの1種
6
![Page 7: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/7.jpg)
レイマーチングは超すごい
レイマーチングによって、コードから生成された映像
メガデモの神 iq(@iquilezles) 氏の作品
https://www.shadertoy.com/view/MdX3Rr
7
![Page 8: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/8.jpg)
レイマーチングは超すごいレイマーチングによって、コードから生成された映像
otaviogood 氏の作品 https://www.shadertoy.com/view/XljGDz
Kali 氏の作品 https://www.shadertoy.com/view/Xtf3Rn
8
![Page 9: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/9.jpg)
レイマーチングは超すごいShadertoy で raymarching タグを検索https://www.shadertoy.com/results?query=tag%3Draymarching
9
![Page 10: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/10.jpg)
レイマーチングはやばい
マインクラフトの作者もレイマーチングに注目!
http://japanese.engadget.com/2016/01/28/notch-oculus-vr-3-5kb/
10
![Page 11: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/11.jpg)
レイマーチングは面白い
超すごい映像をコードだけで動的生成できる!
マインクラフトの作者もレイマーチングに注目!
11
レイマーチングすごく面白そう!!
![Page 12: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/12.jpg)
話の流れ
1. レイマーチングのための基礎知識
2. レイマーチングのアルゴリズム解説
3. レイマーチング発展編
4. three.js の話
12
![Page 13: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/13.jpg)
話の流れ
1. レイマーチングのための基礎知識
2. レイマーチングのアルゴリズム解説
3. レイマーチング発展編
4. three.js の話
13
![Page 14: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/14.jpg)
3Dの描画方法
3Dの描画方法は大きく2種類
1. ラスタライズ法
2. レイトレーシング法
14
![Page 15: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/15.jpg)
ラスタライズ法形状を三角形(ポリゴン)の集合で表現
3Dの頂点を2Dに投影して描画
処理が軽い15
![Page 16: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/16.jpg)
ラスタライズ法形状を三角形(ポリゴン)の集合で表現
3Dの頂点を2Dに投影して描画
処理が軽い16
![Page 17: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/17.jpg)
レイトレーシング法
カメラに届く光線(レイ)を全ピクセル数シュミレーション
17
【画像出典】 http://www.vcl.jp/~kanazawa/raytracing/?page_id=1154
![Page 18: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/18.jpg)
レイトレーシング法全ピクセル数シミュレート
- 1024x768 = 786432(78万)回
処理は重い
無限に滑らか・物理現象の再現が可能
18
【画像出典】 https://sites.google.com/site/
rendering1h/
![Page 19: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/19.jpg)
レイトレーシング法全ピクセル数シミュレート
- 1024x768 = 786432(78万)回
処理は重い
無限に滑らか・物理現象の再現が可能
19
【画像出典】 https://sites.google.com/site/
rendering1h/
詳しくは レイトレーシングの専門家 hole 氏に聞いてください
edupt(パストレーシングベースの
物理ベースレンダラ)の作者
![Page 20: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/20.jpg)
2種類のシェーダ
WebGLのシェーダは2種類
1.頂点シェーダ(vertex shader)
2.フラグメントシェーダ(fragment shader)
20
![Page 21: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/21.jpg)
頂点シェーダ頂点の集合をカメラの世界を基準に座標変換
頂点ごとの処理
21
座標変換
![Page 22: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/22.jpg)
フラグメントシェーダ
ポリゴンの塗り方を決める役割
- どう陰影をつけるか?
- テクスチャを貼るか?
ピクセルごとの処理
別名: ピクセルシェーダ
22
![Page 23: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/23.jpg)
レイトレのフラグメントシェーダ実装
3Dシーンの中に1枚の板を配置
1枚の板の塗り方を決める処理として、レイトレーシングをフラグメントシェーダをつかって実装
23
![Page 24: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/24.jpg)
レイトレのフラグメントシェーダ実装
フラグメントシェーダはGPUで並列処理される
とても高速に処理できる
リアルタイム描画が可能
24
![Page 25: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/25.jpg)
レイトレのフラグメントシェーダ実装
GPUで並列処理? 難しそう…
レイトレーシングは並列性が高い手法
並列の実装は簡単
25
![Page 26: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/26.jpg)
話の流れ
1. レイマーチングのための基礎知識
2. レイマーチングのアルゴリズム解説
3. レイマーチング発展編
4. three.js の話
26
![Page 27: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/27.jpg)
ここから レイマーチングの話
![Page 28: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/28.jpg)
レイマーチングレイマーチング ∈ レイトレーシング
レイマーチングの大きな特徴は、衝突判定
- レイトレーシング
• 形状(球体・平面・ポリゴンなど)によって、衝突判定のアルゴリズムを使い分け
- レイマーチング
• 距離関数でシーンを定義し、レイを少しずつ進めながら衝突判定
28
![Page 29: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/29.jpg)
距離関数とは
距離関数
入力:3Dの座標 p (vec3)
出力:点 p からシーンの物体への 最短距離(float)
29
![Page 30: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/30.jpg)
距離関数とは
距離関数 = 最短距離
イメージしずらいので、 実例を挙げていきます
30
![Page 31: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/31.jpg)
距離関数とは
距離関数 = 点 p から、シーン中の物体への最短距離を返す関数
31
距離関数(p) = 最短距離の長さ
![Page 32: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/32.jpg)
距離関数とは
距離関数 = 点 p から、シーン中の物体への最短距離を返す関数
32
![Page 33: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/33.jpg)
距離関数とは
距離関数 = 点 p から、シーン中の物体への最短距離を返す関数
33
![Page 34: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/34.jpg)
レイマーチングのアルゴリズム
距離関数は分かったけど、どうやって衝突判定するの?
次のシーンを使って実例で説明!
34
![Page 35: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/35.jpg)
レイマーチング
レイを少しずつ進める ||
レイマーチング
35
![Page 36: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/36.jpg)
レイマーチングのアルゴリズム
レイの先端はカメラの位置からスタート
がレイの先端
36
![Page 37: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/37.jpg)
レイマーチングのアルゴリズム
レイの向きは常に真っ直ぐ
37
![Page 38: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/38.jpg)
レイマーチングのアルゴリズム
赤い線 = 距離関数の値 = レイの先端からの最短距離
一番近い位置にあるのは黄色い球体
38
![Page 39: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/39.jpg)
レイマーチングのアルゴリズム
距離関数の値だけ、レイの先端 を進める
39
![Page 40: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/40.jpg)
レイマーチングのアルゴリズム
2週目の先端 から、さらに最短距離を求める
2週目でも黄色い球体が最短
40
![Page 41: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/41.jpg)
レイマーチングのアルゴリズム
最短距離だけレイを進めて、3週目のレイの先端が求まる
41
![Page 42: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/42.jpg)
レイマーチングのアルゴリズム
3週目でも黄色い球体が最短
42
![Page 43: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/43.jpg)
レイマーチングのアルゴリズム
4週目のレイの先端が求まる
43
![Page 44: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/44.jpg)
レイマーチングのアルゴリズム
4週目で、ついに緑の箱が最短!!
44
![Page 45: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/45.jpg)
レイマーチングのアルゴリズム
レイの先端が無事に緑の箱の位置となった!!
45
![Page 46: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/46.jpg)
レイマーチングのアルゴリズム
衝突するまで(最短距離が0)になるまで、ひたすらレイを進めるだけ
最短距離だけ進めるので、進みすぎて通り抜けることはない
単純!!シンプル!!
46
![Page 47: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/47.jpg)
レイマーチングのアルゴリズム
レイマーチングのアルゴリズムの繰り返し処理
||
マーチングループ
47
![Page 48: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/48.jpg)
レイマーチングのアルゴリズム
マーチングループの実装例
48
float dist, depth = 0.0; p = origin;
for ( int i = 0; i < 64; i++ ){ dist = sceneDist( p ); depth += dist; p = origin + depth * ray;
if ( abs(dist) < EPS ) break; }
![Page 49: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/49.jpg)
レイマーチングのアニメーション
https://twitter.com/motions_work/status/694898149622550528
49
![Page 50: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/50.jpg)
スフィアートレーシング
今まで説明したのはレイマーチングの1種のスフィアートレーシング
衝突判定の過程で球(スフィアー)がたくさん出てくる
50
![Page 51: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/51.jpg)
3D描画手法の整理
ラスタライザ
レイトレーシング
-レイマーチング
•スフィアトレーシング
51
![Page 52: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/52.jpg)
距離関数の実装
![Page 53: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/53.jpg)
球体の距離関数
原点が中心の半径rの球体の距離関数
原点からの距離 - 半径r
超シンプル
53
float sphereDist(vec3 p, float r) { return length(p) - r; }
【画像出典】 http://resources.esri.com/help/9.3/arcgisengine/java/api/arcobjects/
com/esri/arcgis/geometry/ISphere.html
r
![Page 54: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/54.jpg)
箱の距離関数
原点にある大きさbの箱の距離関数
これも超シンプル
動作原理はややこしいので割愛><
54
float boxDist(vec3 p, vec3 b){ return length(max(abs(p) - b, 0.0)); }
![Page 55: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/55.jpg)
様々な距離関数http://iquilezles.org/www/articles/distfunctions/distfunctions.htm
最初のメガデモの作者 iq 氏のページにまとめらている
55
![Page 56: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/56.jpg)
シェーディング衝突「した・しない」の情報からはシルエットしか出せない
56
![Page 57: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/57.jpg)
シェーディング光源の向きと法線が分かれば、シェーディング(陰影効果)できるfloat diffuse = clamp(dot(light, normal), 0.1, 1.0);
57
![Page 58: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/58.jpg)
法線を求める
レイトレーシングでは、形状に応じた法線の計算が必要
- 球体の法線:交点から球体の中心を引く
- ポリゴンの法線:エッジの外積を計算
58
![Page 59: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/59.jpg)
法線を求める
レイトレーシングでは、形状に応じた法線の計算が必要
- 球体の法線:交点から球体の中心を引く
- ポリゴンの法線:エッジの外積を計算
59
![Page 60: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/60.jpg)
法線を求める
レイマーチングでは、どんな形状でも同じ計算で法線が求まる
- 球体の法線:距離関数の勾配
- 箱の法線: 距離関数の勾配
60
![Page 61: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/61.jpg)
法線を求める
レイマーチングでは、どんな形状でも同じ計算で法線が求まる
- 球体の法線:距離関数の勾配
- 箱の法線: 距離関数の勾配
61
![Page 62: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/62.jpg)
法線を求める
なるほど! 勾配!
って何だっけ?62
![Page 63: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/63.jpg)
法線を求める
63
const float EPS = 0.01; vec3 getNormal( vec3 p ) { return normalize(vec3( sceneDist(p + vec3( EPS, 0.0, 0.0 ) ) - sceneDist(p + vec3( -EPS, 0.0, 0.0 ) ), sceneDist(p + vec3( 0.0, EPS, 0.0 ) ) - sceneDist(p + vec3( 0.0, -EPS, 0.0 ) ), sceneDist(p + vec3( 0.0, 0.0, EPS ) ) - sceneDist(p + vec3( 0.0, 0.0, -EPS ) ) )); }
勾配の計算 = xyzそれぞれ少しずらして、 距離関数の差分を計算
![Page 64: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/64.jpg)
法線を求める
数学では、f(x,y,z) = 0 で表せる曲面の法線ベクトル n はn = (f’x, f’y, f’z) と fの偏微分(勾配)となると知られている
距離関数は f(x,y,z) = 0 で表せる曲面に等しい
法線n = 距離関数の勾配 として計算可能
64
![Page 65: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/65.jpg)
法線を求める
「学校で微分は傾きと習ったんだけど!?」
y = 2x のような式だと、xの微分は傾き
f(x,y) = 2x - y = 0 に変形すれば、2次元でも微分は法線
65
![Page 66: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/66.jpg)
距離関数は万能
![Page 67: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/67.jpg)
距離関数の発展編
レイマーチングでは、距離関数でシーンを定義
距離関数を制した者がレイマーチングを制す
67
![Page 68: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/68.jpg)
話の流れ
1. レイマーチングのための基礎知識
2. レイマーチングのアルゴリズム解説
3. レイマーチング発展編
4. three.js の話
68
![Page 69: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/69.jpg)
距離関数の合成
箱と球体を和集合で組み合わせた距離関数
min で各距離関数を合成
69
// 箱と球体を和集合で組み合わせた距離関数 float sceneDist(vec3 p) { return min( boxDist(p, vec3(0.9, 0.45, 0.9), 0.05), sphereDist(p, vec3(0.0, 0.45, 0.0), 0.9) ); }
![Page 70: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/70.jpg)
距離関数の合成
距離関数を min や max で合成するだけで、CSG表現が可能
70
![Page 71: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/71.jpg)
距離関数の無限の繰り返し
mod 演算 で p をループさせることで、無限に繰り返し表示できる
71
float distSphere(vec3 p, float r) { return length(p) - r; }
vec3 onRep(vec3 p, float interval) { return mod(p, interval) - interval * 0.5; }
float distScene(vec3 p) { return distSphere(onRep(p, 4.0), 1.0); }
![Page 72: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/72.jpg)
距離関数の実践編
最初の鉄骨の例
CSG表現+
無限の繰り返し
で実現可能!
72
![Page 73: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/73.jpg)
距離関数の実践編
幅widthの四角柱の距離関数
73
float barDist(vec2 p, float width) { return length(max(abs(p) - width, 0.0)); }
float sceneDist(vec3 p) { float bar_x = barDist(p.yz, 0.1); return bar_x; }
![Page 74: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/74.jpg)
距離関数の実践編
y軸の四角柱を和集合
74
float sceneDist(vec3 p) { float bar_x = barDist(p.yz, 0.1); float bar_y = barDist(p.xz, 0.1);
return min(bar_x, bar_y); }
![Page 75: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/75.jpg)
距離関数の実践編
z軸の四角柱を和集合
75
float sceneDist(vec3 p) { float bar_x = barDist(p.yz, 0.1); float bar_y = barDist(p.xz, 0.1); float bar_z = barDist(p.xy, 0.1);
return min( min(bar_x, bar_y), bar_z); }
![Page 76: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/76.jpg)
距離関数の実践編
無限の繰り返し
76
vec2 onRep(vec2 p, float interval) { return mod(p, interval) - interval * 0.5; }
float barDist(vec2 p, float interval, float width) { return length( max(abs(onRep(p, interval)) - width, 0.0)); }
p ➡ onRep(p, interval)
![Page 77: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/77.jpg)
距離関数の実践編
同様に円柱を無限に繰り返し
77
float tubeDist(vec2 p, float interval, float width) { return length(onRep(p, interval)) - width; }
float sceneDist(vec3 p) { float tube_x = tubeDist(p.yz, 0.5, 0.025); float tube_y = tubeDist(p.xz, 0.5, 0.025); float tube_z = tubeDist(p.xy, 0.5, 0.025);
return min(min(tube_x, tube_y),tube_z); }
![Page 78: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/78.jpg)
距離関数の実践編
角柱 から 円柱 を 差集合 で刳り貫くと…
78
- =
![Page 79: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/79.jpg)
距離関数の実践編
カメラの向きを変えると…
79
![Page 80: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/80.jpg)
距離関数の実践編
sceneDist全体
80
float sceneDist(vec3 p) { float bar_x = barDist(p.yz, 1.0, 0.1); float bar_y = barDist(p.xz, 1.0, 0.1); float bar_z = barDist(p.xy, 1.0, 0.1);
float tube_x = tubeDist(p.yz, 0.1, 0.025); float tube_y = tubeDist(p.xz, 0.1, 0.025); float tube_z = tubeDist(p.xy, 0.1, 0.025);
return max(max(max(min(min( bar_x, bar_y),bar_z), -tube_x), -tube_y), -tube_z); }
![Page 81: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/81.jpg)
距離関数の実践編
赤い色をつけて、遠くを明るくすると…
81
![Page 82: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/82.jpg)
距離関数まとめ
距離関数: 物体までの最短距離
以下を簡単に実現できる
- CSG表現(図形の合成)
- 無限の繰り返し
少ないコードで複雑な形状をできる82
![Page 83: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/83.jpg)
話の流れ
1. レイマーチングのための基礎知識
2. レイマーチングのアルゴリズム解説
3. レイマーチング発展編
4. three.js の話
83
![Page 85: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/85.jpg)
three.js を使う理由
WebGLの初期化処理をたった数行のコードで書ける
カメラのコントロールのための ライブラリを最初から提供
85
大量のコードを書きたくない
![Page 86: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/86.jpg)
three.jsの用語
画像出典: https://html5experts.jp/yomotsu/5225/
86
![Page 87: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/87.jpg)
フラグメントシェーダ実装
シーンの中に1枚の板を配置
1枚の板の塗り方を決める処理として、レイマーチングをフラグメントシェーダをつかって実装
87
![Page 88: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/88.jpg)
three.js からシェーダを使う
1枚の板のジオメトリを作り、頂点シェーダとフラグメントシェーダを設定したマテリアルを適用するコード
88
geometry = new THREE.PlaneBufferGeometry(2.0, 2.0); material = new THREE.ShaderMaterial({ uniforms: { resolution: { type: "v2", value: new THREE.Vector2(512.0, 512.0) }, }, vertexShader: "頂点シェーダ", fragmentShader: "フラグメントシェーダ", }); mesh = new THREE.Mesh(geometry, material);
![Page 89: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/89.jpg)
three.js からシェーダを使う
Material の初期化の時に、シェーダのコードを渡すだけ
89
geometry = new THREE.PlaneBufferGeometry(2.0, 2.0); material = new THREE.ShaderMaterial({ uniforms: { resolution: { type: "v2", value: new THREE.Vector2(512.0, 512.0) }, }, vertexShader: "頂点シェーダ", fragmentShader: "フラグメントシェーダ", }); mesh = new THREE.Mesh(geometry, material);
![Page 90: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/90.jpg)
three.js vs 生WebGL
スクロールバーに注目▼
90
three.js 49行 生WebGL 215行
![Page 91: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/91.jpg)
常にthree.jsが最適か?
生WebGLを書くことで勉強になる
高度なことをしたいなら、生WebGLを使うしか無い
91
![Page 92: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/92.jpg)
常にthree.jsが最適か?
three.js勢 も 生WebGL勢 も 仲良くしよう!
92
![Page 93: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/93.jpg)
まとめ
レイトレーシングはフラグメントシェーダで高速にGPU実装できる
レイマーチングでは距離関数で衝突判定をする
- 短いコードで複雑な形状を表現できる
- CSGや繰り返しが簡単にできる
three.jsでWebGLを少ないコードで扱える
93
![Page 94: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/94.jpg)
参考資料
我らが @h_doxas 先生の資料
- https://wgld.org/d/glsl/
メガデモの神 iq(@iquilezles) 氏のページ
- http://iquilezles.org/www/index.htm
のWebフロントエンド本 (私の著書)
- https://techbooster.github.io/c89/#scriptoon2
94
![Page 95: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/95.jpg)
参考資料
これがGPUの力!Three.jsによる“リアルタイム”なレイトレーシング
- http://qiita.com/gam0022/items/03699a07e4a4b5f2d41f
これがGPUの力!three.jsによる“リアルタイム”なレイトレーシング ~宝石編~
- http://qiita.com/gam0022/items/9875480d33e03fe2113c
95
![Page 96: シェーダだけで世界を創る!three.jsによるレイマーチング](https://reader031.vdocuments.pub/reader031/viewer/2022011722/587310371a28ab99088b7a65/html5/thumbnails/96.jpg)
資料について
資料は後日 SlideShare で公開予定
http://www.slideshare.net/shohosoda9
96