スクリーンショット_2018-09-08_9

PBRでブラウザでもリアルな表現をしよう!

こんにちは。最近チームメンバーがUnity使いになっていく中、WebGLで遊んでいるSRETKSです。今回は、汎用の3Dフォーマットである「.glTF」がサポートするPBRマテリアルを使って、ブラウザでもリアルな表現を試してみたいと思います。

PBR(Physical-Based-Rendering)
現実の光学現象をシミュレートすることによりリアルな質感を表現できるレンダリング方法です。(詳しくはCygamesさんのブログが分かりやすいので、ご参考ください)

.glTF(GL Transmission Format)
Kronose Groupが提唱している汎用の3Dフォーマットです。(詳しくは、オフィシャルのgithub@emadurandalさんの記事をご参考ください)

WebGLライブラリが.glTFとPBRに対応したのはこの数年で、決して新しい技術ではありません。ただ、実装例となるとあまり見つからないので、順を追って書いていきます。

尚、この記事は下記のチュートリアル(英文)を元に実装した内容から、なるべくシンプルにPBRと.glTFを使うことを目指して作成しています。より詳しく知りたい方は、元記事もご参考ください!

完成形

まずは完成形のイメージをご覧くださいませ。

STEP 1.BlenderからglTFを出力する

1-1.3Dモデルを準備する

今回はデモ用なので、適当なモデルを探してBlenderにインポートします。

1-2.BlenderにglTFのExporterをインストールする

Blenderから.glTFファイルを出力するには、Blenderのadd-onとしてKhronos Group提供のExporterを追加する必要があります。Exporterのダウンロードとインストール方法は、こちらから確認できます。

1-3.PBRマテリアルを準備する

.glTF出力するモデルにPBRマテリアルを適用するには、Blenderデフォルトのマテリアルではなく、Khronos Groupが設定したマテリアルを使います。まずは、こちらのURLから「glTF2.blend」をダウンロードしてください。

次に、元のBlenderのシーンから「file -> Link -> glTF2.blend」を選択します。.blendファイルの中身が確認できますので、その中から「NodeTree」にある「glTF Metallic Roughness」を選択すれば、Node Editor内で使用できるようになります。

「Add -> Group」から追加できるようになった状態。

1-4.base colorを設定する

glTF Metallic Roughnessを追加したら、次は色や質感を設定していきます。

まずは「Add -> Texture -> Image Texture」でテクスチャ用のNodeを追加し、ダウンロードした3Dモデルのフォルダにある「act_bibliotekar.jpg」を選択してください。そのNodeをbase colorと接続すれば、色が適用されます。

1-5.normalを設定する

色が設定できたら、もう一つImage Texture Nodeを追加して、次は「act_bibliotekar norm.jpg」を選択してください。今度はnormalと接続することで、法線マップが設定できます。

最初よりも、だいぶリアルなイメージになりました。

1-6.glTFファイルを出力する

最後に「File -> Export -> glTF2.0(.glTF)」を選択して、ファイル出力します。これでひとまず、Blenderの作業は終了です。

STEP 2.WebGLで出力する

.glTFファイルが出力できたら、次は描画のためのWebGLライブラリを選択します。どのライブラリがPBRとglTFをサポートしているかは、cx20さんの記事が分かりやすいのでご参考ください。今回は、Babylon.jsを選びます。

Babylon.jsとは

Microsoftが開発しているWebGLライブラリです。これまでWebGLといえばThree.jsのみが知られ、Babylon.js含む他のライブラリはマイナーな存在だったのですが、Babylon.jsは最近徐々に盛り上がって日本の案件でも使われるようになってきました。

ちなみに、Babylon.jsのオフィシャルサイトには私のデモも掲載されているので、興味ある方は是非ご覧くださいませ。

2-1.glTF LoaderつきのBabylon.jsを作成する

Babylon.jsは、下のURLのジェネレーターによって用途に応じたカスタマイズが可能です。(Babylon.jsは他のライブラリと比べて容量が大きいため、このような機能ができたと考えられます)

今回は「LOADERS」の「glTF」にチェックを入れて作成してください。

2-2.環境マップを入手する

PBRは、環境マップの情報をモデルの色や質感に反映します。Babylon.jsでは、.dds形式のファイルを使用します。今回は、Babylon.jsのgithubにあった.ddsファイルを使いました。(他にも、デモで使われているものがいくつかあるはずです)

2-3.ブラウザで出力する

最後に、環境マップと.glTFファイルを読み込む.jsを作成すれば完成です。

let canvas, engine, scene, camera, creature;

const setup = () => {
  //エンジンを初期化してシーンを作成する
  canvas = document.getElementById("render");
  engine = new BABYLON.Engine(canvas, true);
  scene = new BABYLON.Scene(engine);

  //カメラを追加する
  camera = new BABYLON.FreeCamera(
    "camera",
    new BABYLON.Vector3(0, 120, -500),
    scene
  );
  scene.activeCamera = camera;
  camera.attachControl(canvas, true);

  //環境マップを読み込む
  let hdrTexture = BABYLON.CubeTexture.CreateFromPrefilteredData(
    "./environment.dds",
    scene
  );

  hdrTexture.gammaSpace = false;
  scene.createDefaultSkybox(hdrTexture, true, 2000);

  //glTFファイルを読み込む
  let loader = BABYLON.SceneLoader.Append("./gltf/", "creature.gltf", scene);

  loader.onMeshLoaded = mesh => {
    if (mesh.id === "Creature") {
      creature = mesh;
      mesh.material.metallic = 1.0;
      mesh.material.roughness = 0;
      run();
    }
  };
};

//フレームごとの描画
const run = () => {
  engine.runRenderLoop(() => {
    scene.render();
    creature.rotation.y += 0.01;
  });
};

document.addEventListener("DOMContentLoaded", setup);

2-4.WebVR用に出力する

Cameraの部分を以下のように変更するだけで、WebVR用に出力できます。

camera = new BABYLON.VRDeviceOrientationFreeCamera(
    "vrcamera",
    new BABYLON.Vector3(0, 120, -500),
    scene
  );

おまけ

.gltfはFacebookへの投稿も可能です。「File -> export - glTF(.glb)」を選択すれば、モデルとテクスチャなどのデータをまとめた.glb形式のファイルが作成できます。(容量や機能には制限があります)

まとめ

PBRと.glTFによって、ブラウザでもかなりリアルな表現が可能になりました。今のVR/ARはまだまだ専用の機器やアプリが必要なものが多く、それ自体が体験のハードルにならざるを得ないですが、ブラウザは「デバイスを選ばず・誰でもすぐに」体験を提供できるのがメリットです。

今後しばらくは、「どんなユーザー」に「どんな体験を提供するのか」によってプラットフォームには多くの選択肢が存在し、ブラウザもその一つであり続けるのではないでしょうか。

MESONでは、VR/ARが将来もたらす新たなユーザー体験と、それを実現する技術についてのリサーチと検証にも取り組んでいます。もし興味がある方がいらっしゃいましたら、会社のWEBサイトかTwitterなどでお気軽にお声がけくださいませ!


この記事が気に入ったらサポートをしてみませんか?