我正在尝试制作视频纹理。我的代码会将视频添加到我的场景中,但我的立方体只是黑色。视频在某处,因为我可以在浏览器中听到音频播放。我是three.js的新手,所以我不确定我做错了什么。我有一个摄像头和三个灯。我可以看到场景中的其他物体,它们的纹理是可见的。我的代码改编自here。这是我的HTML代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script src="libraries/three.js"></script>
<script src="libraries/OBJLoader2.js"></script>
<script src="libraries/OrbitControls.js"></script>
<script src="libraries/MtlLoader.js"></script>
<script src="libraries/DDSLoader.js"></script>
</head>
<body>
<script src="libraries/main.js"></script>
</body>
</html>
这是我的main.js代码:
//global variables
var renderer;
var scene;
var camera;
var cameraControl;
var loader;
var updateFcts = [];
function createRenderer() {
renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0x000000, 1.0);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
}
function createCamera() {
camera = new THREE.PerspectiveCamera(45, window.innerWidth /window.innerHeight, 0.1, 1000);
camera.position.x = 0;
camera.position.y = 100;
camera.position.z = 450;
camera.lookAt(scene.position);
cameraControl = new THREE.OrbitControls(camera);
}
var THREEx = THREEx || {}
THREEx.VideoTexture = function(url){
var video = document.createElement('video');
video.width = 320;
video.height = 240;
video.autoplay = true;
video.loop = true;
video.src = url;
this.video = video;
var texture = new THREE.Texture( video );
this.texture = texture;
this.update = function(){
if( video.readyState !== video.HAVE_ENOUGH_DATA ) return;
texture.needsUpdate = true;
}
this.destroy = function(){
video.pause()
}
}
function createVideo() {
var videoTexture= new THREEx.VideoTexture('models/textures/video.mp4')
var video = videoTexture.video;
updateFcts.push(function(delta, now){
videoTexture.update(delta, now)
});
var geometry = new THREE.CubeGeometry(10,50,10);
var material = new THREE.MeshBasicMaterial({
map : videoTexture.texture,
side: THREE.DoubleSide
});
var mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
updateFcts.push(function(delta, now){
mesh.rotation.x += 1 * delta;
mesh.rotation.y += 2 * delta;
});
}
function createLight() {
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(10, 40, 20);
spotLight.shadowCameraNear = 20;
spotLight.shadowCameraFar = 50;
spotLight.castShadow = true;
scene.add(spotLight);
var ambient = new THREE.AmbientLight( 0x444444 );
ambient.castShadow = true;
scene.add( ambient );
var directionalLight = new THREE.DirectionalLight( 0xffeedd );
directionalLight.position.set( 0, 0.5, 0.5 ).normalize();
scene.add( directionalLight );
}
function init() {
scene = new THREE.Scene();
createRenderer();
createCamera();
createLight();
createVideo();
document.body.appendChild(renderer.domElement);
render();
}
function render() {
cameraControl.update();
renderer.render(scene, camera);
requestAnimationFrame(render);
}
init();
答案 0 :(得分:1)
我遇到过类似的问题:将相机源渲染到纹理会产生黑色物体(黑色纹理)。
在我的情况下,这是因为没有设置texture.needsUpdate = true
。
所以我自己的代码就像:
updateTexture = function(videoDomElement){
var cameraTexture = new THREE.Texture(videoDomElement);
cameraTexture.needsUpdate = true;
var material = new THREE.MeshLambertMaterial({map: cameraTexture});
material.needsUpdate = true;
existingObject.material = material;
}
答案 1 :(得分:0)
您必须为视频创建画布,以便将其用于构建纹理。 此外,您还必须刷新渲染循环中的每一帧。
var renderer;
var scene;
var camera;
var cameraControl;
var loader;
var updateFcts = [];
var video;
var videoImageContext;
var videoTexture;
function createRenderer() {
renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0x111111, 1.0);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
}
function createCamera() {
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.x = 0;
camera.position.y = 100;
camera.position.z = 450;
camera.lookAt(scene.position);
cameraControl = new THREE.OrbitControls(camera);
}
var THREEx = THREEx || {}
THREEx.VideoTexture = function(url) {
video = document.createElement('video');
video.autoplay = true;
video.loop = true;
video.src = url;
video.load();
video.play();
videoImage = document.createElement('canvas');
videoImage.width = 320;
videoImage.height = 240;
videoImageContext = videoImage.getContext('2d');
videoImageContext.fillStyle = '#000000';
videoImageContext.fillRect(0, 0, videoImage.width, videoImage.height);
this.texture = new THREE.Texture(videoImage);
this.texture.minFilter = THREE.LinearFilter;
this.texture.magFilter = THREE.LinearFilter;
this.destroy = function() {
video.pause()
}
}
function createVideo() {
videoTexture = new THREEx.VideoTexture('myvideo.mp4')
updateFcts.push(function(delta, now) {
videoTexture.update(delta, now)
});
var geometry = new THREE.CubeGeometry(10, 50, 10);
var material = new THREE.MeshBasicMaterial({
map: videoTexture.texture,
side: THREE.DoubleSide
});
var mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
updateFcts.push(function(delta, now) {
mesh.rotation.x += 1 * delta;
mesh.rotation.y += 2 * delta;
});
}
function createLight() {
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(10, 40, 20);
spotLight.shadowCameraNear = 20;
spotLight.shadowCameraFar = 50;
spotLight.castShadow = true;
scene.add(spotLight);
var ambient = new THREE.AmbientLight(0x444444);
ambient.castShadow = true;
scene.add(ambient);
var directionalLight = new THREE.DirectionalLight(0xffeedd);
directionalLight.position.set(0, 0.5, 0.5).normalize();
scene.add(directionalLight);
}
function init() {
scene = new THREE.Scene();
createRenderer();
createCamera();
createLight();
createVideo();
document.body.appendChild(renderer.domElement);
render();
}
function render() {
cameraControl.update();
if (video.readyState === video.HAVE_ENOUGH_DATA) {
videoImageContext.drawImage(video, 0, 0);
if (videoTexture)
videoTexture.texture.needsUpdate = true;
}
renderer.render(scene, camera);
requestAnimationFrame(render);
}
init();
我更改了THREEx.VideoTexture函数并渲染循环并使用r75进行了测试并且正常工作!