I am creating a static scene with a lot of objects and I want to save as image after it is rendered. How do I do that in THREE.js r69?
Most probably, you are not going in the right direction.
if you have some function like this
function animate() {
requestAnimationFrame(animate);
render ();
}
The render is doing it's work all the time.
When you are seeing the scene unfinished, it's because the meshes haven't finished loading, not because the render hasn't finished rendering.
So, you have to listen for some onload event on the models that you are loading, that will depend on the method that you use to load them (and that you don't explain, so I can't help you more)
Given the code in your reply, it isn't clear when you add the mesh to the scene. Anyway, I would try something in the line of
function loaderCallback() {
mesh = new THREE.Mesh (...
scene.add (mesh);
requestAnimationFrame(saveImage);
render ();
}
the function invoked at requestAnimationFrame should be called when render finishes.
Related
I'm trying to destroy (or destruct or dispose) an 'instance' of Three.JS using this:
Full example: https://jsfiddle.net/v7oLzs4m/58/
function kill() {
const rendererDomWas = renderer.domElement;
renderer.dispose();
controls.dispose();
renderer = scene = camera = controls = null;
document.body.removeChild( rendererDomWas );
shouldRender = false;
}
function animate() {
if(!shouldRender) {return} // no more requesting animation frames if 'shouldRender' is false
frameID = window.requestAnimationFrame( animate );
renderer.render( scene, camera );
}
(i.e. disposing, setting references to null, and stopping the draw loop from touching renderer while shouldRender is false)
It appears to work at first (The renderer content stops showing) but when I re-create the instance, it never comes back.
It's as if something is still... holding onto the GLContext which prevents it from being invoked again.
Why can't I re-create a new instance of Three.JS?
I'm not sure why this works (since I was already doing this in my Fiddle...)
But it turns out the secret ingredient (for me) to letting Three.JS get GC'd/disposed is this:
window.cancelAnimationFrame(frameID);
I suppose that this stops the render function from being stored in the hardware-level draw loop, which holds references to GLContext (and the chain)
The GC can't ever happen unless the 'loop is broken'
(Correct me if I'm wrong please)
I preload and create materials textures before start render and animate of objects.
But THREE JS upload texture to GPU only when object will be shown in camera.
So when new object comes on a screen animation is jerking because of texture sends on GPU.
The question is how to send textures to GPU during creation of texture for avoiding it during runtime?
Loading images to GPU takes a lot of time.
My guess is to walk your object tree, set each object's frustumCulled flag to false, call renderer.render(scene, ...) once, then put the flags back to true (or whatever they were).
function setAllCulled(obj, culled) {
obj.frustumCulled = culled;
obj.children.forEach(child => setAllCulled(child, culled));
}
setAllCulled(scene, false);
renderer.render(scene, camera);
setAllCulled(scene, true);
You can also call renderer.setTexture2D(texture, 0) to force a texture to be initialized.
Try renderer.initTexture(texture: THREE:Texture) for r0.149.0
I have created a game in three.js which exists of 3 scenes the GameScene, MenuScene and the HighScoreScene. The user can switch between those scenes - When the player is changing the Scene e.g. from the MenuScene to the HighScoreScene I'm trying to clean up the resources from the old Scene.
But cleaning up the resources seems not to work.
So here is my code which is getting executed when the user is switching between scenes:
So in the old Scene I have this animation loop:
function cancelAnimation() {
cancelAnimationFrame(animationFrameId); // EXECUTING WHEN SWITCHING SCENE!!!
}
function animate() {
animationFrameId = requestAnimationFrame(animate); // Saving id
render();
}
function render() {
renderer.clear();
renderer.render(scene, camera);
}
So when switching the scene I unset all click listeners and I'm calling cancelAnimation.
Because I'm storing that code for each Scene in an object like var menuScene = new MenuScene() I'm also doing this menuScene = undefined when switching the scene.
I'm also passing the same instance of var renderer = new THREE.WebGLRenderer(); to the scenes.
This all seems not to help the game is executing more slowly.
What is the proper way to switch between those scenes and clearing up the resources? What am I doing wrong here?
I'm a three.js beginner. I'm attempting to add a sphere to the scene, using position coordinates returned from a JavaScript get request.
A sphere created before the get request is rendered properly, but a sphere created and added to the scene in the callback function is not rendered - although if I debug and inspect the scene, both spheres exist as its children.
My code:
var sphere = new THREE.Mesh(
new THREE.SphereGeometry(radius),
sphereMaterial);
sphere.position.set(-20,-20,-20);
scene.add(sphere); // this sphere shows
sphere2 = sphere.clone();
sphere2.position.set(50,50,50); // testing initializing outside
$.get("{% /graph %}",function(data,status){
scene.add(sphere2); // this sphere does not show
});
renderer.render(scene, camera);
I tried initializing the second sphere inside and outside the callback, I've tried creating the new sphere instead of cloning, I'm not sure what else to try and I don't know what I'm missing.
The jQuery get request is an asynchronous request. The callback function will not be called until after the render call. This means that the object will get added to the scene, but never drawn.
You will need to call the render function inside the get handler.
$.get("{% /graph %}",function(data,status){
scene.add(sphere2);
renderer.render(scene, camera);
});
Alternately, if you create a rendering loop for things like animation, this is unnecessary.
I am converting flash to html5 files using createjs; in our flash we are having 5 scenes. After completing one scene we have to load the other scene.
For each scene we have one js file. For the first scene I am loading the first js file; for the second scene I have to load the second js file. I am unable to know when the first is going to be complete.
Cant you just call a function when the tween is complete?
var tween = new cretejs.Tween();
tween.get( target).to({x: some_x}).call( onTweenComplete);
function onTweenComplete(){
//Tween is done
}