首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

微信小程序xr-frame透明视频实现

  • 25-03-07 21:22
  • 3955
  • 5652
blog.csdn.net

请添加图片描述

在开发AR小程序的时候需要实现用到透明视频效果。这里使用MP4格式的视频。它的左侧为视频的rgb通道信息,右侧为动画alpha通道信息,左右两侧动画同步播放。
在这里插入图片描述

关于透明视频制作的方法:

之前在unity中使用过这种MP4视频,测试时放到小程序中也可以共用。

客户或美术提供带有alpha通道的MOV视频,再使用ffmpeg代码转换。或者AE处理也可以,但是个人感觉用代码更方便一些。

ffmpeg -i b.mov -vf "split [a], pad=iw*2:ih [b], [a] alphaextract, [b] overlay=w" -c:v libx264 -crf 18 -preset veryfast -pix_fmt yuv420p -movflags +faststart -y output-lr-mov.mp4
  • 1

MOV导出时的注意事项:

  • 使用 ProRes4444 这类支持透明度的编解码器
  • 要选择"straight" alpha 模式(而不是 “premultiplied”)

小程序代码

Components/index.js

Component({
  behaviors: [require('../common/share-behavior').default],
  properties: {
    a: Number,
  },
  data: {
    loaded: false,
    arReady: false,
  },
  lifetimes: {
    async attached() {
      console.log('data', this.data)
      // Add the effect registration here
      const xrFrameSystem = wx.getXrFrameSystem();
      
      function createVideoTsbsEffect(scene) {
        return scene.createEffect({
          "name": "video-tsbs",
          "properties": [{
            "key": "u_baseColorFactor",
            "type": 3,
            "default": [1, 1, 1, 0]
          }],
          "images": [{
            "key": "u_baseColorMap",
            "default": "white",
            "macro": "WX_USE_BASECOLORMAP"
          }],
          "defaultRenderQueue": 3000,
          "passes": [{
            "renderStates": {
              "cullOn": false,
              "blendOn": true,
              "depthWrite": true,
              "cullFace": 2
            },
            "lightMode": "ForwardBase",
            "useMaterialRenderStates": true,
            "shaders": [0, 1]
          }],
          "shaders": [
            `#version 100
            precision highp float;
            attribute vec3 a_position;
            attribute vec2 a_texCoord;

            uniform mat4 u_projection;
            uniform mat4 u_world;
            uniform mat4 u_view;
            varying highp vec2 vTextureCoord;
            
            void main()
            {
              vTextureCoord = a_texCoord;
              gl_Position = u_projection * u_view * u_world * vec4(a_position,1.0);
            }`,
            `#version 100
            precision highp float;

            uniform highp vec4 u_baseColorFactor;
            #ifdef WX_USE_BASECOLORMAP
              uniform sampler2D u_baseColorMap;
            #endif

            varying highp vec2 vTextureCoord;

            void main()
            {
          #ifdef WX_USE_BASECOLORMAP
            vec4 color = texture2D(u_baseColorMap, vec2(vTextureCoord.x*0.5,vTextureCoord.y));
            vec4 colora = texture2D(u_baseColorMap, vec2(vTextureCoord.x*0.5 + 0.5,vTextureCoord.y));

              vec4 baseColor = vec4(color.xyz,colora.x);
          #else
              vec4 baseColor = u_baseColorFactor;
          #endif

            gl_FragData[0] = baseColor;
            }  
          `
          ]
        })
      }
      
      xrFrameSystem.registerEffect("video-tsbs", createVideoTsbsEffect);
    }
  },
  methods: {
    handleReady({detail}) {
      const xrScene = this.scene = detail.value;
      console.log('xr-scene', xrScene);
      
      
      this.triggerEvent('sceneReady', { value: xrScene });
    },
    handleAssetsProgress: function({detail}) {
      console.log('assets progress', detail.value);
    },
    handleAssetsLoaded: function({detail}) {
      console.log('assets loaded', detail.value);
      this.setData({loaded: true});
    },
    handleARReady: function({detail}) {
      console.log('arReady', this.scene.ar.arVersion);
    },
    
    showModel() {
      console.log('showModel called');
      if (this.scene) {
        
        const modelNode = this.scene.getNodeById('setitem');
        
        
        console.log('模型节点:', modelNode);
        
        if (modelNode) {
          console.log('找到模型,设置为可见');
          modelNode.visible = true;
        } else {
          
          const allNodes = this.scene.children;
          console.log('所有节点:', allNodes);
        }
      } else {
        console.log('场景未初始化');
      }
    }
    
  }
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130

Components/index.wxml

这里要把src="你的视频.mp4"这里改为你的视频URL


  
    
  
  
	
  
    
    
    
    
    
  
  
  
    
    
  



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

Pages/index.js

var sceneReadyBehavior = require('../../behavior-scene/scene-ready');
var handleDecodedXML = require('../../behavior-scene/util').handleDecodedXML;

Page({
  behaviors:[sceneReadyBehavior],
  data: {
    renderWidth: 0,
    renderHeight: 0,
    width: 0,
    height: 0,
    top: 0,
    left: 0
  },
  
  onLoad: function() {
    const info = wx.getWindowInfo();
    
    
    this.setData({
      renderWidth: info.screenWidth,
      renderHeight: info.screenHeight,
      width: info.screenWidth,
      height: info.screenHeight,
      top: 0,
      left: 0
    });
  },

  handleSceneReady: function(e) {
    console.log('handleSceneReady called');
    this.scene = e.detail.value;
  },

  handleConfirmPosition: function() {
    console.log('handleConfirmPosition called');
    const arComponent = this.selectComponent('#main-frame');
    console.log('arComponent:', arComponent);
    if (arComponent) {
      arComponent.showModel();
    }
  }
});


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

Pages/index.wxml


   
  确认位置

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
嘟嘟实验室
微信公众号
不定期分享技术文章!
注:本文转载自blog.csdn.net的嘟嘟实验室的文章"https://blog.csdn.net/weixin_43935971/article/details/144612778"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

119
小程序
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top