经纬志
首页 / luma.gl / API 文档

ExternalTexture

先看结论

浏览器外部图像的绑定快照:视频帧、VideoFrame 等对象不拷贝像素, 直接作为纹理参与采样。

最后验证 2026-11-03 · luma.gl 9.4 · 更新 2026-10-29 · 引用本文
device.createExternalTexture({ source, sampler }) → ExternalTexture

创建参数

参数说明
source视频元素或 VideoFrame
width / height无法从 source 推断尺寸时的显式宽高
samplerSampler 或采样参数,作为默认采样器
colorSpacesrgb,导入浏览器图像时的色彩空间
id调试标识

成员

成员说明
width / height图像尺寸
sampler当前默认采样器
updateTimestamp内容更新时间戳,用于判断是否需要重绘
handle底层绑定句柄
props创建参数
destroyed是否已释放

方法

方法返回说明
setSampler(sampler)this替换采样器,接受实例或参数对象
destroy()void释放绑定,不操作源视频

视频纹理

const video = document.querySelector('video');
await video.play();

const videoTexture = device.createExternalTexture({
  source: video,
  sampler: {
    minFilter: 'linear',
    magFilter: 'linear',
    addressModeU: 'clamp-to-edge',
    addressModeV: 'clamp-to-edge'
  }
});

const model = new Model(device, {
  vs: screenVS,
  fs: screenFS,
  bindings: {
    uVideo: videoTexture,
    uVideoSampler: videoTexture.sampler
  },
  vertexCount: 6,
  topology: 'triangle-list'
});

外部纹理的绑定名与配对的采样器名需要成对出现: uVideo 配 uVideoSampler, 与着色器里声明的采样器 uniform 名称保持一致。

逐帧更新

视频播放时纹理内容随之变化,但对象本身不用重建。 每一帧检查 updateTimestamp,变化后再重绘, 避免在没有新帧时做无意义的渲染。

let lastStamp = -1;

function frame() {
  if (videoTexture.updateTimestamp !== lastStamp) {
    lastStamp = videoTexture.updateTimestamp;

    const pass = device.beginRenderPass({ clearColor: [0, 0, 0, 1] });
    model.draw(pass);
    pass.end();
    device.submit();
  }

  requestAnimationFrame(frame);
}

frame();

与普通纹理的选择

场景用哪个
视频、摄像头流ExternalTexture,零拷贝
静态图片、需要 mipmapTexture + copyExternalImage
需要反复读写像素Texture,外部纹理不提供回读

视频必须在播放状态。 暂停或尚未加载元数据的视频尺寸为 0,创建出的纹理无法采样。 等 loadedmetadata 后再创建,或在创建时显式给出 width 与 height。

引用本文

经纬志(2026)。《ExternalTexture》。https://www.jingweizhi.com/lumagl/api/external-texture.html(访问日期 2026-11-03)。