1
+ const xrFrameBehavior = Behavior ( {
2
+ yuvMat : undefined , // yuv纹理
3
+ yuvMatInit : undefined , // yuv纹理是否已经初始化
4
+ DT : undefined , // 缓存displayMatrix
5
+ methods : {
6
+ // xrScene Ready 事件回调
7
+ handleXRSceneReady ( detail ) {
8
+ console . log ( 'handleXRSceneReady' , detail ) ;
9
+ const xrFrameSystem = wx . getXrFrameSystem ( ) ;
10
+
11
+ this . xrCamera = detail . detail . camera ;
12
+ this . xrCameraTrs = this . xrCamera . el . getComponent ( xrFrameSystem . Transform ) ;
13
+ this . xrScene = detail . detail . scene ;
14
+ this . xrFrameReady = true ;
15
+ if ( this . initXRFrame ) {
16
+ this . initXRFrame ( ) ;
17
+ }
18
+ } ,
19
+ // 绑定自定义 YUV effect
20
+ registerYUVEffect ( ) {
21
+ const xrFrameSystem = wx . getXrFrameSystem ( ) ;
22
+ xrFrameSystem . registerEffect ( 'ar-yuv-self' , scene => scene . createEffect ( {
23
+ properties : [
24
+ {
25
+ "key" : 'u_displayMatrix' ,
26
+ "type" : 6 ,
27
+ "default" : [
28
+ 1 , 0 , 0 , 0 ,
29
+ 0 , 1 , 0 , 0 ,
30
+ 0 , 0 , 1 , 0 ,
31
+ 0 , 0 , 0 , 1
32
+ ]
33
+ }
34
+ ] ,
35
+ images : [
36
+ {
37
+ key : 'u_yTexture' ,
38
+ default : 'black' ,
39
+ macro : 'WX_AR_CAMERA_READY'
40
+ } ,
41
+ {
42
+ key : 'u_uvTexture' ,
43
+ default : 'white'
44
+ } ,
45
+ {
46
+ key : 'u_depthTexture' ,
47
+ default : 'white' ,
48
+ macro : 'WX_AR_CAMERA_DEPTH'
49
+ }
50
+ ] ,
51
+ defaultRenderQueue : 2000 ,
52
+ passes : [ {
53
+ renderStates : {
54
+ cullOn : false ,
55
+ blendOn : false ,
56
+ depthWrite : false
57
+ } ,
58
+ lightMode : 'ForwardBase' ,
59
+ useMaterialRenderStates : true ,
60
+ shaders : [ 0 , 1 ]
61
+ } ] ,
62
+ shaders :
63
+ [
64
+ `#version 100
65
+ attribute vec3 a_position;
66
+ attribute vec2 a_texCoord;
67
+
68
+ precision highp float;
69
+
70
+ uniform highp mat4 u_view;
71
+ uniform highp mat4 u_viewInverse;
72
+ uniform highp mat4 u_vp;
73
+ uniform highp mat4 u_projection;
74
+
75
+ uniform highp mat4 u_world;
76
+
77
+
78
+ uniform highp mat4 u_displayMatrix;
79
+ varying highp vec2 v_texCoord;
80
+
81
+ void main() {
82
+ v_texCoord = a_texCoord;
83
+ vec4 pos = u_displayMatrix * vec4(a_position.xy, 1., 1.);
84
+
85
+ gl_Position = pos;
86
+ }
87
+ ` ,
88
+ `#version 100
89
+ precision mediump float;
90
+ precision highp int;
91
+
92
+ uniform sampler2D u_yTexture;
93
+ uniform sampler2D u_uvTexture;
94
+ varying highp vec2 v_texCoord;
95
+
96
+ float unpack(float h, float l) {
97
+ return h * 0.94117647 + l * 0.0588235;
98
+ }
99
+
100
+ void main()
101
+ {
102
+ vec4 yColor = texture2D(u_yTexture, v_texCoord);
103
+ vec4 uvColor = texture2D(u_uvTexture, v_texCoord);
104
+
105
+ #ifdef WX_AR_CAMERA_READY
106
+
107
+ float Y, U, V;
108
+ float R, G, B;
109
+ Y = yColor.r;
110
+ U = unpack(uvColor.r, uvColor.g) - 0.5;
111
+ V = unpack(uvColor.b, uvColor.a) - 0.5;
112
+
113
+ R = Y + 1.402 * V;
114
+ G = Y - 0.344 * U - 0.714 * V;
115
+ B = Y + 1.772 * U;
116
+
117
+ gl_FragData[0] = vec4(B, G, R, 1.0);
118
+ #else
119
+ gl_FragData[0] = vec4(0.0, 0.0, 0.0, 1.0);
120
+
121
+ #endif
122
+ }
123
+ `
124
+ ]
125
+ } ) )
126
+ } ,
127
+ // 初始化 xr-frame 相机 YUV 数据绘制流程节点
128
+ initXRYUVCamera ( ) {
129
+ const xrFrameSystem = wx . getXrFrameSystem ( ) ;
130
+ const scene = this . xrScene ;
131
+ const { assets, rootShadow} = scene ;
132
+
133
+ const el = scene . createElement ( xrFrameSystem . XRNode , {
134
+ layer : 1
135
+ } ) ;
136
+
137
+ let yuvGeometry = assets . getAsset ( 'geometry' , `ar-camera-plane` ) ;
138
+ let yuvEffect = assets . getAsset ( 'effect' , 'ar-yuv-self' ) ;
139
+
140
+ if ( ! yuvEffect ) {
141
+ this . registerYUVEffect ( ) ;
142
+ yuvEffect = assets . getAsset ( 'effect' , 'ar-yuv-self' ) ;
143
+ }
144
+
145
+ const yuvMat = scene . createMaterial ( yuvEffect ) ;
146
+ yuvMat . renderQueue = 1 ; // 第一个绘制
147
+ const mesh = el . addComponent ( xrFrameSystem . Mesh , {
148
+ geometry : yuvGeometry ,
149
+ material : yuvMat
150
+ } ) ;
151
+
152
+ // 相机yuv纹理
153
+ this . yuvMat = yuvMat ;
154
+ this . yuvMatInit = false ;
155
+
156
+ // 不进入正常的剔除
157
+ rootShadow . addChild ( el ) ;
158
+
159
+ console . log ( 'initXRYUVCamera end' )
160
+ } ,
161
+ updataXRYUV ( frame ) {
162
+ // console.log('update yuv')
163
+ const xrFrameSystem = wx . getXrFrameSystem ( ) ;
164
+ const scene = this . xrScene ;
165
+ const yuv = frame . getCameraRawTextureData ( ) ;
166
+ // 未创建相机贴图缓存,先创建
167
+ if ( ! this . cameraTexures ) {
168
+ this . cameraTexures = {
169
+ y : scene . createTexture ( {
170
+ width : yuv . width , height : yuv . height ,
171
+ source : [ yuv . yAddress ] ,
172
+ pixelFormat : xrFrameSystem . ETextureFormat . R8
173
+ } ) ,
174
+ uv : scene . createTexture ( {
175
+ width : yuv . width / 2 , height : yuv . height / 2 ,
176
+ source : [ yuv . uvAddress ] ,
177
+ pixelFormat : xrFrameSystem . ETextureFormat . RGBA4
178
+ } )
179
+ }
180
+ }
181
+ const { y, uv, depth} = this . cameraTexures ;
182
+
183
+ const cameraYUVMat = this . yuvMat ;
184
+ // 未绑定贴图的情况下,绑定贴图
185
+ if ( ! this . yuvMatInit ) {
186
+ cameraYUVMat . setTexture ( 'u_yTexture' , y ) ;
187
+ cameraYUVMat . setTexture ( 'u_uvTexture' , uv ) ;
188
+ // depth && cameraYUVMat.setTexture('u_depthTexture', depth);
189
+ this . yuvMatInit = true ;
190
+ }
191
+
192
+ // 更新displayMat
193
+ const dt = frame . getDisplayTransform ( ) ;
194
+ if ( ! this . DT ) { this . DT = new xrFrameSystem . Matrix4 ( ) ; }
195
+ this . DT . setArray ( [
196
+ dt [ 0 ] , dt [ 1 ] , dt [ 2 ] , 0 ,
197
+ dt [ 3 ] , dt [ 4 ] , dt [ 5 ] , 0 ,
198
+ dt [ 6 ] , dt [ 7 ] , dt [ 8 ] , 0 ,
199
+ 0 , 0 , 0 , 1
200
+ ] ) ;
201
+ cameraYUVMat . setMatrix ( 'u_displayMatrix' , this . DT ) ;
202
+
203
+ // YUV纹理更新
204
+ y . update ( { buffer : yuv . yAddress } ) ;
205
+ uv . update ( { buffer : yuv . uvAddress } ) ;
206
+
207
+ // console.log('update yuv end')
208
+ } ,
209
+ updataXRCameraMatrix ( VKCamera , near , far ) {
210
+ // 同步 VKCamera 矩阵信息到 xrFrame Camera
211
+ if ( VKCamera ) {
212
+ const viewMat = VKCamera . viewMatrix ;
213
+ const projMat = VKCamera . getProjectionMatrix ( near , far ) ;
214
+
215
+ // 更新 viewMatrix
216
+ this . xrCamera . changeViewMatrix ( true , viewMat ) ;
217
+
218
+ // 更新 projectMatrix
219
+ const halfFov = Math . atan ( 1 / projMat [ 5 ] ) * 180 / Math . PI ;
220
+ this . xrCamera . setData ( { near : near , far : far , fov : 2 * halfFov } ) ;
221
+ this . xrCamera . changeProjectMatrix ( true , projMat ) ;
222
+
223
+ }
224
+ } ,
225
+ } ,
226
+ } )
227
+
228
+ export default xrFrameBehavior ;
0 commit comments