前情回顾
上一篇我们大致了解了Threejs中的纹理加载器
(TextureLoader)
的大致使用方法,纹理最基础的用法就是在材质上贴图,将图片通过THREE.TextureLoader
加载,然后设置为材质的map
属性。
视频作为Three.js纹理贴图(VideoTexture)
视频本质上就是一帧帧图片流构成,把视频作为Threejs模型的纹理贴图使用,就是从视频中提取一帧一帧的图片作为模型的纹理贴图,然后不停的更新的纹理贴图就可以产生视频播放的效果。
实现效果如下:1.mp4(5 MB)
1. 创建video播放器
<video id="video" autoplay controls loop> <source src="../assets/v.mp4" /></video>
2. 获取video对象,使用 VideoTexture 来加载video对象实例化纹理,然后设置为网格模型材质对象的map
属性
//获取到video对象var video = document.querySelector("#video"); //通过video对象实例化纹理var texture = new THREE.VideoTexture(video);texture.wrapS = texture.wrapT = THREE.ClampToEdgeWrapping;texture.minFilter = THREE.LinearFilter; // 几何体材质对象var material = new THREE.MeshLambertMaterial({ map: texture});
当然了,创建一个三维场景是必不可少的步骤(场景,相机,渲染器)
完整代码如下:
<template> <div> <div ref="content"></div> <video id="video" autoplay controls loop> <source src="../assets/v.mp4" /> </video> </div></template> <script>// 引入threejsimport * as THREE from "../../public/build/three";//鼠标控制import { OrbitControls } from "../../public/example/jsm/controls/OrbitControls.js"; export default { components: {}, data() { return { // 创建一个场景 scene: null, // 创建一个相机 camera: null, // 创建一个渲染器 renderer: null, // 模型对象 mesh: null, // 平面 plane: null, // 点光源 point: null, // step step: 0 }; }, mounted() { this.init(); }, methods: { // 初始化 init() { // 初始化容器 var content = this.$refs.content; // 创建一个场景 this.scene = new THREE.Scene(); this.scene.background = new THREE.Color("#000"); // 创建几何体 var geometry = new THREE.BoxGeometry(100, 50, 50); //获取到video对象 var video = document.querySelector("#video"); //通过video对象实例化纹理 var texture = new THREE.VideoTexture(video); texture.wrapS = texture.wrapT = THREE.ClampToEdgeWrapping; texture.minFilter = THREE.LinearFilter; // 几何体材质对象 var material = new THREE.MeshLambertMaterial({ map: texture }); // 创建网格模型对象 this.mesh = new THREE.Mesh(geometry, material); //设置几何体位置 this.mesh.position.x = 0; this.mesh.position.y = 10; this.mesh.position.z = 0; this.scene.add(this.mesh); // 创建点光源 var point = new THREE.PointLight("#FFF"); point.position.set(40, 200, 300); this.point = point; this.scene.add(point); const sphereSize = 10; const pointLightHelper = new THREE.PointLightHelper(point, sphereSize); this.scene.add(pointLightHelper); //创建环境光 var ambient = new THREE.AmbientLight(0x444444); this.scene.add(ambient); // 创建一个相机 this.camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 10000 ); this.camera.position.set(0, 0, 200); this.camera.lookAt(0, 0, 0); //坐标轴辅助器,X,Y,Z长度30 // var axes = new THREE.AxesHelper(300); // this.scene.add(axes); // 辅助网格 // let gridHelper = new THREE.GridHelper(100, 100); // this.scene.add(gridHelper); // 创建渲染器 this.renderer = new THREE.WebGLRenderer({ antialias: true }); this.renderer.setSize(window.innerWidth, window.innerHeight); this.renderer.setClearColor(0xb9d3ff, 1); //插入 dom 元素 content.appendChild(this.renderer.domElement); let controls = new OrbitControls(this.camera, this.renderer.domElement); controls.addEventListener("resize", this.render(), false); }, render() { this.renderer.render(this.scene, this.camera); // 自动旋转动画 this.mesh.rotateX(0.01); // this.render requestAnimationFrame(this.render); } }};</script> <style lang="scss" scoped>#video { position: fixed; top: 0; left: 0; width: 300px; height: 200px;}</style>
本人,某个不知名小公司的前端小菜鸡,由于技术太菜,业余时间总是喜欢捣鼓一些花里胡哨的东西,一边学习一边分享,希望能够和大家一起成长,梦想着成为一位前端大大牛。