Pixi.js: Pixi.jsキャンバスとthree.jsキャンバスを組み合わせる

作成日 2015年01月21日  ·  12コメント  ·  ソース: pixijs/pixi.js

こんにちは、みんな !

まず第一に、Pixi.jsをありがとう、それは素晴らしいツールです、私はそれが大好きです! 2Dの世界のためのthree.jsの完璧なカウンターパート。

私はこの構成を希望するプロジェクトに取り組んでいます:

  • Pixi.jsを使用して完全なWebGLで記述された2DUI
  • この2DUIは、Three.jsで記述された3Dワールドの原点にカプセル化されます。
  • この3Dワールドは、Three.jsのVRステレオカメラでレンダリングされます。

3.jsキャンバス内にPixi.jsキャンバスをカプセル化するにはどうすればよいですか?

御時間ありがとうございます !

乾杯

エマニュエル

🤔 Question

最も参考になるコメント

私はaiが私の問題を解決したので投稿を編集します。誰かが同じ問題にぶつかり、例が必要になった場合に備えて、作業コードを投稿します。

<body>
    <script src="js/pixi.js"></script>
    <script src="js/three.min.js"></script>
    <script>
        width = window.innerWidth;
        height = window.innerHeight;

        //-------------------------------------------------------------------------------------
        // 3D Scene canvas
        //-------------------------------------------------------------------------------------
        var scene_3D = new THREE.Scene();
        scene_3D.fog = new THREE.Fog( "#a1a1a1", 2000, 4000 );

        var camera = new THREE.PerspectiveCamera( 75, width / height, 1, 10000 );
        camera.position.set( 0, 0, 700);
        camera.updateProjectionMatrix();

        var canvas_3D = new THREE.WebGLRenderer( { antialias: true } );
        canvas_3D.setSize( width, height );
        canvas_3D.setClearColor( scene_3D.fog.color, 1 );
        document.body.appendChild( canvas_3D.domElement );

        var geometry = new THREE.BoxGeometry( 500, 500, 500 );
        var material = new THREE.MeshNormalMaterial();
        var cube = new THREE.Mesh( geometry, material );
        cube.position.z = -500;
        cube.rotation.z = -45;
        scene_3D.add( cube );

        //-------------------------------------------------------------------------------------
        // 2D UI canvas
        //-------------------------------------------------------------------------------------
        var scene_UI = new PIXI.Stage( 0x66FF99 );

        var canvas_UI = PIXI.autoDetectRenderer(width, height, {transparent:true});
        canvas_UI.view.style.position = "absolute";
        canvas_UI.view.style.top = "0px";
        canvas_UI.view.style.left = "0px";

        var graphics = new PIXI.Graphics();
        graphics.beginFill( 0xe60630 );
        graphics.moveTo( width/2-200, height/2+100 );
        graphics.lineTo( width/2-200, height/2-100 );
        graphics.lineTo( width/2+200, height/2-100 );
        graphics.lineTo( width/2+200, height/2+100 );
        graphics.endFill();

        scene_UI.addChild( graphics );

        //-------------------------------------------------------------------------------------
        // Map 2D UI canvas on 3D Plane
        //-------------------------------------------------------------------------------------
        var texture_UI = new THREE.Texture( canvas_UI.view );
        texture_UI.needsUpdate = true;

        var material_UI = new THREE.MeshBasicMaterial( {map: texture_UI, side:THREE.DoubleSide } );
        material_UI.transparent = true;

        var mesh_UI = new THREE.Mesh( new THREE.PlaneGeometry(width, height), material_UI );
        mesh_UI.position.set(0,0,0);
        scene_3D.add( mesh_UI );

        //-------------------------------------------------------------------------------------
        // Render Animation
        //-------------------------------------------------------------------------------------
        function animate() {
            requestAnimationFrame( animate );
            canvas_UI.render( scene_UI );

            cube.rotation.y += 0.01;
            canvas_3D.render( scene_3D, camera );
        }
        animate();
    </script>
</body>

全てのコメント12件

three.jsがキャンバスをテクスチャとしてサポートしている場合は、pixiをオフスクリーンキャンバスにレンダリングして、それをthree.jsシーンのテクスチャとして使用できます。

スポットオン! それがまさに私たちのやり方です!

16:45の水曜日、2015年1月21日には、チャドエングラー[email protected]
書きました:

three.jsがテクスチャとしてキャンバスをサポートしている場合は、pixiを次のようにレンダリングできます。
オフスクリーンキャンバスを使用して、three.jsシーンのテクスチャとして使用します。


このメールに直接返信するか、GitHubで表示してください
https://github.com/GoodBoyDigital/pixi.js/issues/1366#issuecomment -70872648

マットグローブ

_テクニカルパートナー_

電話番号:07708 114496 :: www.goodboydigital.com
1階、ユニット9B、クイーンズヤード、ホワイトポストレーン、ロンドン、E9 5EN
goodboy©。 全著作権所有。

ワホウ...たくさんの人に感謝します! :)

これは私が高速フィードバックと呼んでいるものです!

細かいところまで考えています。

3Dワールド(Three.js)の上にレンダリングされる2D UIパネル(Pixi.js)を描画する機能が必要です。
ただし、これらの2DUIパネルには次のプロパティがあることが重要です。

  • 不透明度係数が0〜100%のOHPフィルム
  • バックグラウンドでの3Dワールドのぼかし効果

キャンバスをレンダリングするトリックを使用して、それをテクスチャとして適用する場合。 背景のぼかしができなくなるのではないかと思いますか?

これを説明するために画像を添付しました。
transparency

Three.js側のぼかしはありますか? pixiオブジェクトを透明にしてから、テクスチャを3Dシーンに自由にブレンドするだけです。

助けてくれてありがとう! あなたがそれを言ったので...それは間違いなく最も論理的な道です! :)

乾杯

E

私はaiが私の問題を解決したので投稿を編集します。誰かが同じ問題にぶつかり、例が必要になった場合に備えて、作業コードを投稿します。

<body>
    <script src="js/pixi.js"></script>
    <script src="js/three.min.js"></script>
    <script>
        width = window.innerWidth;
        height = window.innerHeight;

        //-------------------------------------------------------------------------------------
        // 3D Scene canvas
        //-------------------------------------------------------------------------------------
        var scene_3D = new THREE.Scene();
        scene_3D.fog = new THREE.Fog( "#a1a1a1", 2000, 4000 );

        var camera = new THREE.PerspectiveCamera( 75, width / height, 1, 10000 );
        camera.position.set( 0, 0, 700);
        camera.updateProjectionMatrix();

        var canvas_3D = new THREE.WebGLRenderer( { antialias: true } );
        canvas_3D.setSize( width, height );
        canvas_3D.setClearColor( scene_3D.fog.color, 1 );
        document.body.appendChild( canvas_3D.domElement );

        var geometry = new THREE.BoxGeometry( 500, 500, 500 );
        var material = new THREE.MeshNormalMaterial();
        var cube = new THREE.Mesh( geometry, material );
        cube.position.z = -500;
        cube.rotation.z = -45;
        scene_3D.add( cube );

        //-------------------------------------------------------------------------------------
        // 2D UI canvas
        //-------------------------------------------------------------------------------------
        var scene_UI = new PIXI.Stage( 0x66FF99 );

        var canvas_UI = PIXI.autoDetectRenderer(width, height, {transparent:true});
        canvas_UI.view.style.position = "absolute";
        canvas_UI.view.style.top = "0px";
        canvas_UI.view.style.left = "0px";

        var graphics = new PIXI.Graphics();
        graphics.beginFill( 0xe60630 );
        graphics.moveTo( width/2-200, height/2+100 );
        graphics.lineTo( width/2-200, height/2-100 );
        graphics.lineTo( width/2+200, height/2-100 );
        graphics.lineTo( width/2+200, height/2+100 );
        graphics.endFill();

        scene_UI.addChild( graphics );

        //-------------------------------------------------------------------------------------
        // Map 2D UI canvas on 3D Plane
        //-------------------------------------------------------------------------------------
        var texture_UI = new THREE.Texture( canvas_UI.view );
        texture_UI.needsUpdate = true;

        var material_UI = new THREE.MeshBasicMaterial( {map: texture_UI, side:THREE.DoubleSide } );
        material_UI.transparent = true;

        var mesh_UI = new THREE.Mesh( new THREE.PlaneGeometry(width, height), material_UI );
        mesh_UI.position.set(0,0,0);
        scene_3D.add( mesh_UI );

        //-------------------------------------------------------------------------------------
        // Render Animation
        //-------------------------------------------------------------------------------------
        function animate() {
            requestAnimationFrame( animate );
            canvas_UI.render( scene_UI );

            cube.rotation.y += 0.01;
            canvas_3D.render( scene_3D, camera );
        }
        animate();
    </script>
</body>

私たちはプロジェクトでこのようなことをしています。 両方のエンジン(pixiとThreeJS)がGL状態を追跡して冗長な呼び出しを最小限に抑えるため、少し注意が必要です。 これは、それらが互いにうまく機能しないことを意味するため、レンダラーを開始する前にフラグをリセットする必要があります。

ThreeJSの新しいバージョンでは、 renderer.resetGLState()使用できます。

PIXIでは、もう少し複雑です。 このようなものは、WebGLRendererのメソッドとして持つと便利です。 これらは前に必要です

    gl.disable(gl.DEPTH_TEST)
    gl.enable(gl.BLEND)
    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
    gl.disable(gl.STENCIL_TEST)
    gl.disable(gl.CULL_FACE)

    gl.frontFace( gl.CCW )    
    gl.cullFace( gl.FRONT )
    gl.colorMask(true, true, true, true)
    gl.activeTexture(gl.TEXTURE0)

    var shaderManager = session.shaderManager

    shaderManager._currentId = undefined
    for (var i=0; i<shaderManager.attribState.length; i++)
        shaderManager.attribState[i] = false
    shaderManager.setShader(shaderManager.currentShader)

    var blend = session.blendModeManager.currentBlendMode
    if (blend in PIXI.blendModesWebGL) {
        session.blendModeManager.currentBlendMode = undefined
        session.blendModeManager.setBlendMode(blend)
    }

これにより、フレームバッファを切り替えることなく、3Dシーンの上にUIをレンダリングできます。

UIの下でぼかしを実現することは、はるかに複雑です。 次のことを行う必要があります。

  • 3Dシーンをフレームバッファにレンダリングする
  • シザーテストを有効にし、マルチパスブラーシェーダー(ピンポンFBOなど)を使用してブラー領域をレンダリングします
  • 次に、2DUIを上にレンダリングします

この非常に正確で文書化されたフィードバックをありがとうマット! :)

私はWebGLプログラミングにかなり慣れていないので、これは非常に役立ちます。
私は最初にMix2ライブラリに躊躇しました。特に、ハッキングされたThree.jsが、必要なもののためにpixiをある程度置き換えることができることを躊躇しました。

しかし、2Dの開発者の焦点である優れた例は、gl2d呼び出しにpixiを使用することを本当に確信させました。

ミックスアプローチを選択したように見えるので、PixiがWebGLで2D要素を描画するためのより効率的な選択であることを確認していると思います。

乾杯

E

ミックスアプローチを選択したように見えるので、PixiがWebGLで2D要素を描画するためのより効率的な選択であることを確認していると思います。

まあ、多分。 ほとんどの場合、追加のパフォーマンスは重要ではなく(3000個のボタンを一度にアニメーション化する必要がある頻度はどれくらいですか?)、堅牢なテキストレンダリング、テキスト入力、スクロールイベントなどはWebGLでは非常に難しい場合があります。

最も簡単な方法は、UIにDOM / CSSを使用することです。 どうしてもWebGLを選択する必要がある場合(つまり、特定の効果、深度テストなど)、PixiはおそらくThreeJS for 2DUIよりも簡単です。

答えられたようですので、これを閉じます。

このスレッドは、閉じられた後に最近のアクティビティがないため、自動的にロックされています。 関連するバグについては、新しい問題を開いてください。

このページは役に立ちましたか?
0 / 5 - 0 評価