読者です 読者をやめる 読者になる 読者になる

フニゲの開発日記

Electronとか...

Three.jsも使ってみよう

Three.js Pixi.js

 3Dも使う必要があって、いまさらな感じもするがThree.jsもやってみた。
 2013年のPixi.jsがリリースされたときのアナウンスを見ると「Pixi.jsはThree.jsの2D版」という考え方が示されていて、まあ確かに似ている部分が多いと思う。片方勉強していれば、もう片方も習得しやすい。

 じゃあPixi.jsとThree.jsを同じcanvas共存できるようにしたらいいと思うのだが、どうもうまくいかないらしい。検索して見つけたサンプルでは、2Dと3Dを別々のcanvasに描画して、2DのcanvasにPixi.jsで描画したものをThree.jsの3D空間にテクスチャとして貼り付ける形になっている。

Combining a Pixi.js canvas and a three.js canvas · Issue #1366 · GoodBoyDigital/pixi.js · GitHub
How to use a Pixi.js Canvas as a Three.js Texture? - Stack Overflow

<html>
<head>
<script src="pixi.js"></script>
<script src="three.js"></script>
</head>

<body>
<script>
    width = window.innerWidth;
    height = window.innerHeight;

    
    // 3DはThree.jsで描画する
    var scene_3D = new THREE.Scene();
    var canvas_3D = new THREE.WebGLRenderer({antialias: true});
    canvas_3D.setSize(width, height);
    document.body.appendChild(canvas_3D.domElement);

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

    var geometry = new THREE.BoxGeometry(500, 500, 500);
    var texture = THREE.ImageUtils.loadTexture("res/funige.png");
    var material = new THREE.MeshBasicMaterial({ map: texture });
    var cube = new THREE.Mesh(geometry, material);
    cube.position.z = -500;
    cube.rotation.z = -45;
    scene_3D.add(cube);

    
    // 2DはPixi.jsで描画する
    var scene_UI = new PIXI.Container();
    var canvas_UI = PIXI.autoDetectRenderer(256, 256, {transparent:true});
    // document.body.appendChild(canvas_UI.view);

    var sprite = new PIXI.Sprite.fromImage("res/funige.png")
    sprite.scale.set(0.3);
    sprite.anchor.set(0.5);
    sprite.position.set(128);
    scene_UI.addChild(sprite);

    
    // canvas_UIの内容を512x512の板に貼り付けて3D空間上に表示する
    var texture_UI = new THREE.Texture(canvas_UI.view) 
    var material_UI = new THREE.MeshBasicMaterial({ map:texture_UI, transparent:true });

    var mesh_UI = new THREE.Mesh(new THREE.PlaneBufferGeometry(512, 512), material_UI);
    mesh_UI.position.set(0,0,0);
    scene_3D.add(mesh_UI);

    
    // アニメーション
    function animate() {
        requestAnimationFrame(animate);

        cube.rotation.y += 0.01;
        sprite.rotation += 0.01;
        mesh_UI.material.map.needsUpdate = true; // 2Dが更新されるたびに呼ぶ

        canvas_UI.render(scene_UI);
        canvas_3D.render(scene_3D, camera);
    }
    animate();
</script>

</body>
</html>

 うーん、だいたい動くんだけど、ブラウザによって表示がばらつくなあ。AndroidはまあChromeだけ動けばいいか……。


f:id:funige:20150531231048p:plain

サンプル

広告を非表示にする