Upgrade to Pro — share decks privately, control downloads, hide ads and more …

TypeScript(WebGL)+React+Viteで、さくっとGeodesic Polyhedronを描画してみた

forcia_dev_pr
December 07, 2022
200

TypeScript(WebGL)+React+Viteで、さくっとGeodesic Polyhedronを描画してみた

Shinjuku.ts#1 発表資料

forcia_dev_pr

December 07, 2022
Tweet

Transcript

  1. 2 自己紹介
 • きみだれ
 ◦ tsuji と申します
 ◦ 今年 フォルシア新卒入社🐤


    
 • 好きな言語
 ◦ TypeScript
 ▪ 特徴:JavaScript に gradual typing を適用した言語 
 ▪ 個人開発・バイトで使用 
 ▪ 開発業務でも
 ◦ Rust
 ▪ 特徴:静的型付け、多相、所有権、ライフタイム、高い実行速度など 
 ▪ 個人開発・研究で使用 
 • 手続きマクロでDSLを作るなど 
 ▪ 2年前、弊社インターン(Rustインメモリデータベースコース)に参加 

  2. UV Sphere / ICO Sphere
 4 - ggったら、主に2つの手法が見つかった
 
 -

    UV Sphere
 - 地球みたいな頂点の配置
 - 頂点の分布に偏りがある
 
 - ICO Sphere
 - 多面体から構成される
 - 頂点がおおよそ均等に分布
 - Geodesic Polyhedron が正式名称らしい
 Geodesic polyhedra are available as geometric primitives in the Blender 3D modeling software package, which calls them icospheres: they are an alternative to the UV sphere, having a more regular distribution of vertices than the UV sphere. https://en.wikipedia.org/wiki/Geodesic_polyhedron
  3. Geodesic Polyhedron の構成方法
 5 1. 多面体を用意します
 2. 各面を複数の三角形に分割します
 3. 分割によって得られた各面内の頂点を球面上に押し出します


    4. できあがり
 
 
 
 
 今回は、これを正二十面体で実装した(見た目が良かった)
 https://upload.wikimedia.org/wikipedia/commons/thumb/f/ff/Ge odesic_icosahedral_polyhedron_example.png/2880px-Geodes ic_icosahedral_polyhedron_example.png
  4. やったこと
 7 • 目的
 ◦ Geodesic Polyhedron を描画する 
 ◦

    できたものを公開したい
 ◦ (描画に使う OpenGL 系ライブラリの API の復習もしたい) 
 
 • やったこと
 ◦ Vite でスッと開発環境を構築し、
 ◦ React で雑にcanvas elementとボタンを生やし、 
 ◦ WebGL でいい感じに Geodesic Polyhedron を描画 
 
 

  5. Vite:開発環境構築
 8 - 開発環境をささっと構築できるツール
 - 今回やりたいことに適していた
 - hot reload のサポート


    - 文字列の import が可能
 - import VertexShader from 'path/to/main.vert?raw'; - Deployも手軽
 - npm run build 後、生成された /dist ディレクトリを github に push するだけ 
 - 立ち上がりが高速
 
 などなど
 
 コレを付けるだけ

  6. React:DOM・イベント操作
 9 - 面の分割数を変更するボタンを作成
 - canvas は再描画させたくないので、分割数の情報は Ref で持つ 


    - canvas element の Ref から WebGL2RenderingContext を生成
 - マウスホイールで分割数の変更ができる
 - React ならイベントの登録が楽
 - addEventListener/removeEventListener とかしなくてもいい 
 - React の強みはそこじゃない 
 
 Q. React 要素少なくない?
 A. ごめんなさい...

  7. Geodesic Polyhedron の頂点生成
 10 - 頂点情報はCPU側(TypeScript プログラム)で生成
 - WebGL では

    Geometry Shader が使えないため 
 - 基準となる正二十面体の頂点情報はベタ書き 
 
 - 面の分割は高校数学で
 - 1辺をn分割するとき、内分点の位置ベクトル v は 元の三角形の各頂点の位置ベクトル v1, v2, v3 を用いて
 
 
 
 
 
 で得られる
 - 考えられる [p1, p2, p3] の組み合わせを二重ループで回せばOK 
 
 v1
 v2
 v3

  8. 11 - ざっくりとした描画処理の流れは以下
 1. 頂点情報やレンダリングに必要なその他の情報を生成 
 2. Shader によって、CPUから渡された情報をGPU上で加工 


    - Vertex Shader  :頂点に紐づいた値(座標など)を操作 
 - Fragment Shader:ポリゴンの色やその他属性をピクセルレベルで制御 
 3. 画面に出力
 
 - VBOの生成
 ◦ ポリゴンの頂点情報が格納されたオブジェクト 
 
 - GLSL(OpenGL Shader Language)プログラムを書き、コンパイル
 
 - Uniform 変数を用いてレンダリング
 ◦ TypeScript から各 Shader に、毎フレームで異なる値を渡す 
 - 描画面(表面or裏面)のフラグ:透過処理で使用(後述) 
 - 姿勢を示す3x3行列     :Vertex Shader で、ポリゴンの回転に使用 
 - 姿勢を示す3x3行列の逆行列 :Fragment Shader で、光の反射計算に使用 
 WebGL:Geodesic Polyhedron の描画

  9. 見た目の調整
 12 - Fragment Shader で色や透明度を調節
 - Phong reflection model

    の Diffuse/Ambient 項のみ実装 
 - 平行光源からの反射、環境光を表現 
 
 - 頂点の座標を用いて彩色
 - 動くとうれしいので回転を施す
 - 経過時間から回転行列を計算 → Uniform 変数として Shader から呼び出し 
 - 見た目をそれっぽくするために透過処理
 - (ポリゴンの裏面のみ描画 + 透明な表面を描画) + alpha blending(色混ぜ) 
 - 片方の面だけを描画する `Culling` という機能を用いる 
 - 裏面の描画では Diffuse 項を強めにかけ、透けてる感を強調 
 - 表面・裏面の識別に Uniform 変数を使用 
 
 ※それっぽく見えるように調整しているだけで、学術的根拠はありません 

  10. まとめ
 13 - Vite を使うことで、一瞬でReact+TSによる開発環境とデプロイ環境が出来上 がった
 - React は...まぁ無いよりは全然いい
 -

    WebGL(Vertex/Fragment Shader) を用いることで、いい感じの
 レンダリングが行えた
 - TypeScript を用いることで、このLTで発表ができた