Reputation: 1088
I am trying to create a simple rectangle with a .mp4 video as texture. As per three.js documentation(http://threejs.org/docs/#Reference/Textures/Texture) this should be straight forward.
When I am putting link of video, all I am getting is a black colored box with no texture on it. I have tested code by replacing video with a jpg image and it works fine. Can someone please explain me what I am doing wrong.
I have already seen the examples in which video is played by first linking it to a video element and then copy the frames on a canvas. I want to try the direct way as mentioned in the three.js documentation.
Upvotes: 7
Views: 29534
Reputation: 391
I spent hours on this, trying to make things work, but nothing worked no matter what I tried. Always a black texture. In the end, it turns out the culprit was display: none
on the video element. All of the above code solutions are valid, but it is very important that you do not set the HTML video element itself to display: none
, otherwise the browser may optimize it and avoid loading the video. The solution to this was to remove the display
tag from the CSS, and instead set opacity
to 0%. Theoretically, the browser may also decide to not render this, so you may need to set opacity to 1% and hide it behind a div if that doesn't work.
Upvotes: 0
Reputation: 45382
In addition to Haos' answer, I needed to set videoTexture.needsUpdate = true;
and videoMaterial.needsUpdate = true;
. Also I've played the video on onloadeddata
.
//Get your video element:
const video = document.getElementById("video");
video.onloadeddata = function () {
video.play();
};
//Create your video texture:
const videoTexture = new THREE.VideoTexture(video);
videoTexture.needsUpdate = true;
const videoMaterial = new THREE.MeshBasicMaterial({
map: videoTexture,
side: THREE.FrontSide,
toneMapped: false,
});
videoMaterial.needsUpdate = true;
//Create screen
const screen = new THREE.PlaneGeometry(10, 10);
const videoScreen = new THREE.Mesh(screen, videoMaterial);
scene.add(videoScreen);
Upvotes: 1
Reputation: 51
Step 1: Add a video to your HTML and "hide" it:
<video id="video" playsinline webkit-playsinline muted loop autoplay width="320" height="240" src="some-video.mp4" style="display: none;"></video>
Step 2:
//Get your video element:
const video = document.getElementById('video');
//Create your video texture:
const videoTexture = new THREE.VideoTexture(video);
const videoMaterial = new THREE.MeshBasicMaterial( {map: videoTexture, side: THREE.FrontSide, toneMapped: false} );
//Create screen
const screen = new THREE.PlaneGeometry(1, 1);
const videoScreen = new THREE.Mesh(screen, videoMaterial);
scene.add(videoScreen);
Upvotes: 5
Reputation: 1489
Think of video as a sequence of images. So to "play" this video on your 3D object - you'll have to pass every single frame of that sequence to your material and then update that material.
Good place to start is here: https://github.com/mrdoob/three.js/wiki/Updates
And here: http://stemkoski.github.io/Three.js/Video.html
Upvotes: 7