在 THREE.js 中动画画布广告牌 [英] Animating Canvas Billboard in THREE.js

查看:56
本文介绍了在 THREE.js 中动画画布广告牌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家,

我正在尝试为映射到平面(如广告牌)的基于 Canvas 的纹理制作动画.我已经强调包括 ma​​terial.needsUpdate &texture.needsUpdate,但我仍然无法让纹理栩栩如生.我还包含了一个旋转立方体,只是为了让我知道动画例程在某种程度上起作用.

代码如下:

<前>if ( window.innerWidth === 0 ) { window.innerWidth = parent.innerWidth;window.innerHeight = parent.innerHeight;}var 相机、场景、渲染器;var 网格、几何、材料;var 光,标志,animTex;var 画布,上下文;在里面();动画();函数初始化(){camera = new THREE.PerspectiveCamera( 50, window.innerWidth/window.innerHeight, 1, 1200 );相机.位置.z = 700;场景 = 新的 THREE.Scene();材料 = 新的 THREE.MeshLambertMaterial({ 颜色:0x885522,线框:假,透支:假});几何=新三立方几何(80、120、100、1、1、1);网格 = 新三.网格(几何,材料);符号 = createSign();光 = 新 THREE.DirectionalLight(0xFFFFFF, 3.0);light.position = new THREE.Vector3(5,10,7);light.target = new THREE.Vector3(0,0,0);场景添加(网格);场景添加(符号);场景添加(光);渲染器 = 新的 THREE.CanvasRenderer();renderer.setSize( window.innerWidth, window.innerHeight );document.body.appendChild(renderer.domElement);}函数 createSign() {canvas = document.createElement("canvas");context = canvas.getContext("2d");画布宽度 = 200;画布高度 = 200;context = canvas.getContext("2d");var 纹理 = 新的 THREE.Texture(canvas);纹理.needsUpdate = true;var material = new THREE.MeshBasicMaterial({ map : texture, overdraw: true });material.needsUpdate = true;var mesh = new THREE.Mesh(new THREE.PlaneGeometry(200, 200), material);mesh.doubleSided = true;返回网格;}函数动画(){var time = Date.now()*0.01;var sinTime = Math.sin ( 时间 * 0.05 ) * 100;var cosTime = Math.cos ( 时间 * 0.05 ) * 100;mesh.rotation.y = sinTime*0.01;requestAnimationFrame( 动画 );context.fillStyle="黑色";context.fillRect(0,0,canvas.width,canvas.height);context.fillStyle="白色";context.fillRect ( (canvas.width/2) + sinTime, (canvas.height/2) + cosTime, 20, 20 )renderer.render(场景,相机);}

这会运行,但我似乎无法更新 Canvas 纹理材质.我忽略了什么?非常感谢您的指点!

解决方案

把它放在你的 render() 调用之前:

sign.material.map.needsUpdate = true;

小提琴:http://jsfiddle.net/pPKVa/

Everyone,

I'm trying to animate a Canvas-based texture that is mapped onto a plane, like a billboard. I've made a point of including material.needsUpdate & texture.needsUpdate, but I'm still unable to get the texture to come to life. I've also included a rotating cube just so I know the animation routine is functioning on some level.

Here is the code:


    
      
      
        if ( window.innerWidth === 0 ) { window.innerWidth = parent.innerWidth; window.innerHeight = parent.innerHeight; }

            var camera, scene, renderer;
            var mesh, geometry, material;
            var light, sign, animTex;
            var canvas, context;

            init();
            animate();

            function init() {

                camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1200 );
                camera.position.z = 700;

                scene = new THREE.Scene();

                material = new THREE.MeshLambertMaterial(
                    { color: 0x885522
                    , wireframe: false
                     , overdraw: false
                    } );
                geometry = new THREE.CubeGeometry( 80, 120, 100, 1,1,1);
                mesh = new THREE.Mesh( geometry, material );

                sign = createSign();

                light = new THREE.DirectionalLight(0xFFFFFF, 3.0);
                light.position = new THREE.Vector3(5,10,7);
                light.target = new THREE.Vector3(0,0,0);

                scene.add( mesh );
                scene.add( sign );
                scene.add( light );

                renderer = new THREE.CanvasRenderer();
                renderer.setSize( window.innerWidth, window.innerHeight );
                document.body.appendChild( renderer.domElement );

            }
            function createSign() {
                canvas = document.createElement("canvas");
                context = canvas.getContext("2d");
                canvas.width = 200;
                canvas.height = 200;
                context = canvas.getContext("2d");              
                var texture = new THREE.Texture(canvas);
                texture.needsUpdate = true;
                var material = new THREE.MeshBasicMaterial({ map : texture, overdraw: true });
                material.needsUpdate = true;
                var mesh = new THREE.Mesh(new THREE.PlaneGeometry(200, 200), material);
                mesh.doubleSided = true;
                return mesh;
            }

            function animate() {

                var time = Date.now()*0.01;
                var sinTime = Math.sin ( time * 0.05 ) * 100;
                var cosTime = Math.cos ( time * 0.05 ) * 100;

                mesh.rotation.y = sinTime*0.01;

                requestAnimationFrame( animate );
                context.fillStyle="black";
                context.fillRect(0,0,canvas.width,canvas.height);
                context.fillStyle="white";
                context.fillRect ( (canvas.width/2) + sinTime, (canvas.height/2) + cosTime, 20, 20 )
                renderer.render( scene, camera );
            }

This runs, but I can't seem to get the Canvas texture material to update. What have I overlooked? Thanks very much for any pointers!

解决方案

Place this right before your render() call:

sign.material.map.needsUpdate = true;

Fiddle: http://jsfiddle.net/pPKVa/

这篇关于在 THREE.js 中动画画布广告牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆