0

How to know three js material rendered finished?

  1. I not have texture URL, i have only a canvas element.
  2. It's not about loading texture , it's about rendering texture.
material.map = new THREE.Texture( canvas ); 
material.map.needsUpdate = true;

so I want to do something because if not then it is complete snapshot is sometime black result

var snapshotData = renderer.domElement.toDataURL(strMime);

What can be do successfully rendered material callback?

Sorry for my bad english. Actually I it's not about loading texturePath, it's about rendering texture. What I really want is how to know when rendering texture is finished.

For example, texture is already loaded but not yet rendered in mesh. What can be do successfully rendered material callback?

Thank you for your helps guys.

  • I can only guess what your problem is. It is better to show all your code or link to a live example that demonstrates the problem... (1) Does `renderer = new THREE.WebGLRenderer( { preserveDrawingBuffer: true } );` solve the problem? (2) Or, instead, does calling `render()` immediately before taking snapshot work?: `render(); var snapshotData = renderer.domElement.toDataURL( strMime );` – WestLangley Dec 09 '16 at 15:24
  • Hello, Thank you for answer me and sorry for my bad english. Yes my rendering code look like renderer = new THREE.WebGLRenderer( { preserveDrawingBuffer: true } ); Actually I it's not about snapshot and not about loading texture. It's about rendering texture for mesh. (material.map.needsUpdate = true;) this command not running while browser inactive, is it bug? because when web browser tab inactive not working snapshot data. – М. Түвшин - заяа Dec 10 '16 at 04:34
  • Sorry, if your question is about inactive browser tabs, then I am not the right person to comment. – WestLangley Dec 10 '16 at 17:19
  • Inactive browser tabs are irrelevant. The moment you render with three.js your texture will be updated to the contents of the canvas. I'm guessing the problem is likely you're not calling `renderer.render` directly when you're finished setting up your texture. Instead you're using `requestAnimationFrame` which will not get called when your tab is inactive. There is no magic. Setting a texture and setting `needsUpdate` does absolutely nothing until you call `renderer.render`. So, you must *manually* call `renderer.render` as shown in the examples below. – gman Dec 11 '16 at 10:03

1 Answers1

0

Materials in three.js get updated when they are used in a rendered scene. You can render a scene at anytime with

renderer.render(someScene, someCamera);

As for calling toDataURL and getting black see these answers

https://stackoverflow.com/a/32641456/128511

https://stackoverflow.com/a/26790802/128511

Effectively though you should be able to do this

renderer.render(someScene, someCamera);
var snapshotData = renderer.domElement.toDataURL(strMime);

If the texture is based on a canvas then it is available as soon as you call renderer.render(...).

"use strict";

var renderer = new THREE.WebGLRenderer();

var camera = new THREE.PerspectiveCamera(70, 300/150, 1, 1000);
camera.position.z = 75;
var scene = new THREE.Scene();

var geometry = new THREE.BoxGeometry(50, 50, 50);

var ctx = document.createElement("canvas").getContext("2d");
ctx.canvas.width = 128;
ctx.canvas.height = 128;

ctx.fillStyle = "red";
ctx.fillRect(0, 0, 128, 128);
ctx.beginPath();
ctx.arc(64, 64, 40, 0, Math.PI * 2, true);
ctx.lineWidth = "10";
ctx.strokeStyle = "yellow";
ctx.stroke();

var texture = new THREE.Texture(ctx.canvas);
texture.needsUpdate = true;
var material = new THREE.MeshBasicMaterial({
  map: texture,
});

var mesh = new THREE.Mesh(geometry, material);
mesh.rotation.y = 45;
mesh.rotation.x = Math.PI * .2;
scene.add(mesh);

renderer.render(scene, camera);
var img = new Image();
img.src = renderer.domElement.toDataURL();
document.body.appendChild(img);
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r79/three.min.js"></script>

Be aware that by default, in three.js you can only use a canvas for 1 texture. If you want use a canvas for 2 textures you need either 1 canvas per texture OR you need to manually force Three.js to update the texture. See this answer

Community
  • 1
  • 1
gman
  • 100,619
  • 31
  • 269
  • 393
  • // the code below executes only after the texture is successfully loaded mesh.material.map = texture; mesh.needsUpdate = true; // mesh.material.map = texture; => it is successfully set to material. But this texture not rendering on mesh not yet. Because tab was inactive. Main problem is i need ready state of texture for rendered on mesh. //write the code to be executed after the texture is mapped but browser tab inactive not working needsUpdate – М. Түвшин - заяа Dec 10 '16 at 04:36