Three.js: Editor: Texture map doesn't render when refresh web page in Chrome

Created on 31 Oct 2018  路  12Comments  路  Source: mrdoob/three.js

Texture map doesn't render when refresh web page in Chrome, but this problem doesn't reappear in Firefox

Three.js version
  • [x] Dev
  • [x] r97
  • [ ] ...
Browser
  • [ ] All of them
  • [x] Chrome 70
  • [ ] Firefox 63
OS
  • [x] Windows

refresh page and mouse hover model before:
image
refresh page and mouse hover model after:
image

Bug Editor

All 12 comments

I can confirm this bug. When reloading, the texture does only render if you transform the camera with the controls. There is also the following warning logged:

THREE.WebGLRenderer: Texture marked for update but image is incomplete

I think the problem is that ObjectLoader.parse() sets Texture.needsUpdate too early. And since Editor.fromJSON() is synchronous and does not apply an onLoad() callback to ObjectLoader.parse(), the editor does not wait until the texture resources are ready.

I also started having the same problem with my old code, which is not waiting that video element is ready before starting to draw scene.

Works on firefox, but prints console errors on latest Chrome/Canary

WebGL: INVALID_VALUE: tex(Sub)Image2D: video visible size is empty

https://codepen.io/elhigu/pen/pozNRNa

Documentation doesn't say anything that user should wait for video to be loaded before starting render loop. https://threejs.org/docs/#api/en/textures/VideoTexture

So is this a bug in library or missing documentation or am I just doing something wrong?

Or should I maybe open a separate issue for this?

It seems your issue has nothing to do with three.js. At least on Chrome you can't just load and play a video with sound. This violates a security policy. As demonstrated in the example, you have to start the video after a user interaction. Or you just mute the video like demonstrated in this fiddle:

https://jsfiddle.net/ugm03821/

@Mugen87 thanks! That seems to be the reason why it doesn't load. Strangely it seems to work every now and then even when video element is started with autoplay and not being muted.

Is there a way to initialize video texture in a way that playback in not started? If I create element without autoplay in a way that first frame is loaded anyways? just calling videoElement.load() didn't seem to work.

Right now only workaround I have found is to initialize the video like this:

  const videoElement = document.createElement('video');
  videoElement.src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/175382/SampleVideo_1280x720_1mb.mp4";
  videoElement.crossOrigin = 'anonymous';
  videoElement.loop = true;
  videoElement.muted = true;
  videoElement.play().then(() => {
    videoElement.pause();
    videoElement.muted = false;
  });

In our use case we actually need should just load video texture that is not playing, but is still rendered.

Also this seems to be able to "autoplay" video without user interaction in chrome:

  videoElement.play().then(() => {
    videoElement.pause();
    videoElement.muted = false;
  }).then(() => videoElement.play());

Chrome bug maybe if unmuted autoplay should not work without user interaction? 馃 I updated https://codepen.io/elhigu/pen/pozNRNa with unmuted autoplay workaround.

EDIT: ok this didn't work if I created new tab running the code. It threw DOMException 馃憤

Is there a way to initialize video texture in a way that playback in not started?

I would say just don't set autoplay to true and avoid to call videoElement.play().

I would say just don't set autoplay to true and avoid to call videoElement.play().

That way I get the WebGL: INVALID_VALUE: tex(Sub)Image2D: video visible size is empty error 馃槬 to console.

https://codepen.io/elhigu/pen/OJLbgdj

If you want avoid the warning, I suggest you create the texture when you actually want to playback the video.

If you want avoid the warning, I suggest you create the texture when you actually want to playback the video.

Well... in that case I wouldn't be able to show first frame of stopped video before starting playback.

Anyways

  const videoElement = document.createElement('video');
  videoElement.src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/175382/SampleVideo_1280x720_1mb.mp4";
  videoElement.crossOrigin = 'anonymous';
  videoElement.loop = true;
  videoElement.muted = true;
  videoElement.play().then(() => {
    videoElement.pause();
    videoElement.muted = false;
  });

workaround does exactly what is needed without errors.

in that case I wouldn't be able to show first frame of stopped video before starting playback.

I was not aware that you want to show the first frame, sry.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

akshaysrin picture akshaysrin  路  3Comments

jack-jun picture jack-jun  路  3Comments

boyravikumar picture boyravikumar  路  3Comments

jlaquinte picture jlaquinte  路  3Comments

filharvey picture filharvey  路  3Comments