threejs中除了能把图片作为纹理进行几何体贴图以外,还可以把视频作为纹理进行贴图设置。纹理的类型有很多,我们可以用不同的加载器来加载,而对于视频作为纹理,我们需要用到今天的主角:VideoTexture。我们先看效果:
我们直接看代码:
<template>
<div>
</div>
</template>
<script setup>
import { ref } from "vue";
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import * as Dat from "dat.gui";
const gui = new Dat.GUI();
const scene = new THREE.Scene();
const camara = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
camara.position.set(0, 0, 10);
const Gemertry = new THREE.BoxGeometry(5, 5, 5);
//视频加载器
let video = document.createElement("video");
video.src = "/src/assets/819.mp4";
video.load();
video.crossOrigin = "anonymous";
document.addEventListener("click", () => {
video
.play()
.then(() => {
render();
})
.catch(err => {
console.log("err:", err);
});
});
// video.play();
let texture = new THREE.VideoTexture(video);
texture.minFilter = THREE.LinearFilter;
texture.magFilter = THREE.LinearFilter;
const materials = [
new THREE.MeshBasicMaterial({ color: "#f90" }),
new THREE.MeshBasicMaterial({ map: texture }),
new THREE.MeshBasicMaterial({ color: "#63a" }),
new THREE.MeshBasicMaterial({ color: "#e2d" }),
new THREE.MeshBasicMaterial({ color: "#c57" }),
new THREE.MeshBasicMaterial({ color: "#f00" })
];
const cube = new THREE.Mesh(Gemertry, materials);
scene.add(cube);
// 将网格对象添加到场景中
const renderer = new THREE.WebGLRenderer();
document.body.appendChild(renderer.domElement);
renderer.setSize(window.innerWidth, window.innerHeight);
const control = new OrbitControls(camara, renderer.domElement);
const render = () => {
renderer.render(scene, camara);
requestAnimationFrame(render);
if (video.readyState === video.HAVE_ENOUGH_DATA) {
texture.needsUpdate = true;
}
};
render();
</script>
<style scoped>
</style>
这里特别要注意:对于视频而言。很多浏览器禁止了默认播放,所以这里我们通过给文档对象添加点击事件来实现,然后在加载成功的回调中我们要重新调用我们的render()函数。