Spaces:
Running
Running
antimatter15
commited on
Commit
•
db8e2ca
1
Parent(s):
e22c65e
improvements to splat quality
Browse files
main.js
CHANGED
@@ -162,7 +162,7 @@ function getProjectionMatrix(fx, fy, width, height) {
|
|
162 |
const zfar = 200;
|
163 |
return [
|
164 |
[(2 * fx) / width, 0, 0, 0],
|
165 |
-
[0, (2 * fy) / height, 0, 0],
|
166 |
[0, 0, zfar / (zfar - znear), 1],
|
167 |
[0, 0, -(zfar * znear) / (zfar - znear), 0],
|
168 |
].flat();
|
@@ -307,8 +307,9 @@ function createWorker(self) {
|
|
307 |
const f_buffer = new Float32Array(buffer);
|
308 |
const u_buffer = new Uint8Array(buffer);
|
309 |
|
310 |
-
const
|
311 |
-
const
|
|
|
312 |
const center = new Float32Array(3 * vertexCount);
|
313 |
const color = new Float32Array(4 * vertexCount);
|
314 |
|
@@ -348,10 +349,6 @@ function createWorker(self) {
|
|
348 |
for (let j = 0; j < vertexCount; j++) {
|
349 |
const i = indexMix[2 * j];
|
350 |
|
351 |
-
quat[4 * j + 0] = (u_buffer[32 * i + 28 + 0] - 128) / 128;
|
352 |
-
quat[4 * j + 1] = (u_buffer[32 * i + 28 + 1] - 128) / 128;
|
353 |
-
quat[4 * j + 2] = (u_buffer[32 * i + 28 + 2] - 128) / 128;
|
354 |
-
quat[4 * j + 3] = (u_buffer[32 * i + 28 + 3] - 128) / 128;
|
355 |
|
356 |
center[3 * j + 0] = f_buffer[8 * i + 0];
|
357 |
center[3 * j + 1] = f_buffer[8 * i + 1];
|
@@ -362,16 +359,50 @@ function createWorker(self) {
|
|
362 |
color[4 * j + 2] = u_buffer[32 * i + 24 + 2] / 255;
|
363 |
color[4 * j + 3] = u_buffer[32 * i + 24 + 3] / 255;
|
364 |
|
365 |
-
scale[
|
366 |
-
|
367 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
368 |
}
|
369 |
|
370 |
-
self.postMessage({
|
371 |
-
|
372 |
center.buffer,
|
373 |
color.buffer,
|
374 |
-
|
375 |
]);
|
376 |
|
377 |
// console.timeEnd("sort");
|
@@ -559,96 +590,94 @@ function createWorker(self) {
|
|
559 |
}
|
560 |
|
561 |
const vertexShaderSource = `
|
562 |
-
precision mediump float;
|
563 |
-
attribute vec2 position;
|
564 |
-
|
565 |
-
attribute vec4 color;
|
566 |
-
attribute
|
567 |
-
attribute vec3
|
568 |
-
attribute vec3
|
569 |
-
|
570 |
-
uniform mat4 projection, view;
|
571 |
-
uniform vec2 focal;
|
572 |
-
|
573 |
-
|
574 |
-
varying
|
575 |
-
varying vec2
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
mat3 S = mat3(
|
583 |
-
scale.x, 0.0, 0.0,
|
584 |
-
0.0, scale.y, 0.0,
|
585 |
-
0.0, 0.0, scale.z
|
586 |
-
);
|
587 |
-
mat3 R = mat3(
|
588 |
-
1.0 - 2.0 * (rot.z * rot.z + rot.w * rot.w), 2.0 * (rot.y * rot.z - rot.x * rot.w), 2.0 * (rot.y * rot.w + rot.x * rot.z),
|
589 |
-
2.0 * (rot.y * rot.z + rot.x * rot.w), 1.0 - 2.0 * (rot.y * rot.y + rot.w * rot.w), 2.0 * (rot.z * rot.w - rot.x * rot.y),
|
590 |
-
2.0 * (rot.y * rot.w - rot.x * rot.z), 2.0 * (rot.z * rot.w + rot.x * rot.y), 1.0 - 2.0 * (rot.y * rot.y + rot.z * rot.z)
|
591 |
);
|
592 |
-
|
593 |
-
return transpose(M) * M;
|
594 |
-
}
|
595 |
|
596 |
-
|
597 |
-
|
598 |
-
vec4
|
599 |
-
|
600 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
601 |
mat3 J = mat3(
|
602 |
-
focal.x /
|
603 |
-
0., focal.y /
|
604 |
0., 0., 0.
|
605 |
);
|
|
|
606 |
mat3 W = transpose(mat3(view));
|
607 |
mat3 T = W * J;
|
608 |
-
mat3 cov = transpose(T) *
|
609 |
-
|
610 |
-
|
611 |
|
612 |
-
|
613 |
-
|
614 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
615 |
|
616 |
-
vec3 cov2d = compute_cov2d(center, scale, quat);
|
617 |
-
float det = cov2d.x * cov2d.z - cov2d.y * cov2d.y;
|
618 |
-
vec3 conic = vec3(cov2d.z, cov2d.y, cov2d.x) / det;
|
619 |
-
float mid = 0.5 * (cov2d.x + cov2d.z);
|
620 |
-
float lambda1 = mid + sqrt(max(0.1, mid * mid - det));
|
621 |
-
float lambda2 = mid - sqrt(max(0.1, mid * mid - det));
|
622 |
-
vec2 v1 = 7.0 * sqrt(lambda1) * normalize(vec2(cov2d.y, lambda1 - cov2d.x));
|
623 |
-
vec2 v2 = 7.0 * sqrt(lambda2) * normalize(vec2(-(lambda1 - cov2d.x),cov2d.y));
|
624 |
|
625 |
vColor = color;
|
626 |
-
|
627 |
-
vCenter = vec2(pos2d) / pos2d.w;
|
628 |
|
629 |
-
|
630 |
-
|
631 |
-
|
|
|
|
|
|
|
632 |
`;
|
633 |
|
634 |
const fragmentShaderSource = `
|
635 |
precision mediump float;
|
636 |
|
637 |
-
varying vec4 vColor;
|
638 |
-
varying
|
639 |
-
varying vec2 vCenter;
|
640 |
-
uniform vec2 viewport;
|
641 |
-
uniform vec2 focal;
|
642 |
-
|
643 |
-
void main () {
|
644 |
-
vec2 d = (vCenter - 2.0 * (gl_FragCoord.xy/viewport - vec2(0.5, 0.5))) * viewport * 0.5;
|
645 |
-
float power = -0.5 * (vConic.x * d.x * d.x + vConic.z * d.y * d.y) - vConic.y * d.x * d.y;
|
646 |
-
if (power > 0.0) discard;
|
647 |
-
float alpha = min(0.99, vColor.a * exp(power));
|
648 |
-
if(alpha < 0.02) discard;
|
649 |
|
650 |
-
|
651 |
-
|
|
|
|
|
|
|
|
|
652 |
`;
|
653 |
|
654 |
let defaultViewMatrix = [
|
@@ -682,7 +711,9 @@ async function main() {
|
|
682 |
const reader = req.body.getReader();
|
683 |
let splatData = new Uint8Array(req.headers.get("content-length"));
|
684 |
|
685 |
-
const downsample = splatData.length / rowLength > 500000 ?
|
|
|
|
|
686 |
console.log(splatData.length / rowLength, downsample);
|
687 |
|
688 |
const worker = new Worker(
|
@@ -766,7 +797,7 @@ async function main() {
|
|
766 |
gl.uniformMatrix4fv(u_view, false, viewMatrix);
|
767 |
|
768 |
// positions
|
769 |
-
const triangleVertices = new Float32Array([
|
770 |
const vertexBuffer = gl.createBuffer();
|
771 |
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
|
772 |
gl.bufferData(gl.ARRAY_BUFFER, triangleVertices, gl.STATIC_DRAW);
|
@@ -795,25 +826,20 @@ async function main() {
|
|
795 |
gl.vertexAttribPointer(a_color, 4, gl.FLOAT, false, 0, 0);
|
796 |
ext.vertexAttribDivisorANGLE(a_color, 1); // Use the extension here
|
797 |
|
798 |
-
//
|
799 |
-
const
|
800 |
-
|
801 |
-
|
802 |
-
|
803 |
-
gl.
|
804 |
-
|
805 |
-
|
806 |
-
|
807 |
-
|
808 |
-
|
809 |
-
|
810 |
-
|
811 |
-
|
812 |
-
const a_scale = gl.getAttribLocation(program, "scale");
|
813 |
-
gl.enableVertexAttribArray(a_scale);
|
814 |
-
gl.bindBuffer(gl.ARRAY_BUFFER, scaleBuffer);
|
815 |
-
gl.vertexAttribPointer(a_scale, 3, gl.FLOAT, false, 0, 0);
|
816 |
-
ext.vertexAttribDivisorANGLE(a_scale, 1); // Use the extension here
|
817 |
|
818 |
let lastProj = []
|
819 |
let lastData
|
@@ -830,11 +856,11 @@ async function main() {
|
|
830 |
document.body.appendChild(link);
|
831 |
link.click();
|
832 |
} else {
|
833 |
-
let {
|
834 |
lastData = e.data;
|
835 |
|
836 |
lastProj = viewProj
|
837 |
-
vertexCount =
|
838 |
|
839 |
gl.bindBuffer(gl.ARRAY_BUFFER, centerBuffer);
|
840 |
gl.bufferData(gl.ARRAY_BUFFER, center, gl.STATIC_DRAW);
|
@@ -842,11 +868,13 @@ async function main() {
|
|
842 |
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
|
843 |
gl.bufferData(gl.ARRAY_BUFFER, color, gl.STATIC_DRAW);
|
844 |
|
845 |
-
|
846 |
-
gl.
|
|
|
|
|
|
|
|
|
847 |
|
848 |
-
gl.bindBuffer(gl.ARRAY_BUFFER, scaleBuffer);
|
849 |
-
gl.bufferData(gl.ARRAY_BUFFER, scale, gl.STATIC_DRAW);
|
850 |
}
|
851 |
};
|
852 |
|
@@ -1179,8 +1207,10 @@ async function main() {
|
|
1179 |
|
1180 |
if (vertexCount > 0) {
|
1181 |
document.getElementById("spinner").style.display = "none";
|
|
|
1182 |
gl.uniformMatrix4fv(u_view, false, actualViewMatrix);
|
1183 |
-
ext.drawArraysInstancedANGLE(gl.
|
|
|
1184 |
} else {
|
1185 |
gl.clear(gl.COLOR_BUFFER_BIT);
|
1186 |
document.getElementById("spinner").style.display = "";
|
@@ -1190,7 +1220,7 @@ async function main() {
|
|
1190 |
if (progress < 100) {
|
1191 |
document.getElementById("progress").style.width = progress + "%";
|
1192 |
} else {
|
1193 |
-
document.getElementById("progress").style.display = "none";
|
1194 |
}
|
1195 |
fps.innerText = Math.round(avgFps) + " fps";
|
1196 |
lastFrame = now;
|
|
|
162 |
const zfar = 200;
|
163 |
return [
|
164 |
[(2 * fx) / width, 0, 0, 0],
|
165 |
+
[0, -(2 * fy) / height, 0, 0],
|
166 |
[0, 0, zfar / (zfar - znear), 1],
|
167 |
[0, 0, -(zfar * znear) / (zfar - znear), 0],
|
168 |
].flat();
|
|
|
307 |
const f_buffer = new Float32Array(buffer);
|
308 |
const u_buffer = new Uint8Array(buffer);
|
309 |
|
310 |
+
const covA = new Float32Array(3 * vertexCount);
|
311 |
+
const covB = new Float32Array(3 * vertexCount);
|
312 |
+
|
313 |
const center = new Float32Array(3 * vertexCount);
|
314 |
const color = new Float32Array(4 * vertexCount);
|
315 |
|
|
|
349 |
for (let j = 0; j < vertexCount; j++) {
|
350 |
const i = indexMix[2 * j];
|
351 |
|
|
|
|
|
|
|
|
|
352 |
|
353 |
center[3 * j + 0] = f_buffer[8 * i + 0];
|
354 |
center[3 * j + 1] = f_buffer[8 * i + 1];
|
|
|
359 |
color[4 * j + 2] = u_buffer[32 * i + 24 + 2] / 255;
|
360 |
color[4 * j + 3] = u_buffer[32 * i + 24 + 3] / 255;
|
361 |
|
362 |
+
let scale = [ f_buffer[8 * i + 3 + 0], f_buffer[8 * i + 3 + 1], f_buffer[8 * i + 3 + 2]];
|
363 |
+
let rot = [(u_buffer[32 * i + 28 + 0] - 128) / 128, (u_buffer[32 * i + 28 + 1] - 128) / 128, (u_buffer[32 * i + 28 + 2] - 128) / 128, (u_buffer[32 * i + 28 + 3] - 128) / 128]
|
364 |
+
|
365 |
+
const R = [
|
366 |
+
1.0 - 2.0 * (rot[2] * rot[2] + rot[3] * rot[3]),
|
367 |
+
2.0 * (rot[1] * rot[2] + rot[0] * rot[3]),
|
368 |
+
2.0 * (rot[1] * rot[3] - rot[0] * rot[2]),
|
369 |
+
|
370 |
+
2.0 * (rot[1] * rot[2] - rot[0] * rot[3]),
|
371 |
+
1.0 - 2.0 * (rot[1] * rot[1] + rot[3] * rot[3]),
|
372 |
+
2.0 * (rot[2] * rot[3] + rot[0] * rot[1]),
|
373 |
+
|
374 |
+
2.0 * (rot[1] * rot[3] + rot[0] * rot[2]),
|
375 |
+
2.0 * (rot[2] * rot[3] - rot[0] * rot[1]),
|
376 |
+
1.0 - 2.0 * (rot[1] * rot[1] + rot[2] * rot[2]),
|
377 |
+
];
|
378 |
+
|
379 |
+
// Compute the matrix product of S and R (M = S * R)
|
380 |
+
const M = [
|
381 |
+
scale[0] * R[0],
|
382 |
+
scale[0] * R[1],
|
383 |
+
scale[0] * R[2],
|
384 |
+
scale[1] * R[3],
|
385 |
+
scale[1] * R[4],
|
386 |
+
scale[1] * R[5],
|
387 |
+
scale[2] * R[6],
|
388 |
+
scale[2] * R[7],
|
389 |
+
scale[2] * R[8],
|
390 |
+
];
|
391 |
+
|
392 |
+
|
393 |
+
covA[3 * j + 0] = M[0] * M[0] + M[3] * M[3] + M[6] * M[6];
|
394 |
+
covA[3 * j + 1] = M[0] * M[1] + M[3] * M[4] + M[6] * M[7];
|
395 |
+
covA[3 * j + 2] = M[0] * M[2] + M[3] * M[5] + M[6] * M[8];
|
396 |
+
covB[3 * j + 0] = M[1] * M[1] + M[4] * M[4] + M[7] * M[7];
|
397 |
+
covB[3 * j + 1] = M[1] * M[2] + M[4] * M[5] + M[7] * M[8];
|
398 |
+
covB[3 * j + 2] = M[2] * M[2] + M[5] * M[5] + M[8] * M[8];
|
399 |
}
|
400 |
|
401 |
+
self.postMessage({ covA, center, color, covB, viewProj }, [
|
402 |
+
covA.buffer,
|
403 |
center.buffer,
|
404 |
color.buffer,
|
405 |
+
covB.buffer,
|
406 |
]);
|
407 |
|
408 |
// console.timeEnd("sort");
|
|
|
590 |
}
|
591 |
|
592 |
const vertexShaderSource = `
|
593 |
+
precision mediump float;
|
594 |
+
attribute vec2 position;
|
595 |
+
|
596 |
+
attribute vec4 color;
|
597 |
+
attribute vec3 center;
|
598 |
+
attribute vec3 covA;
|
599 |
+
attribute vec3 covB;
|
600 |
+
|
601 |
+
uniform mat4 projection, view;
|
602 |
+
uniform vec2 focal;
|
603 |
+
uniform vec2 viewport;
|
604 |
+
|
605 |
+
varying vec4 vColor;
|
606 |
+
varying vec2 vPosition;
|
607 |
+
|
608 |
+
mat3 transpose(mat3 m) {
|
609 |
+
return mat3(
|
610 |
+
m[0][0], m[1][0], m[2][0],
|
611 |
+
m[0][1], m[1][1], m[2][1],
|
612 |
+
m[0][2], m[1][2], m[2][2]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
613 |
);
|
614 |
+
}
|
|
|
|
|
615 |
|
616 |
+
void main () {
|
617 |
+
vec4 camspace = view * vec4(center, 1);
|
618 |
+
vec4 pos2d = projection * camspace;
|
619 |
+
|
620 |
+
float bounds = 1.2 * pos2d.w;
|
621 |
+
if (pos2d.z < -pos2d.w || pos2d.x < -bounds || pos2d.x > bounds
|
622 |
+
|| pos2d.y < -bounds || pos2d.y > bounds) {
|
623 |
+
gl_Position = vec4(0.0, 0.0, 2.0, 1.0);
|
624 |
+
return;
|
625 |
+
}
|
626 |
+
|
627 |
+
mat3 Vrk = mat3(
|
628 |
+
covA.x, covA.y, covA.z,
|
629 |
+
covA.y, covB.x, covB.y,
|
630 |
+
covA.z, covB.y, covB.z
|
631 |
+
);
|
632 |
+
|
633 |
mat3 J = mat3(
|
634 |
+
focal.x / camspace.z, 0., -(focal.x * camspace.x) / (camspace.z * camspace.z),
|
635 |
+
0., -focal.y / camspace.z, (focal.y * camspace.y) / (camspace.z * camspace.z),
|
636 |
0., 0., 0.
|
637 |
);
|
638 |
+
|
639 |
mat3 W = transpose(mat3(view));
|
640 |
mat3 T = W * J;
|
641 |
+
mat3 cov = transpose(T) * Vrk * T;
|
642 |
+
|
643 |
+
vec2 vCenter = vec2(pos2d) / pos2d.w;
|
644 |
|
645 |
+
float diagonal1 = cov[0][0] + 0.3;
|
646 |
+
float offDiagonal = cov[0][1];
|
647 |
+
float diagonal2 = cov[1][1] + 0.3;
|
648 |
+
|
649 |
+
float mid = 0.5 * (diagonal1 + diagonal2);
|
650 |
+
float radius = length(vec2((diagonal1 - diagonal2) / 2.0, offDiagonal));
|
651 |
+
float lambda1 = mid + radius;
|
652 |
+
float lambda2 = max(mid - radius, 0.1);
|
653 |
+
vec2 diagonalVector = normalize(vec2(offDiagonal, lambda1 - diagonal1));
|
654 |
+
vec2 v1 = min(sqrt(2.0 * lambda1), 1024.0) * diagonalVector;
|
655 |
+
vec2 v2 = min(sqrt(2.0 * lambda2), 1024.0) * vec2(diagonalVector.y, -diagonalVector.x);
|
656 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
657 |
|
658 |
vColor = color;
|
659 |
+
vPosition = position;
|
|
|
660 |
|
661 |
+
gl_Position = vec4(
|
662 |
+
vCenter
|
663 |
+
+ position.x * v1 / viewport * 2.0
|
664 |
+
+ position.y * v2 / viewport * 2.0, 0.0, 1.0);
|
665 |
+
|
666 |
+
}
|
667 |
`;
|
668 |
|
669 |
const fragmentShaderSource = `
|
670 |
precision mediump float;
|
671 |
|
672 |
+
varying vec4 vColor;
|
673 |
+
varying vec2 vPosition;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
674 |
|
675 |
+
void main () {
|
676 |
+
float A = -dot(vPosition, vPosition);
|
677 |
+
if (A < -4.0) discard;
|
678 |
+
float B = exp(A) * vColor.a;
|
679 |
+
gl_FragColor = vec4(B * vColor.rgb, B);
|
680 |
+
}
|
681 |
`;
|
682 |
|
683 |
let defaultViewMatrix = [
|
|
|
711 |
const reader = req.body.getReader();
|
712 |
let splatData = new Uint8Array(req.headers.get("content-length"));
|
713 |
|
714 |
+
const downsample = splatData.length / rowLength > 500000 ? 1 : 1 / devicePixelRatio;
|
715 |
+
// const downsample = 1 / devicePixelRatio;
|
716 |
+
// const downsample = 1;
|
717 |
console.log(splatData.length / rowLength, downsample);
|
718 |
|
719 |
const worker = new Worker(
|
|
|
797 |
gl.uniformMatrix4fv(u_view, false, viewMatrix);
|
798 |
|
799 |
// positions
|
800 |
+
const triangleVertices = new Float32Array([-2, -2, 2, -2, 2, 2, -2, 2]);
|
801 |
const vertexBuffer = gl.createBuffer();
|
802 |
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
|
803 |
gl.bufferData(gl.ARRAY_BUFFER, triangleVertices, gl.STATIC_DRAW);
|
|
|
826 |
gl.vertexAttribPointer(a_color, 4, gl.FLOAT, false, 0, 0);
|
827 |
ext.vertexAttribDivisorANGLE(a_color, 1); // Use the extension here
|
828 |
|
829 |
+
// cov
|
830 |
+
const covABuffer = gl.createBuffer();
|
831 |
+
const a_covA = gl.getAttribLocation(program, "covA");
|
832 |
+
gl.enableVertexAttribArray(a_covA);
|
833 |
+
gl.bindBuffer(gl.ARRAY_BUFFER, covABuffer);
|
834 |
+
gl.vertexAttribPointer(a_covA, 3, gl.FLOAT, false, 0, 0);
|
835 |
+
ext.vertexAttribDivisorANGLE(a_covA, 1); // Use the extension here
|
836 |
+
|
837 |
+
const covBBuffer = gl.createBuffer();
|
838 |
+
const a_covB = gl.getAttribLocation(program, "covB");
|
839 |
+
gl.enableVertexAttribArray(a_covB);
|
840 |
+
gl.bindBuffer(gl.ARRAY_BUFFER, covBBuffer);
|
841 |
+
gl.vertexAttribPointer(a_covB, 3, gl.FLOAT, false, 0, 0);
|
842 |
+
ext.vertexAttribDivisorANGLE(a_covB, 1); // Use the extension here
|
|
|
|
|
|
|
|
|
|
|
843 |
|
844 |
let lastProj = []
|
845 |
let lastData
|
|
|
856 |
document.body.appendChild(link);
|
857 |
link.click();
|
858 |
} else {
|
859 |
+
let { covA, covB, center, color, viewProj } = e.data;
|
860 |
lastData = e.data;
|
861 |
|
862 |
lastProj = viewProj
|
863 |
+
vertexCount = center.length / 3;
|
864 |
|
865 |
gl.bindBuffer(gl.ARRAY_BUFFER, centerBuffer);
|
866 |
gl.bufferData(gl.ARRAY_BUFFER, center, gl.STATIC_DRAW);
|
|
|
868 |
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
|
869 |
gl.bufferData(gl.ARRAY_BUFFER, color, gl.STATIC_DRAW);
|
870 |
|
871 |
+
|
872 |
+
gl.bindBuffer(gl.ARRAY_BUFFER, covABuffer);
|
873 |
+
gl.bufferData(gl.ARRAY_BUFFER, covA, gl.STATIC_DRAW);
|
874 |
+
|
875 |
+
gl.bindBuffer(gl.ARRAY_BUFFER, covBBuffer);
|
876 |
+
gl.bufferData(gl.ARRAY_BUFFER, covB, gl.STATIC_DRAW);
|
877 |
|
|
|
|
|
878 |
}
|
879 |
};
|
880 |
|
|
|
1207 |
|
1208 |
if (vertexCount > 0) {
|
1209 |
document.getElementById("spinner").style.display = "none";
|
1210 |
+
// console.time('render')
|
1211 |
gl.uniformMatrix4fv(u_view, false, actualViewMatrix);
|
1212 |
+
ext.drawArraysInstancedANGLE(gl.TRIANGLE_FAN, 0, 4, vertexCount);
|
1213 |
+
// console.timeEnd('render')
|
1214 |
} else {
|
1215 |
gl.clear(gl.COLOR_BUFFER_BIT);
|
1216 |
document.getElementById("spinner").style.display = "";
|
|
|
1220 |
if (progress < 100) {
|
1221 |
document.getElementById("progress").style.width = progress + "%";
|
1222 |
} else {
|
1223 |
+
document.getElementById("progress").style.display = "none";
|
1224 |
}
|
1225 |
fps.innerText = Math.round(avgFps) + " fps";
|
1226 |
lastFrame = now;
|