THREE.js糟糕的表现

时间:2019-07-03 07:41:11

标签: three.js

用THREE.js玩一下,我刚刚在场景中添加了两个对象,一个在中心,另一个在场景中旋转,相机在两个对象周围旋转。

这简单的事情使我的Macbook pro 2015变得疯狂。加载页面后的几秒钟内,风扇最大速度运转,并且计算机中的所有部件均变慢。

在Safari和Chrome中都会发生这种情况。 WebGL已打开。

我知道可以尝试锁定帧频。但这是Three.js的普遍问题,还是取决于编写不当的代码?如果编写得不好的代码可以为我提供我应该思考的内容以及该代码做错了什么的指针:

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>three.js webgl - geometries</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <script src="./three.js"></script>
        <style>
            html, body {
                margin: 0;
                padding: 0;
                width: 100%;
                height: 100%;
            }
        </style>
    </head>
    <body>
        <div id="container"></div>
        <script type="module">

            var container;
            var camera, scene, renderer;
            var mouseX = 0, mouseY = 0;
            var windowHalfX = window.innerWidth / 2;
            var windowHalfY = window.innerHeight / 2;
            var mercury;

            init();
            animate();

            function init() {
                container = document.getElementById( 'container' );
                camera = new THREE.PerspectiveCamera( 20, window.innerWidth / window.innerHeight, 1, 10000 );
                camera.position.z = 1800;
                scene = new THREE.Scene();
                scene.background = new THREE.Color( 0x333333 );
                var light = new THREE.DirectionalLight( 0xffffff );
                light.position.set( 0, 0, 1 );
                scene.add( light );

                light = new THREE.DirectionalLight( 0xffffff );
                light.position.set( 1, 0, 0 );
                scene.add( light );

                light = new THREE.DirectionalLight( 0xffffff );
                light.position.set( -1, -1, -2 );
                scene.add( light );

                // shadow
                var canvas = document.createElement( 'canvas' );
                canvas.width = 128;
                canvas.height = 128;

                var context = canvas.getContext( '2d' );
                var gradient = context.createRadialGradient( canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2 );

                gradient.addColorStop( 0.1, 'rgba(210,210,210,1)' );
                gradient.addColorStop( 1, 'rgba(255,255,255,1)' );

                context.fillStyle = gradient;
                context.fillRect( 0, 0, canvas.width, canvas.height );

                var shadowTexture = new THREE.CanvasTexture( canvas );
                var shadowMaterial = new THREE.MeshBasicMaterial( { map: shadowTexture } );

                var radius = 200;
                var geometry1 = new THREE.IcosahedronBufferGeometry( radius, 1 );
                var count = geometry1.attributes.position.count;
                geometry1.addAttribute( 'color', new THREE.BufferAttribute( new Float32Array( count * 3 ), 3 ) );

                var geometry2 = geometry1.clone();
                var geometry3 = geometry1.clone();

                var color = new THREE.Color();
                var positions1 = geometry1.attributes.position;
                var positions2 = geometry2.attributes.position;
                var positions3 = geometry3.attributes.position;

                var colors1 = geometry1.attributes.color;
                var colors2 = geometry2.attributes.color;
                var colors3 = geometry3.attributes.color;

                for ( var i = 0; i < count; i ++ ) {
                    color.setHSL( ( positions1.getY( i ) / radius + 1 ) / 2, 1.0, 0.5 );
                    colors1.setXYZ( i, color.r, color.g, color.b );
                    color.setHSL( 0, ( positions2.getY( i ) / radius + 1 ) / 2, 0.5 );
                    colors2.setXYZ( i, color.r, color.g, color.b );
                    color.setRGB( 1, 0.8 - ( positions3.getY( i ) / radius + 1 ) / 2, 0 );
                    colors3.setXYZ( i, color.r, color.g, color.b );
                }

                var material = new THREE.MeshPhongMaterial( {
                    color: 0xffffff,
                    flatShading: true,
                    vertexColors: THREE.VertexColors,
                    shininess: 0
                } );

                var wireframeMaterial = new THREE.MeshBasicMaterial( { color: 0x000000, wireframe: true, transparent: true } );

                var mesh = new THREE.Mesh( geometry3, material );
                var wireframe = new THREE.Mesh( geometry3, wireframeMaterial );
                mesh.add( wireframe );
                scene.add( mesh );

                var mercuryGeo = new THREE.SphereGeometry(50,15,15);
                var mercuryMat = new THREE.MeshPhongMaterial(); 
                mercury = new THREE.Mesh(mercuryGeo, mercuryMat); 
                scene.add(mercury); 

                renderer = new THREE.WebGLRenderer( { antialias: true } );
                renderer.setPixelRatio( window.devicePixelRatio );
                renderer.setSize( window.innerWidth, window.innerHeight );
                container.appendChild( renderer.domElement );

                window.addEventListener( 'resize', onWindowResize, false );
            }

            function onWindowResize() {
                windowHalfX = window.innerWidth / 2;
                windowHalfY = window.innerHeight / 2;
                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();
                renderer.setSize( window.innerWidth, window.innerHeight );
            }

            function animate() {
                requestAnimationFrame( animate );
                render();
            }

            var t = 0;
            function render() { 

                var timer = Date.now() * 0.0001;
                camera.position.x = Math.cos( timer ) * 2500;
                camera.position.z = Math.sin( timer ) * 2500;
                camera.lookAt( scene.position );

                t += 0.01;          
                mercury.rotation.y += 0.03;

                mercury.position.x = 1000*Math.cos(t) + 0;
                mercury.position.z = 1000*Math.sin(t) + 0; // These to strings make it work

                renderer.render( scene, camera );
            }

        </script>

    </body>
</html>

0 个答案:

没有答案