我有一个来自Blender的3D对象:cylinder.obj,可以使用Three.js在屏幕上进行渲染。我也有使用鼠标旋转对象的代码。所有这些场景都位于一个大div内,例如600x600像素div。

我有以下用于渲染逻辑的代码:

// Renders the scene and updates the render as needed.
function animate() {
    // Render the scene.
    renderer.render(scene, camera);

    requestAnimationFrame(animate);
}


以我的理解,这是创建一个循环并在页面上一次又一次地渲染对象。

有没有一种方法可以在场景中渲染一次对象,然后仅在对象发生任何变化(如纹理变化)或使用鼠标旋转对象时才重绘。一旦完成该纹理应用程序或鼠标旋转完成,我希望场景保持原样并且不占用任何CPU进行3D渲染。

简而言之,有一种方法可以只在需要时渲染场景,然后保持空闲状态,而当场景像图像一样时不消耗大量CPU。

我是three.js的新手。我正在Chrome和IE11中测试此应用程序。让我知道是否需要更多信息进行澄清。

编辑:添加完整的JS代码:

// global variables
// Set up the scene, camera, and renderer as global variables.
var scene, camera, renderer;
var WIDTH = $("#myDiv").width(),
    HEIGHT = $("#myDiv").height();

// Sets up the scene.
function init() {

    // Create the scene and set the scene size.
    scene = new THREE.Scene();
    // Create a renderer and add it to the DOM.
    if (Detector.webgl)
        renderer = new THREE.WebGLRenderer({ antialias: true });
    else
        renderer = new THREE.CanvasRenderer();  //IE10 and below, and may be mobile devices

    renderer.setSize(WIDTH, HEIGHT);
    renderer.domElement.id = 'mycanvas'; //setting id for canvas element
    console.log(renderer);
    $("#myDiv").append(renderer.domElement);

    // Create a camera, zoom it out from the model a bit, and add it to the scene.
    camera = new THREE.PerspectiveCamera(45, WIDTH / HEIGHT, 0.1, 100);
    camera.position.set(-3, 4, 12);
    scene.add(camera);

    // Create an event listener that resizes the renderer with the browser window.
    window.addEventListener('resize', function () {
        var WIDTH = window.innerWidth,
            HEIGHT = window.innerHeight;
        renderer.setSize(WIDTH, HEIGHT);
        camera.aspect = WIDTH / HEIGHT;
        camera.updateProjectionMatrix();
    });

    // Set the background color of the scene.
    renderer.setClearColor(0x333F47, 1);

    var light2 = new THREE.PointLight(0xffffff);
    light2.position.set(0, 10, -10);
    scene.add(light2);

    var light3 = new THREE.PointLight(0xffffff);
    light3.position.set(1, 5, 10);
    scene.add(light3);


    // Load in the mesh and add it to the scene.
    var objLoader = new THREE.OBJLoader();
    objLoader.load('objects/male.obj', function (object) {
        object.position.y = 0;
        object.scale.x = object.scale.y = object.scale.z = 1;
        scene.add(object);
    });
}

// Renders the scene and updates the render as needed.
function draw() {

    //requestAnimationFrame(draw);


    // Render the scene.
    renderer.render(scene, camera);
}

init();
draw();

最佳答案

仅在发生某些事情之后才做某事称为事件驱动编程。

例如:

function OnMouseMove(evt) {
    // do some transform update on object

    // after done updating - draw!
    draw();
}

function textureLoaded() {
    // hurray, my texture's now loaded, I'm ready to draw now
    draw();
}

function draw() {
    renderer.render(scene, camera);
}


因此,可以使用计时器来代替绘制,而仅在需要它们时(在您的情况下)在鼠标移动后或纹理完成加载后才进行绘制。

然后,您可以将OnMouseMove附加到事件侦听器,并将textureLoaded附加为Three.js的用于纹理加载的回调函数。

P. S. GPU实际上是在绘制图形,而不是CPU。

10-07 19:45
查看更多