Pixi.js: Combinando un lienzo Pixi.js y un lienzo three.js

Creado en 21 ene. 2015  ·  12Comentarios  ·  Fuente: pixijs/pixi.js

Hola chicos !

En primer lugar, gracias por Pixi.js, es una gran herramienta, ¡me encanta! la contraparte perfecta de three.js para el mundo 2D.

Estoy trabajando en un proyecto en el que me gustaría tener esta configuración:

  • Una interfaz de usuario 2D escrita en WebGL completo con Pixi.js
  • Esta interfaz de usuario 2D se encapsularía en el origen de un mundo 3D escrito en Three.js
  • Este mundo 3D se renderizaría luego con una cámara estereoscópica de realidad virtual en Three.js

¿Cómo procedería a encapsular un lienzo de Pixi.js dentro de un lienzo de Three.js?

Gracias por tu tiempo !

Salud

Emmanuel

🤔 Question

Comentario más útil

EDITO la publicación ya que he resuelto mi problema, publico el código de trabajo en caso de que alguien tenga el mismo problema y necesite un ejemplo.

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

Todos 12 comentarios

Si three.js admite un lienzo como textura, entonces puede convertir pixi en un lienzo fuera de la pantalla y usarlo como textura en su escena three.js.

¡Correcto! ¡así es exactamente como lo hacemos!

El miércoles 21 de enero de 2015 a las 4:45 p.m., Chad Engler [email protected]
escribió:

Si three.js admite un lienzo como textura, entonces podría renderizar pixi a
un lienzo fuera de la pantalla y utilícelo como textura en su escena three.js.

-
Responda a este correo electrónico directamente o véalo en GitHub
https://github.com/GoodBoyDigital/pixi.js/issues/1366#issuecomment -70872648
.

Mat Groves

_Socio técnico_

Teléfono: 07708 114496 :: www.goodboydigital.com
Primer piso, unidad 9B, Queens Yard, White Post Lane, Londres, E9 5EN
buen chico ©. Reservados todos los derechos.

Wahou ... ¡Muchas gracias chicos! :)

¡Esto es lo que llamo retroalimentación rápida!

Solo estoy pensando en un pequeño detalle.

Necesito tener la capacidad de dibujar un panel de IU 2D (Pixi.js) que se renderizará en Top of a 3D World (Three.js).
Pero es importante que esos paneles de IU 2D tengan las siguientes propiedades.

  • Transparencia con un factor de opacidad de 0 a 100%
  • Efecto de desenfoque del mundo 3D en el fondo

Si utilizo los trucos de renderizar mi lienzo y lo aplico como textura. ¿Me temo que el desenfoque del fondo no será posible?

Adjunto una imagen para ilustrar esto.
transparency

¿El desenfoque en el lado de Three.js? Simplemente haga transparente el objeto pixi y luego mezcle la textura en su escena 3D como desee.

De nuevo, gracias por tu ayuda ! Ahora que lo dijiste ... ¡definitivamente es el camino más lógico! :)

Salud

mi

EDITO la publicación ya que he resuelto mi problema, publico el código de trabajo en caso de que alguien tenga el mismo problema y necesite un ejemplo.

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

Estamos haciendo algo como esto en un proyecto. Se vuelve un poco complicado ya que ambos motores (pixi y ThreeJS) realizan un seguimiento del estado de GL para minimizar las llamadas redundantes. Esto significa que no funcionan bien entre sí, por lo que debe restablecer sus indicadores antes de iniciar los renderizadores.

Con las nuevas versiones de ThreeJS puede usar renderer.resetGLState() .

En PIXI, es un poco más complicado. Sería útil tener cosas como esta como método en WebGLRenderer. Estos son necesarios antes

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

Esto le permite renderizar la interfaz de usuario sobre la escena 3D sin ningún cambio de búfer de cuadros.

Lograr el desenfoque debajo de la interfaz de usuario es significativamente más complicado. Necesitarías:

  • renderizar la escena 3D en un búfer de fotogramas
  • habilitar la prueba de tijera y renderizar las regiones de desenfoque con un sombreador de desenfoque de múltiples pasadas (FBO de ping-pong, etc.)
  • luego renderice la interfaz de usuario 2D en la parte superior

¡Gracias por este comentario tan preciso y documentado, Matt! :)

Como soy bastante nuevo en la programación WebGL, esto es extremadamente útil.
Primero dudé en la biblioteca Mix 2, especialmente en que un Three.js pirateado puede, de alguna manera, reemplazar pixi para lo que necesito.

Pero los excelentes ejemplos, el punto de enfoque del desarrollador en 2D, realmente me convencieron de usar pixi para llamadas gl2d.

Como también parece haber elegido un enfoque Mixto, supongo que confirma que Pixi es definitivamente una opción más eficiente para dibujar elementos 2D con WebGL.

Salud

mi

Como también parece haber elegido un enfoque Mixto, supongo que confirma que Pixi es definitivamente una opción más eficiente para dibujar elementos 2D con WebGL.

Bien quizás. En la mayoría de los casos, el rendimiento adicional es discutible (¿con qué frecuencia necesita 3000 botones que se animen a la vez?), Y cosas como la representación de texto sólida, la entrada de texto y los eventos de desplazamiento pueden ser increíblemente desafiantes en WebGL.

La ruta más fácil es usar DOM / CSS para la interfaz de usuario. Si es absolutamente necesario elegir WebGL (es decir, para ciertos efectos, pruebas de profundidad, etc.), probablemente Pixi será más fácil que ThreeJS para la interfaz de usuario 2D.

Voy a cerrar esto ya que parece respondido.

Este hilo se ha bloqueado automáticamente ya que no ha habido ninguna actividad reciente después de su cierre. Abra un nuevo problema para errores relacionados.

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

SebastienFPRousseau picture SebastienFPRousseau  ·  3Comentarios

lunabunn picture lunabunn  ·  3Comentarios

gigamesh picture gigamesh  ·  3Comentarios

madroneropaulo picture madroneropaulo  ·  3Comentarios

Darker picture Darker  ·  3Comentarios