Reputation: 2065
I have a 3D object from Blender: cylinder.obj which I am able to render on the screen using Three.js. I also have the code in place to rotate the object using mouse. All this scene is inside a big div, say 600x600 pixel div.
I have the following code for render logic:
// Renders the scene and updates the render as needed.
function animate() {
// Render the scene.
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
This in my understanding is creating a loop and rendering the object again and again on the page.
Is there a way I can render the object once in the scene and then only redraw when there is any change to the object like texture change or when rotating the object using mouse. Once this texture application is done or the mouse rotate is complete, I want the scene to say intact and not consume any CPU for 3D rendering.
So, in brief, is there a way to render the scene only when needed and then stay idle and not consume a lot of CPU when the scene is behaving like an image.
I am new to three.js. I am testing this application in Chrome and IE11. Let me know if any more information is needed for clarification.
EDIT: Adding full JS code:
// 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();
Upvotes: 3
Views: 5204
Reputation: 2065
Figured out the logic using start - stop animation function on my events from link: Prevent requestAnimationFrame from running all the time
Upvotes: 0
Reputation: 7771
To do something only after something happens is called event-driven programming.
For example:
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);
}
So instead drawing with timer, you draw thing only when you need them to, and in your case, after mouse move or after the texture's finished loading.
You could then attach OnMouseMove
to an event listener, and textureLoaded
as some Three.js's callback function for texture loading.
P. S. GPU is actually doing the drawing, not the CPU.
Upvotes: 3