three.js/examples/js見てますか？

### 前置き

このエントリは[HTML5 Advent Calendar 2014](http://qiita.com/advent-calendar/2014/html5)の12月15日の記事かつ私のQiitaデビュー作です。

three.js/examples/js見てますか・・・の前にそもそもthree.js使ってますか？残念ながらこのエントリは（別に難しいことは書いていないとはいえ）全く使ったことがない人に向けては書かれていないので、three.js使ってない人は明日以降のエントリに期待しつつ、そっとこのタブを閉じましょう。

### three.js/examples/js

さて、ということで本題です。みなさんthree.js/examples/jsをチェックしてますか？controlsディレクトリにある各種Controlsオブジェクトは使っていても、それ以外のオブジェクトはノーチェックという方も多いのではないでしょうか？というか私がそうだったんですが、先日欲しい機能のライブラリを探していたらexamples/js以下にまさにそのものがあり、この際にと思ってざっと中身を確認してみたらわりと宝の山だったので、その中から一部を本エントリでご紹介します。

### 紹介

examples/jsには本当にたくさんのサンプルが含まれていますが、再利用可能なものに限るとざっくり以下のように分類できるのではないでしょうか。

- コントロール
- オブジェクト
- アルゴリズム
- シェーダー
- 表示上の特殊効果
- インポート／エクスポート

もちろんこの分類は厳密なものではなく、これらに含まれないものや複数を組み合わせて利用するようなものもありますが、とりあえず今回のエントリではこの分類にそっていくつか紹介してみたいと思います。

#### コントロール

コントロールについてはおそらくほとんどの人が知っているでしょう。controlsディレクトリ以下にあり、ユーザーの入力に応じてカメラ（視点）を移動するものです。

よく使うものは

- controls/FirstPersonControls.js: 平面上を移動
- controls/FlyControls.js: 立体機動
- controls/OrbitControls.js: 中心から視点を逸らさないように周囲を移動

の3つくらいかと思いますが、それ以外にも

- controls/DeviceOrientationControls.js: デバイスの傾きに合わせて移動
- controls/OculusControls.js: OculusRiftのヘッドトラッキングに合わせて移動

と言ったキーボードやマウス以外を入力装置にできるコントロールもあります。一度目を通しておくといいでしょう。

#### オブジェクト

examplesで使用されているオブジェクトには、他のアプリケーションでも利用できそうな汎用的なものもいくつかあります。特に汎用性の高そうなものは以下でしょうか。

- Cloth.js: はためく布<br/>![スクリーンショット 2014-12-19 13.58.15.png](https://qiita-image-store.s3.amazonaws.com/0/8717/ee973cbd-42fd-5af3-763c-33083aae3991.png)
- Mirror.js: 鏡面反射する平面<br/>![スクリーンショット 2014-12-19 14.00.52.png](https://qiita-image-store.s3.amazonaws.com/0/8717/cacfd42c-9d3e-5ed5-ddfa-cf129ae1daa6.png)
- Ocean.js: 波打つ水面<br/>![スクリーンショット 2014-12-19 14.02.18.png](https://qiita-image-store.s3.amazonaws.com/0/8717/37d85c09-18de-419f-7d8c-99e415be5e7b.png)
- WaterShader.js: 水面っぽい反射をするシェーダーとそれを使用した水面<br/>![スクリーンショット 2014-12-19 14.03.45.png](https://qiita-image-store.s3.amazonaws.com/0/8717/b0d83aed-ecb3-b77e-cb85-6771a33104d2.png)

#### アルゴリズム

3Dグラフィックスを扱う際に（おそらく）利用できるであろう各種アルゴリズムの実装もexamplesにはいくつも含まれています。実際のところ私は門外漢なので有用性を正しく理解できているわけではないのですが、なんとなくこの辺は使いどころがありそうです。

- ImprovedNoise.js: パーリンノイズ
- Octree.js: 八分木
- PRNG.js: 擬似乱数生成器
- modifiers/SubdivisionModifier.js: ポリゴンの細分化
- modifiers/TessellateModifier.js: テッセレーション

#### シェーダー

3Dグラフィックスの見た目を改善するのにシェーダーは欠かせません。examples以下には本当にたくさんのシェーダーがあり紹介しきれませんが、目についたものだけを挙げてみます。

- ShaderGodRays.js: ゴッドレイシェーダー<br/>![スクリーンショット 2014-12-19 14.17.44.png](https://qiita-image-store.s3.amazonaws.com/0/8717/25c9e50d-ebf1-2415-2cf9-5007d21091b9.png)
- ShaderToon.js: トゥーンシェーダー<br/>![スクリーンショット 2014-12-19 14.23.56.png](https://qiita-image-store.s3.amazonaws.com/0/8717/c1d1c0c0-032d-c91f-08b9-8bd0c52a1e39.png)
- shaders/BokehShader.js: ボケシェーダー<br/>![スクリーンショット 2014-12-19 14.28.11.png](https://qiita-image-store.s3.amazonaws.com/0/8717/fb4a0e45-150c-6d73-b996-d4f837c7fa6e.png)
- shaders/HorizontalBlurShader.js: ブラーシェーダー<br/>![スクリーンショット 2014-12-19 14.29.37.png](https://qiita-image-store.s3.amazonaws.com/0/8717/947dc7ff-8579-c21f-1c3a-e8f1af3f7751.png)

独自にシェーダーを書けるようになると3Dの表現力が格段にあがります。勉強も兼ねてshadersディレクトリ以下をソースコードも含めてざっと見ておくといいのではないでしょうか。

#### 表示上の特殊効果

先のシェーダーを利用したりしなかったりして特殊効果を得るためのオブジェクトが effects/ ディレクトリと postprosessing/ ディレクトリの中にあります。いくつか紹介します。

まずeffects/ですが、ここで目立つのは

- effects/OculusRiftEffect.js

でしょう。ご想像通りかどうかはわかりませんが、これはOculusRiftで立体視できるよう視差のある樽型に変形された画像を表示してくれます。

![スクリーンショット 2014-12-19 14.26.27.png](https://qiita-image-store.s3.amazonaws.com/0/8717/72a97eb9-e88c-d4ee-040a-64104ec7cb8f.png)

つまり、このEffectと先ほど紹介したcontrols/OculusControls.jsと組み合わせればThree.jsを使用して簡単にOculusRiftに対応した3Dコンテンツを作れるということになります。

effects にはそれ以外にも立体視用のオブジェクトが含まれていますので、いい使いどころが見つかれば手軽に面白い効果が得られるはずです。

- effects/AnaglyphEffect.js: 赤と青の立体写真っぽいエフェクト<br/>![スクリーンショット 2014-12-19 14.30.54.png](https://qiita-image-store.s3.amazonaws.com/0/8717/29025d57-e1c7-0f3c-ff49-8f512067a598.png)
- effects/StereoEffect.js: ステレオ立体視できるようにするエフェクト<br/>![スクリーンショット 2014-12-19 14.31.53.png](https://qiita-image-store.s3.amazonaws.com/0/8717/00730e94-5661-2db4-70cc-495b284699a2.png)

postprosessing/ は実はよく分かってないのですが、とりあえずなんかいい感じの表示ができそうです。分かりやすいものを2つ上げます。

- postprosessing/BloomPass.js: ライトブルーム<br/>![スクリーンショット 2014-12-19 14.36.25.png](https://qiita-image-store.s3.amazonaws.com/0/8717/d9321d17-843f-703c-057e-9eb15b5be611.png)
- postprosessing/DotScreenPass.js: 印刷物のようにドットで陰影を表示するフィルタ<br/>![スクリーンショット 2014-12-19 14.40.11.png](https://qiita-image-store.s3.amazonaws.com/0/8717/cda8e04a-b203-8c4f-bce8-c58e9612452e.png)

#### インポート／エクスポート

loaders/ディレクトリとexporters/ディレクトリにはそれぞれThree.jsのMeshやGeometryを各種形式からインポートしたり、エクスポートするためのオブジェクトが数多く含まれています。おそらくこれらを使用すればインポート／エクスポートに関しては自分で実装する必要はほぼないはずですので一度は目を通しておきましょう。以下に一部をリストします。対象フォーマットはファイル名から察してください。

- exporters/OBJExporter.js
- exporters/STLBinaryExporter.js
- exporters/STLExporter.js
- loaders/OBJLoader.js
- loaders/OBJMTLLoader.js
- loaders/PLYLoader.js
- loaders/STLLoader.js
- loaders/SVGLoader.js
- loaders/VRMLLoader.js

<!--
## その他
  - RaytracingRenderer.js: レイトレーシングしてくれる？
    - http://localhost:8000/examples/raytracing_sandbox.html
-->

### 最後に

どうでしょう？three.js/examples/jsにはそのそっけないディレクトリ名に反して汎用的なコードがたくさん含まれているということが分かっていただけたでしょうか？

このすぐ下にこのエントリで紹介しきれなかったオブジェクトをざっと一覧しました。three.jsを使った3Dウェブアプリを作っていて何かライブラリに切り出せそうな機能を実装する必要に駆られた時は、手を動かす前にちょっとexamples/jsを確認してみてください。もしかしたらすでに必要な機能が実装されているかもしれません。

*Happy 3D Coding!*

----

### メモ

- **AudioObject.js**<br/>ドップラー効果を伴う3Dサウンド
- [**Cloth.js**](http://threejs.org/examples/webgl_animation_cloth.html)<br/>布オブジェクト
- **CurveExtras.js**<br/>各種曲線オブジェクト（GrannyKnot, HeartCurve, VivianiCurve...）
- **Detector.js**<br/>実行中のブラウザがWebGLをサポートしているかどうかの判定
- **ImprovedNoise.js**<br/>[パーリンノイズ](http://ja.wikipedia.org/wiki/%E3%83%91%E3%83%BC%E3%83%AA%E3%83%B3%E3%83%8E%E3%82%A4%E3%82%BA)
- **MarchingCubes.js**<br/>[マーチングキューブ法](http://ja.wikipedia.org/wiki/%E3%83%9E%E3%83%BC%E3%83%81%E3%83%B3%E3%82%B0%E3%82%AD%E3%83%A5%E3%83%BC%E3%83%96%E6%B3%95)によりボクセルをポリゴンに変換
- [**Mirror.js**](http://threejs.org/examples/webgl_mirror.html)<br/>鏡面反射するオブジェクト
- [**Ocean.js**](http://threejs.org/examples/webgl_shaders_ocean2.html)<br/>波打つ水面っぽいオブジェクト
- **Octree.js**<br/>[八分木](http://ja.wikipedia.org/wiki/%E5%85%AB%E5%88%86%E6%9C%A8)
- **PRNG.js**<br/>擬似乱数生成器
- **ParametricGeometries.js**
- **ShaderDeferred.js**<br/>遅延シェーディング
- [**ShaderGodRays.js**](http://threejs.org/examples/webgl_postprocessing_godrays.html)<br/>ゴッドレイシェーダー
- [**ShaderSkin.js**](http://threejs.org/examples/webgl_materials_skin.html)<br/>スキンシェーダー
- [**ShaderTerrain.js**](http://threejs.org/examples/webgl_terrain_dynamic.html)<br/>地形っぽいシェーダー
- [ShaderToon.js](http://threejs.org/examples/webgl_marchingcubes.html)<br/>トゥーンシェーダー
- **SimplexNoise.js**<br/>[Simplexノイズ](http://en.wikipedia.org/wiki/Simplex_noise)
- **SimulationRenderer.js**<br/>Boids
- [**SkyShader.js**](http://threejs.org/examples/#webgl_shaders_sky)<br/>SphereGeometryに設定できる青空っぽいシェーダー
- [**Sparks.js**](http://threejs.org/examples/webgl_particles_shapes.html)
- **TypedArrayUtils.js**<br/>TypedArrayに使用できるユーティリティ関数群（クイックソート、Kd木）
- [**WaterShader.js**](http://threejs.org/examples/webgl_shaders_ocean.html)<br/>水面っぽい反射をするシェーダーとそれを使用したWaterオブジェクト
- **cameras/**
  - **CombinedCamera.js**<br/>OrthographicCameraとTHREE.PerspectiveCameraを切り替えて使用できるカメラ
- **controls/**<br/>カメラ（視点）を操作するためのコントロール
  - **DeviceOrientationControls.js**<br/>デバイスの傾きでオブジェクトを操作するコントロール
  - **EditorControls.js**
  - **FirstPersonControls.js**<br/>高さ固定で移動できるコントロール
  - **FlyControls.js**<br/>Scene内を自由に移動できるコントロール
  - **OculusControls.js**<br/>Oculusのヘッドトラッキングに追従するコントロール
  - **OrbitControls.js**
  - **OrthographicTrackballControls.js**
  - **PointerLockControls.js**
  - **TrackballControls.js**
  - **TransformControls.js**
  - **VRControls.js**
- **curves/**<br/>[NURBS曲線・曲面](http://ja.wikipedia.org/wiki/NURBS)を描くためのオブジェクト群
  - **NURBSCurve.js**<br/>NURBS曲線
  - **NURBSSurface.js**<br/>NURBS曲面
  - **NURBSUtils.js**
- **effects/**<br/>レンダリングの結果に特殊な効果を与えるオブジェクト群
  - [**AnaglyphEffect.js**](http://threejs.org/examples/webgl_effects_anaglyph.html)<br/>赤と青の立体写真っぽくするエフェクト
  - **AsciiEffect.js**
  - [**OculusRiftEffect.js**](http://threejs.org/examples/webgl_effects_oculusrift.html)<br/>OculusRiftで表示できるように両眼用の表示と樽型の変形を加えるエフェクト
  - [**ParallaxBarrierEffect.js**](http://threejs.org/examples/webgl_effects_parallaxbarrier.html)
  - **StereoEffect.js**<br/>ステレオ立体視できるようにするエフェクト
  - **VREffect.js**
- **exporters/**<br/>THREE.Geometryを様々な形式でエクスポート
  - **OBJExporter.js**<br/>OBJ形式（各種3Dモデリングツールで利用可能）
  - **STLBinaryExporter.js**<br/>STLバイナリ形式（3Dプリンタのデファクト？）
  - **STLExporter.js**<br/>STLアスキー形式（3Dプリンタのデファクト？）
  - **SceneExporter.js**<br/>THREE.Sceneの情報をJSON形式でエクスポート（loaders/SceneLoaderで読み込める）
  - **TypedGeometryExporter.js**
- **geometries/**<br/>特殊なジオメトリ群
  - **ConvexGeometry.js**<br/>コンストラクタの引数として受け取った点群を含んだ凸包
  - **DecalGeometry.js**
  - **hilbert2D.js**<br/>2次元ヒルベルト曲線
  - [**hilbert3D.js**](http://threejs.org/examples/webgl_lines_splines.html)<br/>3次元ヒルベルト曲線
- **loaders/**<br/>様々な形式の3DモデルをTHREE.Geometryとして取り込み
  - **MTLLoader.js, OBJLoader.js, OBJMTLLoader.js, PLYLoader.js**などなど
  - **SceneLoader.js**<br/>exporters/SceneExporterでエクスポートしたJSONを読み込み
- **math/**<br/>（名前に反して）色関係のユーティリティ
  - **ColorConverter.js**
  - **Lut.js**
- **modifiers/**<br/>ポリゴンの細分化など
  - **ExplodeModifier.js**<br/>全てのfaceが独自のvertexを使用するように変更
  - **SubdivisionModifier.js**<br/>各ポリゴンをループ分割して細分化
  - **TessellateModifier.js**<br/>テッセレーションを実行
- **postprocessing/**
  - [**BloomPass.js**](http://threejs.org/examples/webgl_lines_colors.html)<br/>ライトブルーム（強い光が暗い部分に滲み出るような効果）
  - [BokehPass.js](http://threejs.org/examples/webgl_postprocessing_dof.html)<br/>ピントの合わない部分がボケるフィルタ
  - [DotScreenPass.js](http://threejs.org/examples/webgl_postprocessing.html)<br/>印刷物のようにドットで陰影を表示するフィルタ
  - EffectComposer.js
  - FilmPass.js
  - [GlitchPass.js](http://threejs.org/examples/webgl_postprocessing_glitch.html)<br/>Glitchされるフィルタ
  - MaskPass.js
  - RenderPass.js
  - SavePass.js
  - ShaderPass.js
  - TexturePass.js
- **renderers/**<br/>各種レンダラ群
  - CSS2DRenderer.js
  - CSS3DRenderer.js
  - CSS3DStereoRenderer.js
  - CanvasRenderer.js
  - Projector.js
  - [RaytracingRenderer.js](http://threejs.org/examples/raytracing_sandbox.html)<br/>レイトレーシングしてくれる？
  - SVGRenderer.js
  - SoftwareRenderer.js
  - WebGLDeferredRenderer.js
  - plugins/
    - DepthPassPlugin.js
- **shaders/**<br/>各種シェーダー群
  - BasicShader.js<br/>そのまま表示する以外なにもしない基本的なシェーダー
  - BleachBypassShader.js
  - BlendShader.js
  - BokehShader.js
  - BokehShader2.js
  - BrightnessContrastShader.js
  - ColorCorrectionShader.js
  - ColorifyShader.js
  - ConvolutionShader.js
  - CopyShader.js
  - DOFMipMapShader.js
  - DigitalGlitch.js
  - DotScreenShader.js
  - EdgeShader.js
  - EdgeShader2.js
  - FXAAShader.js
  - FilmShader.js
  - FocusShader.js
  - FresnelShader.js
  - HorizontalBlurShader.js
  - HorizontalTiltShiftShader.js
  - HueSaturationShader.js
  - KaleidoShader.js
  - LuminosityShader.js
  - MirrorShader.js
  - NormalMapShader.js
  - OceanShaders.js
  - ParallaxShader.js
  - RGBShiftShader.js
  - SSAOShader.js
  - SepiaShader.js
  - TechnicolorShader.js
  - TriangleBlurShader.js
  - UnpackDepthRGBAShader.js
  - VerticalBlurShader.js
  - VerticalTiltShiftShader.js
  - VignetteShader.js
- **utils/**
  - GeometryUtils.js
  - UVsDebug.js
- wip/<br/>作業中のオブジェクト群？