poppygl 0.0.28 → 0.0.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +96 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -503,9 +503,86 @@ function srgbEncodeLinear01(linear) {
|
|
|
503
503
|
return 1.055 * Math.pow(linear, 1 / 2.4) - 0.055;
|
|
504
504
|
}
|
|
505
505
|
|
|
506
|
+
// lib/utils/srgbDecodeToLinear01.ts
|
|
507
|
+
function srgbDecodeToLinear01(srgb) {
|
|
508
|
+
if (srgb <= 0.04045) return srgb / 12.92;
|
|
509
|
+
return ((srgb + 0.055) / 1.055) ** 2.4;
|
|
510
|
+
}
|
|
511
|
+
|
|
506
512
|
// lib/utils/clamp.ts
|
|
507
513
|
var clamp = (value, min, max) => Math.max(min, Math.min(max, value));
|
|
508
514
|
|
|
515
|
+
// lib/render/clipMeshToNearPlane.ts
|
|
516
|
+
function clipMeshToNearPlane(mesh, mvp) {
|
|
517
|
+
const count = mesh.positions.length / 3;
|
|
518
|
+
const distances = new Float64Array(count);
|
|
519
|
+
let needsClipping = false;
|
|
520
|
+
for (let i = 0; i < count; i++) {
|
|
521
|
+
const distance = (mvp[2] + mvp[3]) * mesh.positions[i * 3] + (mvp[6] + mvp[7]) * mesh.positions[i * 3 + 1] + (mvp[10] + mvp[11]) * mesh.positions[i * 3 + 2] + mvp[14] + mvp[15];
|
|
522
|
+
distances[i] = distance;
|
|
523
|
+
if (!(distance >= 0)) needsClipping = true;
|
|
524
|
+
}
|
|
525
|
+
if (!needsClipping) return mesh;
|
|
526
|
+
const positions = Array.from(mesh.positions);
|
|
527
|
+
const normals = mesh.normals ? Array.from(mesh.normals) : null;
|
|
528
|
+
const uvs = mesh.uvs ? Array.from(mesh.uvs) : null;
|
|
529
|
+
const colors = mesh.colors ? Array.from(mesh.colors) : null;
|
|
530
|
+
const indices = [];
|
|
531
|
+
const sourceIndices = mesh.indices ?? Uint32Array.from({ length: count }, (_, i) => i);
|
|
532
|
+
const intersections = /* @__PURE__ */ new Map();
|
|
533
|
+
const intersect = (a, b) => {
|
|
534
|
+
if (a > b) [a, b] = [b, a];
|
|
535
|
+
if (distances[a] === 0) return a;
|
|
536
|
+
if (distances[b] === 0) return b;
|
|
537
|
+
const key = `${a}:${b}`;
|
|
538
|
+
const cached = intersections.get(key);
|
|
539
|
+
if (cached !== void 0) return cached;
|
|
540
|
+
const t = distances[a] / (distances[a] - distances[b]);
|
|
541
|
+
const index = positions.length / 3;
|
|
542
|
+
const interpolate = (values, size) => {
|
|
543
|
+
if (!values) return;
|
|
544
|
+
for (let k = 0; k < size; k++) {
|
|
545
|
+
const start = values[a * size + k];
|
|
546
|
+
values.push(start + t * (values[b * size + k] - start));
|
|
547
|
+
}
|
|
548
|
+
};
|
|
549
|
+
interpolate(positions, 3);
|
|
550
|
+
interpolate(normals, 3);
|
|
551
|
+
interpolate(uvs, 2);
|
|
552
|
+
interpolate(colors, 3);
|
|
553
|
+
intersections.set(key, index);
|
|
554
|
+
return index;
|
|
555
|
+
};
|
|
556
|
+
for (let i = 0; i < sourceIndices.length; i += 3) {
|
|
557
|
+
const triangle = [
|
|
558
|
+
sourceIndices[i],
|
|
559
|
+
sourceIndices[i + 1],
|
|
560
|
+
sourceIndices[i + 2]
|
|
561
|
+
];
|
|
562
|
+
if (triangle.some((vertex) => !Number.isFinite(distances[vertex]))) continue;
|
|
563
|
+
const polygon = [];
|
|
564
|
+
for (let j = 0; j < 3; j++) {
|
|
565
|
+
const a = triangle[j];
|
|
566
|
+
const b = triangle[(j + 1) % 3];
|
|
567
|
+
const aInside = distances[a] >= 0;
|
|
568
|
+
const bInside = distances[b] >= 0;
|
|
569
|
+
if (aInside) polygon.push(a);
|
|
570
|
+
if (aInside !== bInside) polygon.push(intersect(a, b));
|
|
571
|
+
}
|
|
572
|
+
for (let j = 1; j + 1 < polygon.length; j++) {
|
|
573
|
+
indices.push(polygon[0], polygon[j], polygon[j + 1]);
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
return {
|
|
577
|
+
...mesh,
|
|
578
|
+
positions: new Float32Array(positions),
|
|
579
|
+
normals: normals ? new Float32Array(normals) : null,
|
|
580
|
+
uvs: uvs ? new Float32Array(uvs) : null,
|
|
581
|
+
colors: colors ? new Float32Array(colors) : null,
|
|
582
|
+
indices: new Uint32Array(indices)
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
|
|
509
586
|
// lib/render/SoftwareRenderer.ts
|
|
510
587
|
var SoftwareRenderer = class {
|
|
511
588
|
width;
|
|
@@ -676,15 +753,15 @@ var SoftwareRenderer = class {
|
|
|
676
753
|
return out;
|
|
677
754
|
}
|
|
678
755
|
drawMesh(mesh, camera, light, material, cullBackFaces = true, gammaOut = true) {
|
|
679
|
-
|
|
756
|
+
let { positions, normals, uvs, indices, model, colors } = mesh;
|
|
680
757
|
const view = camera.view;
|
|
681
758
|
const proj = camera.proj;
|
|
682
759
|
const mvp = mat43.create();
|
|
683
760
|
mat43.multiply(mvp, proj, mat43.multiply(mat43.create(), view, model));
|
|
684
761
|
const normalMat = mat3.create();
|
|
685
762
|
mat3.normalFromMat4(normalMat, model);
|
|
686
|
-
|
|
687
|
-
|
|
763
|
+
let vertexCount = positions.length / 3 | 0;
|
|
764
|
+
let idx = indices ?? (() => {
|
|
688
765
|
const a = new Uint32Array(vertexCount);
|
|
689
766
|
for (let i = 0; i < vertexCount; i++) a[i] = i;
|
|
690
767
|
return a;
|
|
@@ -693,6 +770,16 @@ var SoftwareRenderer = class {
|
|
|
693
770
|
if (!useNormals) {
|
|
694
771
|
useNormals = computeSmoothNormals(positions, idx);
|
|
695
772
|
}
|
|
773
|
+
const clipped = clipMeshToNearPlane(
|
|
774
|
+
{ ...mesh, normals: useNormals, indices: idx },
|
|
775
|
+
mvp
|
|
776
|
+
);
|
|
777
|
+
positions = clipped.positions;
|
|
778
|
+
useNormals = clipped.normals;
|
|
779
|
+
uvs = clipped.uvs;
|
|
780
|
+
colors = clipped.colors;
|
|
781
|
+
idx = clipped.indices;
|
|
782
|
+
vertexCount = positions.length / 3;
|
|
696
783
|
const vScreen = new Array(vertexCount);
|
|
697
784
|
const vInvW = new Float32Array(vertexCount);
|
|
698
785
|
const vNDCz = new Float32Array(vertexCount);
|
|
@@ -808,7 +895,12 @@ var SoftwareRenderer = class {
|
|
|
808
895
|
uvp[0],
|
|
809
896
|
uvp[1]
|
|
810
897
|
);
|
|
811
|
-
baseColor = mulColor(baseColor,
|
|
898
|
+
baseColor = mulColor(baseColor, [
|
|
899
|
+
srgbDecodeToLinear01(texel[0]),
|
|
900
|
+
srgbDecodeToLinear01(texel[1]),
|
|
901
|
+
srgbDecodeToLinear01(texel[2]),
|
|
902
|
+
texel[3]
|
|
903
|
+
]);
|
|
812
904
|
}
|
|
813
905
|
const [cr, cg, cb] = this.perspInterp(cs, invW, [l0, l1, l2]);
|
|
814
906
|
baseColor = [
|