@@ -14,20 +14,140 @@ AFRAME.registerComponent("gaussian_splatting", {
14
14
15
15
const focal = ( size . y / 2.0 ) / Math . tan ( this . el . sceneEl . camera . el . components . camera . data . fov / 2.0 * Math . PI / 180.0 ) ;
16
16
17
- const geometry = new THREE . PlaneGeometry ( 4 , 4 ) ;
17
+ let u_buffer = new Uint8Array ( buffer ) ;
18
+ if (
19
+ u_buffer [ 0 ] == 112 &&
20
+ u_buffer [ 1 ] == 108 &&
21
+ u_buffer [ 2 ] == 121 &&
22
+ u_buffer [ 3 ] == 10
23
+ ) {
24
+ buffer = this . processPlyBuffer ( buffer ) ;
25
+ u_buffer = new Uint8Array ( buffer ) ;
26
+ }
27
+
28
+ const rowLength = 3 * 4 + 3 * 4 + 4 + 4 ;
29
+ let vertexCount = Math . floor ( buffer . byteLength / rowLength ) ;
30
+ let f_buffer = new Float32Array ( buffer ) ;
31
+
32
+ if ( vertexCount > 4096 * 4096 / 3 ) {
33
+ console . log ( "vertexCount limited to 4096*4096/3" , vertexCount ) ;
34
+ vertexCount = Math . floor ( 4096 * 4096 / 3 ) ;
35
+ }
36
+
37
+ let matrices = new Float32Array ( vertexCount * 16 ) ;
38
+ const paddedCenterCovariances = new Float32Array ( 4096 * 4096 * 4 ) ;
39
+ const paddedColors = new Float32Array ( 4096 * 4096 * 4 ) ;
40
+ for ( let i = 0 ; i < vertexCount ; i ++ ) {
41
+ let quat = new THREE . Quaternion (
42
+ ( u_buffer [ 32 * i + 28 + 1 ] - 128 ) / 128.0 ,
43
+ ( u_buffer [ 32 * i + 28 + 2 ] - 128 ) / 128.0 ,
44
+ - ( u_buffer [ 32 * i + 28 + 3 ] - 128 ) / 128.0 ,
45
+ ( u_buffer [ 32 * i + 28 + 0 ] - 128 ) / 128.0 ,
46
+ ) ;
47
+ let center = new THREE . Vector3 (
48
+ f_buffer [ 8 * i + 0 ] ,
49
+ f_buffer [ 8 * i + 1 ] ,
50
+ - f_buffer [ 8 * i + 2 ]
51
+ ) ;
52
+ let scale = new THREE . Vector3 (
53
+ f_buffer [ 8 * i + 3 + 0 ] ,
54
+ f_buffer [ 8 * i + 3 + 1 ] ,
55
+ f_buffer [ 8 * i + 3 + 2 ]
56
+ ) ;
57
+
58
+ let mtx = new THREE . Matrix4 ( ) ;
59
+ mtx . makeRotationFromQuaternion ( quat ) ;
60
+ mtx . transpose ( ) ;
61
+ mtx . scale ( scale ) ;
62
+ let mtx_t = mtx . clone ( )
63
+ mtx . transpose ( ) ;
64
+ mtx . premultiply ( mtx_t ) ;
65
+ mtx . setPosition ( center ) ;
66
+
67
+ let destOffset = i * 12 ;
68
+ paddedCenterCovariances [ destOffset + 0 ] = center . x ;
69
+ paddedCenterCovariances [ destOffset + 1 ] = center . y ;
70
+ paddedCenterCovariances [ destOffset + 2 ] = center . z ;
71
+ paddedCenterCovariances [ destOffset + 3 ] = mtx . elements [ 0 ] ;
72
+ paddedCenterCovariances [ destOffset + 4 ] = mtx . elements [ 1 ] ;
73
+ paddedCenterCovariances [ destOffset + 5 ] = mtx . elements [ 2 ] ;
74
+ paddedCenterCovariances [ destOffset + 6 ] = mtx . elements [ 5 ] ;
75
+ paddedCenterCovariances [ destOffset + 7 ] = mtx . elements [ 6 ] ;
76
+ paddedCenterCovariances [ destOffset + 8 ] = mtx . elements [ 10 ] ;
77
+
78
+ // RGBA
79
+ destOffset = i * 4 ;
80
+ paddedColors [ destOffset + 0 ] = u_buffer [ 32 * i + 24 + 0 ] / 255 ;
81
+ paddedColors [ destOffset + 1 ] = u_buffer [ 32 * i + 24 + 1 ] / 255 ;
82
+ paddedColors [ destOffset + 2 ] = u_buffer [ 32 * i + 24 + 2 ] / 255 ;
83
+ paddedColors [ destOffset + 3 ] = u_buffer [ 32 * i + 24 + 3 ] / 255 ;
84
+
85
+ for ( let j = 0 ; j < 16 ; j ++ ) {
86
+ matrices [ i * 16 + j ] = mtx . elements [ j ] ;
87
+ }
88
+ }
89
+
90
+ const centerCovarianceTexture = new THREE . DataTexture ( paddedCenterCovariances , 4096 , 4096 , THREE . RGBAFormat , THREE . FloatType ) ;
91
+ centerCovarianceTexture . needsUpdate = true ;
92
+ const colorTexture = new THREE . DataTexture ( paddedColors , 4096 , 4096 , THREE . RGBAFormat , THREE . FloatType ) ;
93
+ colorTexture . needsUpdate = true ;
94
+
95
+ const camera_mtx = this . el . sceneEl . camera . el . object3D . matrixWorld . elements ;
96
+ let view = new Float32Array ( [ camera_mtx [ 2 ] , camera_mtx [ 6 ] , camera_mtx [ 10 ] ] ) ;
97
+ let splatIndexArray = this . sortSplats ( matrices , view ) ;
98
+ const splatIndexes = new THREE . InstancedBufferAttribute ( splatIndexArray , 1 , false ) ;
99
+ splatIndexes . setUsage ( THREE . DynamicDrawUsage ) ;
100
+
101
+ const baseGeometry = new THREE . BufferGeometry ( ) ;
102
+ const positionsArray = new Float32Array ( 6 * 3 ) ;
103
+ const positions = new THREE . BufferAttribute ( positionsArray , 3 ) ;
104
+ baseGeometry . setAttribute ( 'position' , positions ) ;
105
+ positions . setXYZ ( 2 , - 2.0 , 2.0 , 0.0 ) ;
106
+ positions . setXYZ ( 1 , 2.0 , 2.0 , 0.0 ) ;
107
+ positions . setXYZ ( 0 , - 2.0 , - 2.0 , 0.0 ) ;
108
+ positions . setXYZ ( 5 , - 2.0 , - 2.0 , 0.0 ) ;
109
+ positions . setXYZ ( 4 , 2.0 , 2.0 , 0.0 ) ;
110
+ positions . setXYZ ( 3 , 2.0 , - 2.0 , 0.0 ) ;
111
+ positions . needsUpdate = true ;
112
+
113
+ const geometry = new THREE . InstancedBufferGeometry ( ) . copy ( baseGeometry ) ;
114
+ geometry . setAttribute ( 'splatIndex' , splatIndexes ) ;
115
+ geometry . instanceCount = vertexCount ;
116
+
18
117
const material = new THREE . ShaderMaterial ( {
19
118
uniforms : {
20
119
viewport : { value : new Float32Array ( [ size . x , size . y ] ) } ,
21
- focal : { value : focal }
120
+ focal : { value : focal } ,
121
+ centerCovarianceTexture : { value : centerCovarianceTexture } ,
122
+ colorTexture : { value : colorTexture }
22
123
} ,
23
124
vertexShader : `
24
125
out vec4 vColor;
25
126
out vec2 vPosition;
26
127
uniform vec2 viewport;
27
128
uniform float focal;
28
129
130
+ attribute uint splatIndex;
131
+ uniform sampler2D centerCovarianceTexture;
132
+ uniform sampler2D colorTexture;
133
+
134
+ ivec2 getDataUV(in int stride, in int offset) {
135
+ uint covarianceD = splatIndex * uint(stride) + uint(offset);
136
+ return ivec2(covarianceD%uint(4096),covarianceD/uint(4096));
137
+ }
138
+
29
139
void main () {
30
- vec4 center = vec4(instanceMatrix[3][0], instanceMatrix[3][1], instanceMatrix[3][2], 1);
140
+ vec4 sampledCenterCovarianceA = texelFetch(centerCovarianceTexture, getDataUV(3, 0), 0);
141
+ vec4 sampledCenterCovarianceB = texelFetch(centerCovarianceTexture, getDataUV(3, 1), 0);
142
+ vec4 sampledCenterCovarianceC = texelFetch(centerCovarianceTexture, getDataUV(3, 2), 0);
143
+
144
+ vec4 center = vec4(sampledCenterCovarianceA.xyz, 1);
145
+ vec3 cov3D_M11_M12_M13 = vec3(sampledCenterCovarianceA.w, sampledCenterCovarianceB.xy);
146
+ vec3 cov3D_M22_M23_M33 = vec3(sampledCenterCovarianceB.zw, sampledCenterCovarianceC.x);
147
+
148
+ ivec2 colorUV = ivec2(splatIndex%uint(4096),splatIndex/uint(4096));
149
+ vec4 sampledColor = texelFetch(colorTexture, colorUV, 0);
150
+
31
151
// Adjust View Pose
32
152
mat4 adjViewMatrix = inverse(viewMatrix);
33
153
adjViewMatrix[0][1] *= -1.0;
@@ -50,6 +170,12 @@ AFRAME.registerComponent("gaussian_splatting", {
50
170
return;
51
171
}
52
172
173
+ mat3 Vrk = mat3(
174
+ cov3D_M11_M12_M13.x, cov3D_M11_M12_M13.y, cov3D_M11_M12_M13.z,
175
+ cov3D_M11_M12_M13.y, cov3D_M22_M23_M33.x, cov3D_M22_M23_M33.y,
176
+ cov3D_M11_M12_M13.z, cov3D_M22_M23_M33.y, cov3D_M22_M23_M33.z
177
+ );
178
+
53
179
mat3 J = mat3(
54
180
focal / camspace.z, 0., -(focal * camspace.x) / (camspace.z * camspace.z),
55
181
0., -focal / camspace.z, (focal * camspace.y) / (camspace.z * camspace.z),
@@ -58,7 +184,7 @@ AFRAME.registerComponent("gaussian_splatting", {
58
184
59
185
mat3 W = transpose(mat3(modelView));
60
186
mat3 T = W * J;
61
- mat3 cov = transpose(T) * mat3(instanceMatrix) * T;
187
+ mat3 cov = transpose(T) * Vrk * T;
62
188
63
189
vec2 vCenter = vec2(pos2d) / pos2d.w;
64
190
@@ -74,7 +200,7 @@ AFRAME.registerComponent("gaussian_splatting", {
74
200
vec2 v1 = min(sqrt(2.0 * lambda1), 1024.0) * diagonalVector;
75
201
vec2 v2 = min(sqrt(2.0 * lambda2), 1024.0) * vec2(diagonalVector.y, -diagonalVector.x);
76
202
77
- vColor = vec4(instanceMatrix[0][3], instanceMatrix[1][3], instanceMatrix[2][3], instanceMatrix[3][3]) ;
203
+ vColor = sampledColor ;
78
204
vPosition = position.xy;
79
205
80
206
gl_Position = vec4(
@@ -97,7 +223,8 @@ AFRAME.registerComponent("gaussian_splatting", {
97
223
blending : THREE . CustomBlending ,
98
224
blendSrcAlpha : THREE . OneFactor ,
99
225
depthTest : true ,
100
- depthWrite : false
226
+ depthWrite : false ,
227
+ transparent : false
101
228
} ) ;
102
229
103
230
window . addEventListener ( 'resize' , ( ) => {
@@ -109,67 +236,9 @@ AFRAME.registerComponent("gaussian_splatting", {
109
236
material . uniforms . focal . value = focal ;
110
237
} ) ;
111
238
112
- let u_buffer = new Uint8Array ( buffer ) ;
113
- if (
114
- u_buffer [ 0 ] == 112 &&
115
- u_buffer [ 1 ] == 108 &&
116
- u_buffer [ 2 ] == 121 &&
117
- u_buffer [ 3 ] == 10
118
- ) {
119
- buffer = this . processPlyBuffer ( buffer ) ;
120
- u_buffer = new Uint8Array ( buffer ) ;
121
- }
122
-
123
- const rowLength = 3 * 4 + 3 * 4 + 4 + 4 ;
124
- let vertexCount = Math . floor ( buffer . byteLength / rowLength ) ;
125
- let f_buffer = new Float32Array ( buffer ) ;
126
-
127
- let matrices = new Float32Array ( vertexCount * 16 ) ;
128
- for ( let i = 0 ; i < vertexCount ; i ++ ) {
129
- let quat = new THREE . Quaternion (
130
- ( u_buffer [ 32 * i + 28 + 1 ] - 128 ) / 128.0 ,
131
- ( u_buffer [ 32 * i + 28 + 2 ] - 128 ) / 128.0 ,
132
- - ( u_buffer [ 32 * i + 28 + 3 ] - 128 ) / 128.0 ,
133
- ( u_buffer [ 32 * i + 28 + 0 ] - 128 ) / 128.0 ,
134
- ) ;
135
- let center = new THREE . Vector3 (
136
- f_buffer [ 8 * i + 0 ] ,
137
- f_buffer [ 8 * i + 1 ] ,
138
- - f_buffer [ 8 * i + 2 ]
139
- ) ;
140
- let scale = new THREE . Vector3 (
141
- f_buffer [ 8 * i + 3 + 0 ] ,
142
- f_buffer [ 8 * i + 3 + 1 ] ,
143
- f_buffer [ 8 * i + 3 + 2 ]
144
- ) ;
145
-
146
- let mtx = new THREE . Matrix4 ( ) ;
147
- mtx . makeRotationFromQuaternion ( quat ) ;
148
- mtx . transpose ( ) ;
149
- mtx . scale ( scale ) ;
150
- let mtx_t = mtx . clone ( )
151
- mtx . transpose ( ) ;
152
- mtx . premultiply ( mtx_t ) ;
153
- mtx . setPosition ( center ) ;
154
-
155
- // RGBA
156
- mtx . elements [ 3 ] = u_buffer [ 32 * i + 24 + 0 ] / 255 ;
157
- mtx . elements [ 7 ] = u_buffer [ 32 * i + 24 + 1 ] / 255 ;
158
- mtx . elements [ 11 ] = u_buffer [ 32 * i + 24 + 2 ] / 255 ;
159
- mtx . elements [ 15 ] = u_buffer [ 32 * i + 24 + 3 ] / 255 ;
160
-
161
- for ( let j = 0 ; j < 16 ; j ++ ) {
162
- matrices [ i * 16 + j ] = mtx . elements [ j ] ;
163
- }
164
- }
165
-
166
- const camera_mtx = this . el . sceneEl . camera . el . object3D . matrixWorld . elements ;
167
- let view = new Float32Array ( [ camera_mtx [ 2 ] , camera_mtx [ 6 ] , camera_mtx [ 10 ] ] ) ;
168
- this . iMesh = new THREE . InstancedMesh ( geometry , material , vertexCount ) ;
169
- this . iMesh . frustumCulled = false ;
170
- this . iMesh . instanceMatrix . array = this . sortSplats ( matrices , view ) ;
171
- this . iMesh . instanceMatrix . needsUpdate = true ;
172
- this . el . object3D . add ( this . iMesh ) ;
239
+ let mesh = new THREE . Mesh ( geometry , material , vertexCount ) ;
240
+ mesh . frustumCulled = false ;
241
+ this . el . object3D . add ( mesh ) ;
173
242
174
243
this . worker = new Worker (
175
244
URL . createObjectURL (
@@ -185,8 +254,10 @@ AFRAME.registerComponent("gaussian_splatting", {
185
254
} , [ matrices . buffer ] ) ;
186
255
187
256
this . worker . onmessage = ( e ) => {
188
- this . iMesh . instanceMatrix . array = new Float32Array ( e . data . sortedMatrices ) ;
189
- this . iMesh . instanceMatrix . needsUpdate = true ;
257
+ let indexes = new Uint32Array ( e . data . sortedIndexes ) ;
258
+ mesh . geometry . attributes . splatIndex . set ( indexes ) ;
259
+ mesh . geometry . attributes . splatIndex . needsUpdate = true ;
260
+ mesh . geometry . instanceCount = indexes . length ;
190
261
this . sortReady = true ;
191
262
} ;
192
263
this . sortReady = true ;
@@ -213,8 +284,8 @@ AFRAME.registerComponent("gaussian_splatting", {
213
284
}
214
285
if ( e . data . view ) {
215
286
const view = new Float32Array ( e . data . view ) ;
216
- const sortedMatrices = sortFunction ( matrices , view ) ;
217
- self . postMessage ( { sortedMatrices } , [ sortedMatrices . buffer ] ) ;
287
+ const sortedIndexes = sortFunction ( matrices , view ) ;
288
+ self . postMessage ( { sortedIndexes } , [ sortedIndexes . buffer ] ) ;
218
289
}
219
290
} ;
220
291
} ,
@@ -247,15 +318,7 @@ AFRAME.registerComponent("gaussian_splatting", {
247
318
let depthIndex = new Uint32Array ( vertexCount ) ;
248
319
for ( let i = 0 ; i < vertexCount ; i ++ ) depthIndex [ starts0 [ sizeList [ i ] ] ++ ] = i ;
249
320
250
- let sortedMatrices = new Float32Array ( vertexCount * 16 ) ;
251
- for ( let j = 0 ; j < vertexCount ; j ++ ) {
252
- let i = depthIndex [ j ] ;
253
- for ( let k = 0 ; k < 16 ; k ++ ) {
254
- sortedMatrices [ j * 16 + k ] = matrices [ i * 16 + k ] ;
255
- }
256
- }
257
-
258
- return sortedMatrices ;
321
+ return depthIndex ;
259
322
} ,
260
323
processPlyBuffer : function ( inputBuffer ) {
261
324
const ubuf = new Uint8Array ( inputBuffer ) ;
0 commit comments