Jump to content

Combining Three.js and pixi.js


Recommended Posts

Hi there,

I'm pretty new to pixi and webgl in general and was wondering about something very specific. I'm running through a POC for building up a 3D game (based on Three.js) with all its UI managed by pixi.js
I found a couple of suggestions and ideas: rendering three.js renderer on a background sprite of pixi or output pixis's rendered on a texture that would be attached to a texture of a mesh that would be displayed by Three.js's renderer. The problem that this solutions lead to performance issues.

I pretty easily found an old talking about this (Right Here)  and mainly a person nicknamed "mattdesl" suggested this :


It gets a little tricky since both engines (pixi and ThreeJS) keep track of GL state to minimize redundant calls. This means that they don't play nicely with each other, so you need to reset their flags before starting the renderers.

With new versions of ThreeJS you can use renderer.resetGLState().

In PIXI, it's a bit more complicated. Things like this would be useful to have as a method in WebGLRenderer. These are needed before

    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)

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

    var shaderManager = session.shaderManager

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

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

This allows you to render the UI on top of the 3D scene without any frame buffer switching.

Achieving the blur underneath your UI is significantly more complicated. You would need to:

  • render the 3D scene to a frame buffer
  • enable scissor test and render the blur region(s) with a multi pass blur shader (ping-ponging FBOs etc)
  • then render 2D UI on top

Basically rendering three.js into a frame buffer and then render pixi.js over it. I will have to first render three.js on a framebuffer and pass it to pixi (how can I achiever the latter ?) but mainly my question is about the GL state reset that this quote talk about ! Is this still valid as a concern ? how can I access the blendModeManager and the ShaderManager ?

Thank you for your help guys. I will update you with my progress.

Link to comment
Share on other sites

  • 7 months later...

Isn't combining PIXI and THREE as simple as this?

var THREE_TEXTURE = PIXI.BaseTexture.fromCanvas(renderer.domElement, PIXI.SCALE_MODES.LINEAR);    // 'renderer.domElement' the view, canvas-element in THREE
var THREE_SPRITE = new PIXI.Sprite.from(new PIXI.Texture(THREE_TEXTURE));
app.stage.addChild(THREE_SPRITE); // 'app.stage': PIXI's stage

Then simply update that PIXI BaseTexture within requestAnimationFrame after THREE rendered its content.. (in that same function)

// all kinds of THREE things

// and then:  

var render = function() {  
    // render the THREE scene, whatever you want... 
    // and this simple thing will update PIXI's baseTexture every frame.

    // course make the RaF loop:



render();  // init it.. 

This works, even on an iPad mini. Can't find anything wrong with it. It keeps running at 60 FPS, even on a heavy project I'm working on.

One canvas element (PIXI's).



Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...