レンダーパイプラインの利用 - actnwit/RhodoniteTS GitHub Wiki

Rhodoniteでは屈折表現やMSAAなどの込み入った表現ができますが、本来そのためには複雑なレンダリングパスの設定を行う必要があります。 それには一般的なリアルタイムレンダリングの知識が要求され、誰にでも容易にできることではありません。

image

そのため、Rhodoniteではレンダーパイプラインという仕組みを用意しています。 レンダーパイプラインは複雑なマルチパスの設定をすでに構築ずみのクラスであり、ユーザーはこれを使うことで屈折表現やMSAAなどの高度な表現の恩恵を簡単に受けることができます。 (UnityエンジンのURP(Universal Render Pipeline)のようなものです)

現在、ForwardRenderPipelineというレンダリングパイプラインのみが存在しますが、今後別のパイプラインが追加される可能性があります。

ForwardRenderPipeline

Forwardレンダリング方式のレンダーパイプラインです。

import Rn from '../../../dist/esm/index.mjs';

const p = document.createElement('p');
document.body.appendChild(p);

declare const window: any;

(async () => {
  Rn.Config.isUboEnabled = false;
  const canvas = document.getElementById('world') as HTMLCanvasElement;
  await Rn.System.init({
    approach: Rn.ProcessApproach.FastestWebGL2,
    canvas,
  });

  Rn.MeshRendererComponent.isDepthMaskTrueForTransparencies = true;

  // create ForwardRenderPipeline
  const forwardRenderPipeline = new Rn.ForwardRenderPipeline();
  forwardRenderPipeline.setup(canvas.width, canvas.height);

  // camera
  const {cameraComponent, cameraEntity} = createCamera();

  // gltf
  const mainExpression = await Rn.GltfImporter.import(
    '../../../assets/gltf/glTF-Sample-Models/2.0/IridescentDishWithOlives/glTF-Binary/IridescentDishWithOlives.glb',
    {
      cameraComponent: cameraComponent,
      defaultMaterialHelperArgumentArray: [
        {
          makeOutputSrgb: false,
        },
      ],
    }
  );

  // env
  const envExpression = createEnvCubeExpression(
    './../../../assets/ibl/papermill',
    cameraEntity
  );

  const mainRenderPass = mainExpression.renderPasses[0];
  // cameraController
  const mainCameraControllerComponent = cameraEntity.getCameraController();
  const controller =
    mainCameraControllerComponent.controller as Rn.OrbitCameraController;
  controller.setTarget(mainRenderPass.sceneTopLevelGraphComponents[0].entity);
  controller.dolly = 0.83;

  forwardRenderPipeline.setExpressions([envExpression, mainExpression]);

  // lighting
  setIBL('./../../../assets/ibl/papermill');

  const draw = function (frame) {
    Rn.System.process(frame);
  };

  forwardRenderPipeline.startRenderLoop(draw);
})();

使い方

まず、ForwardRenderPipelineをnewで生成し、次にsetupメソッドを呼びます。

  // create ForwardRenderPipeline
  const forwardRenderPipeline = new Rn.ForwardRenderPipeline();
  forwardRenderPipeline.setup(canvas.width, canvas.height);

次に、描画させたいExpressionの配列をsetExpressionsメソッドでセットします。

  forwardRenderPipeline.setExpressions([envExpression, mainExpression]);

Rn.System.startRenderLoop()ではなく、forwardRenderPipelineのstartRenderLoop()メソッドを呼びます。引数として描画関数をセットします。渡した関数の第一引数にはforwardRenderPipelineからframeオブジェクトが渡されるので、それを使ってRn.System.processメソッドを呼び出します。

  const draw = function (frame) {
    Rn.System.process(frame);
  };
  forwardRenderPipeline.startRenderLoop(draw);