普通视图

发现新文章,点击刷新页面。
昨天 — 2026年3月21日首页

微信小程序开发02:原始人也能看懂的着色器与视频处理

作者 海石
2026年3月21日 18:41

往期回顾:

微信小程序开发01:XR-FRAME的快速上手

1、背景

还记得01时,3.3.3章节的成果展示吗?

image.png

虽然图片识别成功了,并且视频加载完毕了

但是视频存在大规模的绿色背景,这是业务不期望展示的

期望的效果是抠除绿色背景,仅保留人物主体,如下图

e1ea2feb31f439a3ea638f80d006b27d.jpg

今天我们就来尝试对视频图层做调整

2、温故知新

为了快速实现MVP,我们忽略了很多信息,但这些信息对我们基于MVP二次开发时,比较重要

我们需要了解一下当前demo工程的结构:

mermaid-1774086497015.png

清晰的分层架构 :

  • Pages 层 (如 xr-template-water/index.wxml ):

    • 负责页面配置和展示
    • 定义标题、介绍等元数据
    • 处理页面级别的交互
  • Components 层 (如 xr-template-water/index.wxml ):

    • 包含实际的 XR 场景逻辑
    • 处理 3D 渲染、AR 追踪等核心功能
    • 实现具体的业务逻辑
  • 共享行为机制 share-behavior.js 的设计 :

    • 提供统一的分享功能实现
    • 统一处理 AR 追踪状态初始化
    • 减少重复代码,提高一致性
    • 被所有 template 组件复用

再来看看数据流向:

用户交互
    │
    ▼
Pages 层 (页面配置)
    │
    ▼
xr-demo-viewer (容器组件)
    │
    ├─► 显示 UI (标题、介绍、代码)
    │
    └─► <slot> (主内容)
            │
            ▼
Components/Template (业务组件)
    │
    ├─► share-behavior (共享功能)
    │       │
    │       ├─► 分享初始化
    │       └─► AR 状态管理
    │
    └─► xr-scene (XR 场景)
            │
            ├─► 资源加载
            ├─► 3D 渲染
            └─► AR 追踪

像我们在第一期做的改造,得益于此demo工程的优秀设计,当我们想要新增功能时,只要做4步操作:

  • 创建 pages/template/xr-template-newFeature
  • 创建 components/template/xr-template-newFeature
  • 使用 xr-demo-viewer 包裹
  • 引入 share-behavior 获得共享功能

3、透明视频

ok,接下来我们进入正题,如何让绿幕视频可以扣除绿幕,实现一些付费AR软件提供的功能?

有两条路:

  1. 直接导入微信小程序支持的透明视频
  2. 通过自定义着色器计算每个像素颜色与绿色背景的距离,使用 smoothstep 函数根据距离动态调整透明度,使绿色背景变为透明而其他内容保持不透明。

第一条路需要使用AE等视频处理软件,导出成果,对素材的质量要求较高,也就是对上游有依赖

因此,不想被上游依赖,我们便选择第二条路,自己实现视频扣除纯色背景的功能

况且,XR FRAME本就支持着色器

// XR-Frame 提供的 API
wx.getXrFrameSystem().registerEffect("chroma-key", createChromaKeyEffect);

scene.createEffect({
  "name": "chroma-key",
  "shaders": [vertexShader, fragmentShader]  // 支持 GLSL 着色器
})

ok,写到这里,大家应该还是困惑,着色器和视频有什么关系?

着色器就像一个超级快的修图师,把视频的每一帧图片都检查一遍,把绿色的像素变成透明,然后把处理好的图片贴在3D模型这块"布料"上,纹理材质就是这块布料和修图师的组合

大白话说完,我们来看看处理的过程

我们创建一个新的资源,让它被包裹在xr-assets下,这个新的资源就是我们刚刚提到的“修图师”,它在小程序里的体现就是“材质”,即xr-asset-material

  <xr-assets>
    <xr-asset-load type="video-texture" asset-id="ayuan-video" src="https:/xxxx.mp4" options="autoPlay:true,loop:true" />
    <xr-asset-material asset-id="chroma-key-mat" effect="chroma-key" />
  <xr-assets>

asset-id我们很熟悉了,对应于材质的名字,就和视频的asset-id一样

effect是效果,即材质的模板

通过对effect的设置,我们可以调整光照模式,等等

image.png

"chroma-key"是我们通过scene.createEffect方法创造出来的一种自定义效果

部分源码如下:

function createChromaKeyEffect(scene) {
  return scene.createEffect({
    "name": "chroma-key",  // 给这个修图师起个名字叫"绿幕扣除"
    
    // 定义要用的工具:视频图片
    "images": [{
      "key": "u_baseColorMap",  // 视频纹理的代号
      "default": "white",
      "macro": "WX_USE_BASECOLORMAP"
    }],
    
    // 定义修图规则(着色器代码)
    "shaders": [
      // 第一个着色器:负责把3D模型放到屏幕上
      `顶点着色器...`,
      
      // 第二个着色器:负责给每个像素上色(这里是关键!)
      `片元着色器...
        vec4 color = texture2D(u_baseColorMap, vTextureCoord);  // 取出视频的像素颜色
        
        vec3 greenKey = vec3(0.055, 0.816, 0.294);  // 绿幕的颜色
        float dist = distance(color.rgb, greenKey);  // 算一下这个像素离绿色有多远
        
        float threshold = 0.40;  // 设定一个距离标准
        float alpha = smoothstep(threshold - 0.005, threshold + 0.005, dist);
        // 如果离绿色很近,透明度就变成0(看不见)
        // 如果离绿色很远,透明度就保持1(看得见)
        
        color.a *= alpha;  // 把算好的透明度应用到像素上
      `
    ]
  })
}

写完之后,别忘了在系统中注册,这样之后到处都可以使用

// 在组件加载时执行
lifetimes: {
  async attached() {
    const xrFrameSystem = wx.getXrFrameSystem();
    
    // 把这个修图师注册到系统里,以后可以随时用
    xrFrameSystem.registerEffect("chroma-key", createChromaKeyEffect);
  }
}

然后我们就要把之前的视频,和我们刚刚创建的材质,组合起来

  • 创建一个3D平面模型
  • 给这个模型穿上"chroma-key-mat"这件衣服
  • 把视频"ayuan-video"贴在衣服上
  • 把模型放到场景里
handleARReady: async function ({ detail }) {
  // 创建一个3D平面(就像一块板子)
  const videoPlane = this.scene.createElement(xr.XRMesh, {
    geometry: 'plane',           // 形状:平面
    material: 'chroma-key-mat',  // 材质:用刚才创建的“布料”
    uniforms: 'u_baseColorMap: video-ayuan-video',  // 把视频贴在布料上
    position: '0 0.5 0',      // 位置
    scale: '0.8 0.45 1',      // 大小
  });
  
  // 把这个平面添加到场景中
  lockItemEle.addChild(videoPlane);
}

一句话总结 :代码先创建了一个"绿幕扣除"的修图方案,然后创建一块用这个方案的布料,最后把视频贴在这块布料上,视频的每一帧都会自动被修图师处理,绿色背景就变透明了!

mermaid-1774089305244.png

附录

架构图

mermaid-1774084518187.png

昨天以前首页

微信小程序开发01:XR-FRAME的快速上手

作者 海石
2026年3月16日 02:06

一、前言

最近要基于微信小程序实现一个具备AR功能的APP,在进行技术选型时,发现小程序本身自带了XR-FRAME这个框架,

image.png

从描述上来看:

image.png

没有比它更“合适”的,用来进行AR功能开发的框架了 本来想使用 Vibe Coding 无痛完成开发,但是却在实际使用中,发现大模型写不太来 wxml<xr-...>相关的代码

于是在此开了一个系列文章,用来记录我遇到的坑 😓

二、从 1 到 1.x

个人的建议,一开始不从0到1,而是从1到1.x即基于现有的demo二次开发一个

否则,如果想在学习完下方所有<xr->相关的基础元素,再开始代码编写,着实头疼

image.png

官方文档里提供了扫码即可查看的示例

image.png

不过呢,没放源码的链接,这边我通过github找到了大概就是官方文档示例的源码仓库,地址如下:

dtysky/xr-frame-demo: Demos for xr-frame system in wx-mini-program.

image.png

运行后的效果如下:

image.png

三、动手试试

需求背景:我期望实现一个基础的AR功能,即扫描一张自定义的图片,然后能够出现一个自定义的元素

编码工具:Trae-CN

3.1 如何用【Trae】帮忙编写【微信开发者工具】里的工程代码

习惯了vibe coding后,【微信开发者工具】并不像VSCODE一样,也不能说通过IDEA插件的方式安装AI IDE工具 多少有点寸步难行,真的不想 古法编程 😭


其实很简单,在【微信开发者工具】里新建一个工程之后

image.png

在Trae里打开此工程即可

image.png

image.png

然后Trae里写代码,【微信开发者工具】里负责 编译 即可

3.2 基于现有页面完成自定义改造

我们将刚刚git clone下来的项目的源码直接替换掉新建的示例工程的代码,

image.png 然后运行它,选择下方标签

image.png 然后再选择此功能页

image.png

可以看到,此功能页的实际效果,就符合了我们在本章节初的需求背景

1e49e907220497e2a7e6b6be7a4de161.jpg

扫描具体的某一张图片(鹿的图片),然后出现自定义元素(蝴蝶)

我们快速在源码中定位到相关页面的

image.png

但是却发现怎么JS里面几乎是空的?

image.png

查阅文档后我们明白behaviors有点类似 Vue 中的mixins

image.png 那显然,我们暂时不用关心sceneReadyBehavior中到底有什么

接着看别的文件,我们发现了在JSON中的这个

image.png

一开始我没仔细看,我还纳闷为什么这个组件还要引用自己 😓

image.png

然后才发现这里命名都很一致,不过一个是 pages/... 一个是 components/... 😓

不过也可以取巧,试着🎲赌一下被识别的图片名称和官网示例的链接是一致的

image.png

你还真别说,还真的一致,😀

image.png 这种另辟蹊径的方式,也能帮我这位老眼昏花的人,找到核心JS代码的位置 miniprogram\components\template\xr-template-markerLock\index.js image.png

3.3 资源替换

3.3.1 识别图替换

由于微信小程序对打包上传的代码有严格的大小限制,不超过2MB,

image.png

🙅‍因此图方便使用静态图片放在工程里,走不通

这里我用某云的对象存储解决这个问题,提供一个公有读,私有写的链接即可

不过说个题外话,我发现生成的链接粘贴到浏览器里会触发立刻下载,

image.png

而不是和微信官网示例的鹿的图片一样,可以网页预览

image.png

好奇的同时去学习了一下,发现是 Header 的问题, 我们设置 Content-Dispositioninline 即可实现网页预览了

image.png

3.3.2 展示元素替换

我期望将原来的模型换成视频,这时候就可以利用Tare基于工程上下文去帮我们实现,同样运行demo工程 找到应用视频的页面,定位到源码位置

image.png

image.png

image.png

我们不需要去了解 xr.XRGLTF 切换到 xr.XRMesh 需要注意什么,Trae 会去了解的

3.3.3 成果

微信视频2026-03-16_015939_400 00_00_00-00_00_07.gif

四、总结

在本篇文章,我们实现了最基础的AR功能,在下一篇文章,我们会将模型、视频、图片相结合,实现拥有更多功能的AR页面。

❌
❌