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.
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
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);
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);
Related
I'm using a three VideoTexture in my R3F App. Unfortunatly its not gamma corrected so my video seems washed out. I tried setting the encoding to sRGBEncoding for my texture, but that doesn't seem to do anything. Also there is nothing about encoding in the three docs of videotexture.
How can i set RGBEncoding on VideoTextures?
thanks in advance.
Here is my texture:
import {
MeshStandardMaterial,
VideoTexture,
sRGBEncoding,
} from "three";
const textureVid = document.createElement("video");
textureVid.src = "assets/video/test.mp4";
textureVid.play();
const videoTexture = new VideoTexture(textureVid);
videoTexture.encoding = sRGBEncoding;
const matTVScreen = new MeshStandardMaterial({
color: 0x000000,
map: videoTexture,
});
So basically my code was right. I had to delete my Browser cache to see these changes.
Assign the material from the video tag to the Mesh and get an inverted video. Before that, this place had a texture with the correct orientation. What can this be related to? I've have this problem when I switched from loading models in GLTF format
material = new MeshPhysicalMaterial();
const video = document.getElementById('myvideo');
video.play();
material.map = new VideoTexture(video);
material.map.format = RGBFormat;
http://prntscr.com/t4ldyf
If your texture is showing up vertically inverted, you can flip it with the Texture.flipY property. The default value is true, so try setting it to false.
material.map = new VideoTexture(video);
material.map.format = RGBFormat;
material.map.flipY = false;
I am new to three js. i want to display a video on plane Geometry . i tried with the following code but it is showing a blank web page with out any errors
var video = document.getElementById('video');
video.src = "***VIDEO URL***";
video.load();
video.play();
var texture = new THREE.VideoTexture(videoImage);
texture.needsUpdate;
texture.minFilter = THREE.LinearFilter;
texture.magFilter = THREE.LinearFilter;
texture.format = THREE.RGBFormat;
texture.crossOrigin = 'anonymous';
var meshPlace = new THREE.Mesh(
new THREE.PlaneGeometry(USE_WIDTH, USE_HEIGHT , 40),
new THREE.MeshBasicMaterial({ map: texture }),);
scene.add( meshPlace );
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
I fount this on Using Video as texture with Three.js
Hope this helps :)
I'm trying the second approach to use Text in three.js, drawing on a canvas and using the result as a texture. It basically works, except for the following problem -don't know if it's a bug:
I create two texts, with transparent background, and overlap then. They show ok, but when I rotate one of them, the transparency is messed up.
I create the text objects with following (excerpt) function
function createText(text, ...){
var textHolder = document.createElement( 'canvas' );
var ctext = textHolder.getContext('2d');
...
var tex = new THREE.Texture(textHolder);
var mat = new THREE.MeshBasicMaterial( { map: tex, overdraw: true});
mat.transparent = true;
mat.map.needsUpdate = true;
var textBoard = new THREE.Mesh(new THREE.PlaneGeometry(textHolder.width, textHolder.height),mat);
textBoard.dynamic = true;
textBoard.doubleSided = true;
return textBoard;
}
and add them to the scene.
See demonstration with full code in jsfiddle
Transparency is tricky in webGL.
The best solution in your case is to do the following for your transparent text material:
mat.depthTest = false;
updated fiddle: http://jsfiddle.net/SXA8n/4/
three.js r.55
How to use THREE.ImageUtils.loadTexture() in jsfiddle. I have created a demo [ http://jsfiddle.net/georgeneil/cfrsj/10/ ]. Here I am not able to view the texture. I am getting the points rendered as black.
You can base64 encode the image. And then add the string in your code.
Updated jsfiddle: http://jsfiddle.net/cfrsj/11/
The problem is you cannot use a texture that is hosted externally. Here is some code I created to put a texture on a plane. I believe I adapted this code from one of mr doob's projects:
img = new Image();
texture = new THREE.Texture(img);
img.onload = function() {
texture.needsUpdate = true;
makeParticle();
};
img.src = "http://www.aerotwist.com/tutorials/creating-particles-with-three-js/images/particle.png";
geometry = new THREE.PlaneGeometry( 438, 695, 200 );
material = new THREE.MeshBasicMaterial( {map: texture} );