You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将HTML5播放器视频绘制投影到Unity WebGL的3D平面上

问题解决方案

核心错误点

  • 你错误使用了WebGL2RenderingContext.texImage3D()接口:该接口用于创建三维体积纹理,你要上传的视频帧是普通二维图像,直接使用texImage2D()即可,这是你代码报错的首要原因。
  • 你提到的「本地自有文件无CORS问题」认知有误:如果直接通过file://协议打开HTML文件,就算是本地资源也会触发浏览器的跨源安全限制,抛出安全异常,你需要用本地HTTP服务启动项目访问。

可直接运行的修改后代码

我调整了你的JS逻辑,补充了WebGL纹理初始化的必要步骤,修改后代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WebGL</title>
    <style>
        body {
            background-color: aquamarine;
        }
    </style>
</head>
<body>
    <video muted autoplay width="480" height="270" crossorigin="anonymous">
        <source src="./test.mp4" type="video/mp4" />
    </video>
    <br>
    <canvas width="1080" height="720"></canvas>
    <button onclick="captureVideoFrame()">Capture</button>
    
    <script>
        let gl, videoTexture;
        // 初始化WebGL纹理
        function initGL() {
            const canvas = document.querySelector("canvas");
            gl = canvas.getContext("webgl2");
            // 创建纹理对象
            videoTexture = gl.createTexture();
            gl.bindTexture(gl.TEXTURE_2D, videoTexture);
            // 设置纹理参数,避免非2的幂尺寸视频报错
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
        }

        function captureVideoFrame() {
            const video = document.querySelector("video");
            // 首次调用初始化GL
            if (!gl) initGL();
            
            gl.bindTexture(gl.TEXTURE_2D, videoTexture);
            // 直接上传视频帧到2D纹理
            gl.texImage2D(
                gl.TEXTURE_2D,
                0,
                gl.RGBA,
                gl.RGBA,
                gl.UNSIGNED_BYTE,
                video
            );
            // 这里后续可以加纹理传递给Unity的逻辑
        }

        // 可选:如果要逐帧更新,用requestAnimationFrame自动调用
        function updateFrameLoop() {
            captureVideoFrame();
            requestAnimationFrame(updateFrameLoop);
        }
        // 视频可播放后启动逐帧更新
        document.querySelector('video').addEventListener('canplay', () => {
            updateFrameLoop();
        })
    </script>
</body>
</html>

Unity侧对接说明

你不需要手动操作Unity底层的WebGL上下文,Unity已经提供了对应能力:

  1. 你在Unity中创建一个RenderTexture或者普通2D纹理,把纹理ID传递到JS侧
  2. JS侧可以直接用GLctx.bindTexture(GLctx.TEXTURE_2D, 纹理ID)绑定Unity的纹理,再执行texImage2D上传视频帧即可
  3. 逐帧更新的性能完全达标,1080p@60fps的视频更新不会造成明显性能损耗,浏览器底层对视频帧上传到WebGL纹理有硬件加速优化

HLS适配说明

你计划用hls.js的方案完全可行,只需要在HTML的video标签初始化逻辑中加入hls.js的加载代码即可,不需要修改纹理上传的核心逻辑,视频帧读取的接口是统一的。


内容的提问来源于stack exchange,提问作者verified_tinker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.16 07:54:04