Jump to content

Mixing 2D and 3D using Phaser and Three.js


Recommended Posts

I got to wondering if it would be possible to render a 3D object in Phaser.  Obviously Phaser doesn't have this functionality built in, so I decided to try it using Three.js.   This is the result.  Just figured I would share separate to the tutorial series, in case anyone else what interested in trying it.



There are a few hacks to be aware of.  First, the canvas is flipped on Chrome, but oddly, not on Safari...   not sure why.  Second, the way I update the texture is brutal, there has to be a better way.  Third I did a this/that hack because I got sick of trying to get context working right with an anonymous method, one of Typescripts warts.  There is a better way, I just didn't bother searching further for it.


The code is written in typescript, but you can simply right click the running result to see the Javascript generated code.


The actual running example is here. If it's upside down, your browser doesn't flip the rendered results.  I've only tested Safari (no flip) and Chrome (flip)

Link to comment
Share on other sites

To be honest, I sorta thought I would find tons of people doing it already and was shocked when I found very little on the subject.  It's an increasingly common technique in games these days...  I hate to think though what the performance would be like on mine, especially with multiple realtime 3D objects live.  For dynamically generating sprites though the technique is perfectly viable since the calculations are done up front.



By the way, is there a better way to update the PIXI texture once the ThreeJS canvas changes, Rich?  There has to be, as the way I did it has the stench of evil about it.

Link to comment
Share on other sites

How did you do it?

renderThreeJS(target:Phaser.Sprite) {            if (this.renderer) {                this.renderer.render(this.scene, this.threeJSCamera);                if(target) {                    target.texture.destroy(true);                       target.setTexture(PIXI.Texture.fromCanvas(                        <HTMLCanvasElement>document.getElementById("hiddenContent")                            .children[0], PIXI.scaleModes.DEFAULT));                }            }        }

... yeah, not my finest hour.  It's called "it worked, good enough" coding.

Link to comment
Share on other sites

Are you rendering a ThreeJS scene into a Phaser canvas? Or the opposite?


Yeah, threeJS renders to a canvas, theoretically a hidden one.  The other oddity is, the render results were flipped on Chrome, like you get with a frame buffer.  This made complete sense to me, so I simply flipped the scene before rendering... then I discovered the results aren't flipped on Safari...  HTML...  figures.

Link to comment
Share on other sites

Still need to do the hackish destroy to get the texture to update, but I did discover I can create the Canvas in Phaser and never attach it to the dom, making the code much cleaner at least on the HTML side:

            this.canvasTarget = Phaser.Canvas.create(256,256,"renderHere");            this.renderer = new THREE.WebGLRenderer({ alpha: true, canvas:this.canvasTarget });
Link to comment
Share on other sites

  • 7 months later...

While the post is a bid old, you have my thanks. It was helpful in getting animated 3D objects rendering onto canvas (needed to avoid WebGL for project requirements).
For the dirty part you spoke of I used this:

    this.owner.loadTexture(PIXI.Texture.fromCanvas(        this.tjsRenderer.domElement, PIXI.scaleModes.DEFAULT));

instead of calling destroy and then setting the texture. Similar obviously, but this eliminated the constant spam of WebGL errors I was getting in the console.


I also simply referenced the renderer, which was stored within that class, instead of searching out the dom element in the document every frame.




(edit: I should note that the .owner is due to a component based system in our engine, in this case its an extension of Phaser.Sprite)

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