見出し画像

A-Frame × TypeScript × Webpack でさくっとデモを作る際のプロジェクト構成

こんにちは、ARスタートアップMESONでプロデューサー・ディレクターをやっているjujujun110です。

いまMESONで手がけているお仕事はUnityによるネイティブ開発が中心なのですが、URLだけで簡単に空間とインタラクションができるWebAR/VRはが脚光を浴びる日も近いのではないかと個人的に興味をもっています。

たとえばアメリカのECモールサービスShopifyでは、あらゆるショップが自分の商品の3DモデルをARで提供できるようになっていて、欲しい商品のデザインやサイズが自分の部屋にマッチするか、アプリ不要・ワンタップで確かめられるようになっています。

(Product Hunt より引用)

ということで、 Web AR / VR をまた触りはじめていこうかなと思ったので、定期的にブログも書いていこうと思っています。(WebARも、WebVRフレームワークであるA-Frameに依存しているケースが多いので、基本的にはA-Frameの話が中心になると思います。)

直近ではシェーダーあたりの深淵なる領域に挑戦していければと思っています...が、今回は次回以降の下準備として、プロジェクト環境を整備したときのことについて書いていこうかなと思います。

最短でアプリケーションを作り出すためのプロジェクト構成

さて、フロントエンドといえばとにかく面倒くさいのが環境構築。

僕が以前A-Frameをよく触っていた2016頃は、生jsとbrowserifyあたりを使っていたのですが、今だとTypescript × Webpackの構成がデファクトっぽくなってきている気がするので、今回はとりあえず環境構築がてらA-Frameが動きそうなテンプレートを(自分用に)作ってみました。

初期状態はこんな感じで、シーン自体はA-Frameのチュートリアルと同じっもので、そこに頂点シェーダとフラグメントシェーダだけかかっている状態です。

git clone
cd aframe-ts-template
rm -rf .git 
git init

みたいな感じで最速でプロジェクトをセットアップし、

npm run dev -> Hotリロードの開発サーバー立ち上げ
npm run dist -> 本番用ソースコードのビルド
npm run deploy -> github pagesに公開

みたいに使えるようになっています。

├── dist/
│   ├── bundle.js
│   └── index.html
├── src/
│   ├── index.ts ← エントリーポイント
│   ├── js/
│   │   └── TypeScriptコンポーネント(.ts)
│   ├── scss/
│   │   └── style.scss
│   └── shaders/
│       └── シェーダ(.ts, .vert, .frag)
├── test/
│   └── typescriptモジュールのテストコード
└── もろもろの設定ファイルたち

プロジェクト構成はざっくりこんな感じ。

A-Frame本体のソースコードが非常に重くてビルドやデプロイに時間がかかるので、A-FrameだけはCDNから読み込み、他のライブラリはindex.tsから読み込む方針にしています。

TypescriptとWebpackとGLSLシェーダー(.vert, .frag)の組み合わせについての情報が少なく苦労しましたが、こんな感じでWebpackのloaderの設定をして...

# webpack.config.js
rules: [
    { test: /\.ts$/, use: ["babel-loader", "ts-loader"] },
    { test: /\.scss$/, use: ["style-loader", "css-loader", "sass-loader"] },
    { test: /\.(glsl|vert|frag)$/, exclude: /node_modules/, use: ['raw-loader', 'glslify-loader'] }
]

こんな感じでシェーダーを登録すると、うまくシーンに反映させられます。

# my-shader.js
AFRAME.registerShader('my-shader', {
  schema: {
    color: { type: 'color', is: 'uniform', default: 'white' },
    opacity: { type: 'number', is: 'uniform', default: 1.0 },
    thickness: { type: 'number', is: 'uniform', default: 1.0 },
    interval: { type: 'number', is: 'uniform', default: 0.01 }
  },
  vertexShader: require('./my-vertex-shader.vert').default,
  fragmentShader: require('./my-fragment-shader.frag').default,
})

これで、シンタックスハイライトがある状態でGLSLを編集できるので、シェーダー編集のPDCAも回しやすくて良いですね。

まとめ

というわけで、僕がここのところ使っているA-Frameの環境構築について書いてみました。DOM側で複雑な操作をする場合はVueやReactの導入してもうまく動くらしいので検討してみるのもよいかもしれません。

A-Frame × GLSLでバリバリ開発を進めていきたい方の参考になれば幸いです。

次回以降はもうちょっとXRやってる人のブログっぽい、グラフィカルな内容になると思うのでお楽しみに〜🙌