首先,你需要一个这样的视频
或者一个这样的视频
webgl渲染可以用three.js,上下叠加的代码如下:
import * as THREE from 'three'; let videoWidth = 540; //视频实际的宽度 let videoHeight = 540;//原视频实际的高度的一般 //定义渲染器 var renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); renderer.setPixelRatio(window.devicePixelRatio); renderer.setClearColor(new THREE.Color("lightgrey"), 0); renderer.setSize(videoWidth, videoHeight); //居中显示 // renderer.domElement.style.position = "absolute"; renderer.domElement.style.top = (window.innerHeight - videoWidth) / 2 + "px"; renderer.domElement.style.left = (window.innerWidth - videoWidth) / 2 + "px"; // renderer.domElement.style.backgroundColor = "#999"; // canvas的背景图 // renderer.domElement.style.backgroundImage = "url('./images/6b4b2ec4_E812211_16ce1ab6.jpg')"; document.body.appendChild(renderer.domElement); var scene = new THREE.Scene(); var camera = new THREE.Camera(); scene.add(camera); //播放视频 var video = document.getElementById("video"); video.onended = () => { video.play(); } //获取视频纹理 var texture = new THREE.VideoTexture(video); texture.minFilter = THREE.LinearFilter; texture.magFilter = THREE.LinearFilter; texture.format = THREE.RGBAFormat; //定义几何体 var geometry = new THREE.PlaneBufferGeometry(2, 2); //处理视频纹理 var uniforms = { time: { type: "f", value: 1.0 }, videoTexture: { type: "sampler2D", value: texture } }; var material = new THREE.ShaderMaterial({ uniforms: uniforms, vertexShader: `varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }`, fragmentShader: `#ifdef GL_ES precision highp float; #endif uniform float time; uniform sampler2D videoTexture; varying vec2 vUv; void main( void ) { gl_FragColor = vec4( texture2D(videoTexture, vec2(vUv.x, 0.5 + vUv.y/2.)).rgb, texture2D(videoTexture, vec2(vUv.x, vUv.y/2.)).r ); }`, // 通过视频的rgb值,转换成webGl渲染需要的rgba值 // vec4是取样器获取的是值对应的是(r,g,b,a) // texture2D是取样器获取的是视频的rgb值,可以通过.r,.g,.b或者.rg,.rb,.gb,.rgb分别取样 // vUv传入的是纹理的坐标(浮点数) transparent: true }); var mesh = new THREE.Mesh(geometry, material) scene.add(mesh); var animate = function () { requestAnimationFrame(animate); renderer.render(scene, camera); }; // document.getElementById('play-button').addEventListener('click', e => { // video.play(); // requestAnimationFrame(animate); // }); video.play(); requestAnimationFrame(animate);
如果是左右,只需要改一下叠加的方向就行,代码中的 fragmentShader 属性改为如下:
fragmentShader: `#ifdef GL_ES precision highp float; #endif uniform float time; uniform sampler2D texture; varying vec2 vUv; void main( void ) { gl_FragColor = vec4( texture2D(texture, vec2(vUv.x/2., vUv.y)).rgb, texture2D(texture, vec2(vUv.x/2., vUv.y)).r ); }`,
以上解决视频背景透明问题
参考原文:前端如何制作出透明背景视频
标签:视频,threeJS,渲染,webgl,THREE,vUv,renderer,var,new From: https://www.cnblogs.com/hyt09/p/17445435.html