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

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

forcia_dev_pr
December 07, 2022
37

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

Shinjuku.ts#1 発表資料

forcia_dev_pr

December 07, 2022
Tweet

Transcript

  1. TypeScript(WebGL)+React+Vite で、
    さくっと Geodesic Polyhedron を描画してみた
    フォルシア株式会社 旅行プラットフォーム第6部 

    辻 裕太

    2022/11/14
    Shinjuku.ts #1


    View Slide

  2. 2
    自己紹介

    ● きみだれ

    ○ tsuji と申します

    ○ 今年 フォルシア新卒入社🐤


    ● 好きな言語

    ○ TypeScript

    ■ 特徴:JavaScript に gradual typing を適用した言語 

    ■ 個人開発・バイトで使用 

    ■ 開発業務でも

    ○ Rust

    ■ 特徴:静的型付け、多相、所有権、ライフタイム、高い実行速度など 

    ■ 個人開発・研究で使用 

    ● 手続きマクロでDSLを作るなど 

    ■ 2年前、弊社インターン(Rustインメモリデータベースコース)に参加 


    View Slide

  3. 本題

    3
    とある週末、ダラダラしながらこんなことを考えていました

    「頂点がおおよそ均等に分布する球って、

                 どうやって構成するんだろう...?」

    - 地球のような、緯線・経線に沿った頂点の配置は直感的

    - 極に近いほど面のサイズが小さくなる(=頂点の密度が上がる)




    密

    疎


    View Slide

  4. 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

    View Slide

  5. 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

    View Slide

  6. デモ

    6
    https://forcia-tsuji.github.io/geodesic-polyhedron/


    View Slide

  7. やったこと

    7
    ● 目的

    ○ Geodesic Polyhedron を描画する

    ○ できたものを公開したい

    ○ (描画に使う OpenGL 系ライブラリの API の復習もしたい)


    ● やったこと

    ○ Vite でスッと開発環境を構築し、

    ○ React で雑にcanvas elementとボタンを生やし、

    ○ WebGL でいい感じに Geodesic Polyhedron を描画



    View Slide

  8. Vite:開発環境構築

    8
    - 開発環境をささっと構築できるツール

    - 今回やりたいことに適していた

    - hot reload のサポート

    - 文字列の import が可能

    - import VertexShader from 'path/to/main.vert?raw';
    - Deployも手軽

    - npm run build 後、生成された /dist ディレクトリを github に push するだけ 

    - 立ち上がりが高速


    などなど


    コレを付けるだけ


    View Slide

  9. React:DOM・イベント操作

    9
    - 面の分割数を変更するボタンを作成

    - canvas は再描画させたくないので、分割数の情報は Ref で持つ

    - canvas element の Ref から WebGL2RenderingContext を生成

    - マウスホイールで分割数の変更ができる

    - React ならイベントの登録が楽

    - addEventListener/removeEventListener とかしなくてもいい

    - React の強みはそこじゃない 


    Q. React 要素少なくない?

    A. ごめんなさい...


    View Slide

  10. Geodesic Polyhedron の頂点生成

    10
    - 頂点情報はCPU側(TypeScript プログラム)で生成

    - WebGL では Geometry Shader が使えないため

    - 基準となる正二十面体の頂点情報はベタ書き


    - 面の分割は高校数学で

    - 1辺をn分割するとき、内分点の位置ベクトル v は
    元の三角形の各頂点の位置ベクトル v1, v2, v3 を用いて






    で得られる

    - 考えられる [p1, p2, p3] の組み合わせを二重ループで回せばOK 


    v1

    v2
 v3


    View Slide

  11. 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 の描画


    View Slide

  12. 見た目の調整

    12
    - Fragment Shader で色や透明度を調節

    - Phong reflection model の Diffuse/Ambient 項のみ実装

    - 平行光源からの反射、環境光を表現 


    - 頂点の座標を用いて彩色

    - 動くとうれしいので回転を施す

    - 経過時間から回転行列を計算 → Uniform 変数として Shader から呼び出し

    - 見た目をそれっぽくするために透過処理

    - (ポリゴンの裏面のみ描画 + 透明な表面を描画) + alpha blending(色混ぜ)

    - 片方の面だけを描画する `Culling` という機能を用いる 

    - 裏面の描画では Diffuse 項を強めにかけ、透けてる感を強調

    - 表面・裏面の識別に Uniform 変数を使用 


    ※それっぽく見えるように調整しているだけで、学術的根拠はありません 


    View Slide

  13. まとめ

    13
    - Vite を使うことで、一瞬でReact+TSによる開発環境とデプロイ環境が出来上
    がった

    - React は...まぁ無いよりは全然いい

    - WebGL(Vertex/Fragment Shader) を用いることで、いい感じの

    レンダリングが行えた

    - TypeScript を用いることで、このLTで発表ができた


    View Slide