@@ -94,8 +94,116 @@ Extending glTF node:
94
94
}
95
95
```
96
96
97
+ ## Implementation
98
+
99
+ _ This section is non-normative_
100
+
101
+ In this example, we follow a reference implementation for rendering Gaussian Splats.
102
+
103
+ In the vertex shader, we first must compute covariance in 3D and then 2D space. In optimizing implementations, 3D covariance can be computed ahead of time.
104
+
105
+ ```
106
+ //https://github.com/graphdeco-inria/diff-gaussian-rasterization/blob/59f5f77e3ddbac3ed9db93ec2cfe99ed6c5d121d/cuda_rasterizer/forward.cu#L118
107
+ void calculateCovariance3D(vec3 rotation, vec3 scale, out float[6] covariance3D)
108
+ {
109
+ mat3 S = mat3(
110
+ scale[0], 0, 0,
111
+ 0, scale[1], 0,
112
+ 0, 0, scale[2]
113
+ );
114
+
115
+ float r = rot.w;
116
+ float x = rot.x;
117
+ float y = rot.y;
118
+ float z = rot.z;
119
+
120
+ mat3 R = mat3(
121
+ 1. - 2. * (y * y + z * z), 2. * (x * y - r * z), 2. * (x * z + r * y),
122
+ 2. * (x * y + r * z), 1. - 2. * (x * x + z * z), 2. * (y * z - r * x),
123
+ 2. * (x * z - r * y), 2. * (y * z + r * x), 1. - 2. * (x * x + y * y)
124
+ );
125
+
126
+ mat3 M = S * R;
127
+ mat3 Sigma = transpose(M) * M;
128
+
129
+ covariance3D = float[6](
130
+ Sigma[0][0], Sigma[0][1], Sigma[0][2],
131
+ Sigma[1][1], Sigma[1][2], Sigma[2][2]
132
+ );
133
+ }
134
+
135
+ //https://github.com/graphdeco-inria/diff-gaussian-rasterization/blob/59f5f77e3ddbac3ed9db93ec2cfe99ed6c5d121d/cuda_rasterizer/forward.cu#L74
136
+ vec3 calculateCovariance2D(vec3 worldPosition, float cameraFocal_X, float cameraFocal_Y, float tan_fovX, float tan_fovY, float[6] covariance3D, mat4 viewMatrix)
137
+ {
138
+ vec4 t = viewmatrix * vec4(worldPos, 1.0);
139
+
140
+ float limx = 1.3 * tan_fovx;
141
+ float limy = 1.3 * tan_fovy;
142
+ float txtz = t.x / t.z;
143
+ float tytz = t.y / t.z;
144
+ t.x = min(limx, max(-limx, txtz)) * t.z;
145
+ t.y = min(limy, max(-limy, tytz)) * t.z;
146
+
147
+ mat3 J = mat3(
148
+ focal_x / t.z, 0, -(focal_x * t.x) / (t.z * t.z),
149
+ 0, focal_y / t.z, -(focal_y * t.y) / (t.z * t.z),
150
+ 0, 0, 0
151
+ );
152
+
153
+ mat3 W = mat3(
154
+ viewmatrix[0][0], viewmatrix[1][0], viewmatrix[2][0],
155
+ viewmatrix[0][1], viewmatrix[1][1], viewmatrix[2][1],
156
+ viewmatrix[0][2], viewmatrix[1][2], viewmatrix[2][2]
157
+ );
158
+ mat3 T = W * J;
159
+ mat3 Vrk = mat3(
160
+ covariance3D[0], covariance3D[1], covariance3D[2],
161
+ covariance3D[1], covariance3D[3], covariance3D[4],
162
+ covariance3D[2], covariance3D[4], covariance3D[5]
163
+ );
164
+
165
+ mat3 cov = transpose(T) * transpose(Vrk) * T;
166
+
167
+ cov[0][0] += .3;
168
+ cov[1][1] += .3;
169
+ return vec3(cov[0][0], cov[0][1], cov[1][1]);
170
+ }
171
+
172
+ vec3 calculateConic(vec3 covariance2D)
173
+ {
174
+ float det = covariance2D.x * covariance2D.z - covariance2D.y * covariance2D.y;
175
+ return vec3(covariance2D.z, -covariance2D.y, covariance2D.x) * (1. / det);
176
+ }
177
+
178
+ ```
179
+ //https://github.com/graphdeco-inria/diff-gaussian-rasterization/blob/59f5f77e3ddbac3ed9db93ec2cfe99ed6c5d121d/cuda_rasterizer/forward.cu#L330
180
+ ```
181
+ in vec2 vertexPosition;
182
+ in vec2 screenPosition;
183
+ in vec3 conic;
184
+ in vec4 color;
185
+
186
+ out vec4 splatColor;
187
+
188
+ vec2 d = screenPosition - vertexPosition;
189
+ float power = -0.5 * (conic.x * d.x * d.x + conic.z * d.y * d.y) - conic.y * d.x * d.y);
190
+
191
+ if(power > 0.)
192
+ discard;
193
+
194
+ float alpha = min(.99f, color.a * exp(power));
195
+
196
+ if(alpha < 1./255.)
197
+ discard;
198
+
199
+ splatColor = vec4(color * alpha, alpha);
200
+ ```
201
+
202
+
97
203
## Schema
98
204
205
+ [ Gaussian Splatting JSON Schema] ( ./schema/primitive.KHR_gaussian_splatting.schema.json )
206
+
99
207
100
208
101
209
## Known Implementations
0 commit comments