Pixi.js: Menggabungkan kanvas Pixi.js dan kanvas three.js

Dibuat pada 21 Jan 2015  ·  12Komentar  ·  Sumber: pixijs/pixi.js

Hai kawan !

Pertama-tama Terima kasih untuk Pixi.js, ini alat yang hebat, I Love it! counter part yang sempurna dari three.js untuk dunia 2D.

Saya sedang mengerjakan proyek di mana saya ingin memiliki konfigurasi ini:

  • UI 2D yang ditulis dalam WebGL lengkap dengan Pixi.js
  • UI 2D ini akan merangkum asal mula dunia 3D yang ditulis dalam Three.js
  • Dunia 3D ini kemudian akan dirender dengan kamera stereoskopik VR di Three.js

Bagaimana Anda melanjutkan untuk merangkum Kanvas Pixi.js di dalam Kanvas Three.js?

Terima kasih atas waktunya !

Bersulang

Emmanuel

🤔 Question

Komentar yang paling membantu

Saya MENGEDIT posting karena ai telah menyelesaikan masalah saya, saya memposting kode yang berfungsi kalau-kalau seseorang mengalami masalah yang sama dan memerlukan contoh.

<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>

Semua 12 komentar

Jika three.js mendukung kanvas sebagai tekstur maka Anda dapat merender pixi ke kanvas di luar layar dan menggunakannya sebagai tekstur dalam adegan three.js Anda.

Tepat! persis seperti itu kami melakukannya!

Pada Rabu, 21 Jan 2015 pukul 16.45, Chad Engler [email protected]
menulis:

Jika three.js mendukung kanvas sebagai tekstur maka Anda dapat membuat pixi
kanvas di luar layar dan gunakan itu sebagai tekstur dalam adegan three.js Anda.

-
Balas email ini secara langsung atau lihat di GitHub
https://github.com/GoodBoyDigital/pixi.js/issues/1366#issuecomment -70872648
.

Mat Groves

_Mitra Teknis_

Telepon: 07708 114496 :: www.goodboydigital.com
Lantai Pertama, Unit 9B, Queens Yard, White Post Lane, London, E9 5EN
goodboy ©. Seluruh hak cipta.

Wahou ... Terima kasih banyak guys! :)

Inilah yang saya sebut sebagai Umpan Balik Cepat!

Saya hanya memikirkan detail kecil.

Saya harus memiliki kemampuan untuk menggambar panel 2D UI (Pixi.js) yang akan ditampilkan di Top of a 3D World (Three.js).
Namun penting bahwa panel UI 2D tersebut memiliki properti berikut.

  • Transparansi dengan faktor opasitas dari 0-100%
  • Efek blur Dunia 3D di latar belakang

Jika saya menggunakan trik rendering kanvas saya dan menerapkannya sebagai tekstur. Saya khawatir keburaman latar belakang tidak mungkin terjadi?

Saya telah melampirkan gambar untuk mengilustrasikan ini.
transparency

Lakukan pengaburan di sisi Three.js? Buat saja objek pixi transparan dan kemudian campur tekstur ke dalam pemandangan 3D Anda sesuka Anda.

Sekali lagi terima kasih atas Bantuan Anda! Sekarang setelah Anda mengatakannya ... itu pasti jalan yang paling logis! :)

Bersulang

E

Saya MENGEDIT posting karena ai telah menyelesaikan masalah saya, saya memposting kode yang berfungsi kalau-kalau seseorang mengalami masalah yang sama dan memerlukan contoh.

<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>

Kami melakukan sesuatu seperti ini dalam sebuah proyek. Ini menjadi sedikit rumit karena kedua mesin (pixi dan ThreeJS) melacak status GL untuk meminimalkan panggilan yang berlebihan. Ini berarti mereka tidak bermain baik satu sama lain, jadi Anda perlu mengatur ulang bendera mereka sebelum memulai perender.

Dengan versi baru ThreeJS Anda dapat menggunakan renderer.resetGLState() .

Di PIXI, ini sedikit lebih rumit. Hal-hal seperti ini akan berguna sebagai metode di WebGLRenderer. Ini dibutuhkan sebelumnya

    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)
    }

Ini memungkinkan Anda untuk merender UI di atas pemandangan 3D tanpa peralihan frame buffer.

Mencapai keburaman di bawah UI Anda jauh lebih rumit. Anda perlu:

  • membuat adegan 3D menjadi penyangga bingkai
  • aktifkan uji gunting dan render wilayah blur dengan multi pass blur shader (ping-ponging FBOs dll)
  • lalu render UI 2D di atas

Terima kasih atas umpan balik yang sangat tepat dan terdokumentasi ini Matt! :)

Karena saya cukup baru dalam pemrograman WebGL, ini sangat membantu.
Saya ragu-ragu pertama kali untuk mencampur 2 perpustakaan, terutama bahwa Three.js yang diretas dapat dalam beberapa hal menggantikan pixi untuk apa yang saya butuhkan.

Tapi contoh yang sangat bagus, titik fokus dev pada 2D, benar-benar meyakinkan saya untuk menggunakan pixi untuk panggilan gl2d.

Karena Anda terlihat telah memilih pendekatan Campuran juga, saya rasa itu mengkonfirmasi bahwa Pixi jelas merupakan pilihan yang lebih efisien untuk menggambar elemen 2D dengan WebGL.

Bersulang

E

Karena Anda terlihat telah memilih pendekatan Campuran juga, saya rasa itu mengkonfirmasi bahwa Pixi jelas merupakan pilihan yang lebih efisien untuk menggambar elemen 2D dengan WebGL.

Ya, mungkin. Dalam kebanyakan kasus, kinerja tambahan diperdebatkan (seberapa sering Anda memerlukan 3000 tombol yang dianimasikan sekaligus?), Dan hal-hal seperti rendering teks yang kuat, input teks, dan peristiwa gulir dapat menjadi sangat menantang di WebGL.

Rute termudah adalah dengan menggunakan DOM / CSS untuk UI. Jika Anda benar-benar perlu memilih WebGL (yaitu untuk efek tertentu, pengujian mendalam, dll) maka Pixi mungkin akan lebih mudah daripada ThreeJS untuk 2D UI.

Akan menutup ini karena sepertinya dijawab.

Utas ini telah dikunci secara otomatis karena tidak ada aktivitas baru-baru ini setelah ditutup. Silakan buka masalah baru untuk bug terkait.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat