tela.js 1.2.6 → 1.2.7
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/README.md +1 -1
- package/package.json +1 -1
- package/src/Camera/raster.js +3 -2
- package/src/Color/Color.js +2 -1
- package/src/Geometry/Box.js +2 -1
- package/src/Geometry/Triangle.js +36 -3
package/README.md
CHANGED
|
@@ -78,7 +78,7 @@ loop(({ time, dt }) => {
|
|
|
78
78
|
And run it: `node index.mjs` / `bun index.js`
|
|
79
79
|
|
|
80
80
|
> Note: [Attention to running node with ES6 imports module](https://nodejs.org/api/esm.html#modules-ecmascript-modules)
|
|
81
|
-
|
|
81
|
+
> Note: If you're using `bun` and the `Window`, which uses `@kmamal/sdl` as dependency, make sure to run `bun pm trust @kmamal/sdl`.
|
|
82
82
|
|
|
83
83
|
## Generate images and videos
|
|
84
84
|
|
package/package.json
CHANGED
package/src/Camera/raster.js
CHANGED
|
@@ -234,10 +234,11 @@ function rasterTriangle({ canvas, camera, elem, w, h, zBuffer, params }) {
|
|
|
234
234
|
}
|
|
235
235
|
const [i, j] = canvas.canvas2grid(x, y);
|
|
236
236
|
const zBufferIndex = Math.floor(w * i + j);
|
|
237
|
-
if (z < zBuffer[zBufferIndex]) {
|
|
237
|
+
if (z < zBuffer[zBufferIndex] && c.alpha >= 1) {
|
|
238
238
|
zBuffer[zBufferIndex] = z;
|
|
239
|
-
return
|
|
239
|
+
return c;
|
|
240
240
|
}
|
|
241
|
+
return Math.random() < c.alpha ? c : undefined;
|
|
241
242
|
}
|
|
242
243
|
canvas.drawTriangle(intPoints[0], intPoints[1], intPoints[2], shader);
|
|
243
244
|
}
|
package/src/Color/Color.js
CHANGED
|
@@ -7,7 +7,7 @@ import { MAX_8BIT, RAD2DEG } from "../Utils/Constants.js";
|
|
|
7
7
|
*/
|
|
8
8
|
export default class Color {
|
|
9
9
|
constructor(rgb, alpha = 1.0) {
|
|
10
|
-
this.rgb = rgb;
|
|
10
|
+
this.rgb = rgb.map(x => Number.isNaN(x) ? 0 : x);
|
|
11
11
|
this.alpha = alpha;
|
|
12
12
|
}
|
|
13
13
|
|
|
@@ -112,4 +112,5 @@ export default class Color {
|
|
|
112
112
|
static WHITE = Color.ofRGB(1, 1, 1);
|
|
113
113
|
static GRAY = Color.ofRGB(0.5, 0.5, 0.5);
|
|
114
114
|
static GREY = Color.ofRGB(0.5, 0.5, 0.5);
|
|
115
|
+
static BROWN = Color.ofRGB(0.345,0.2235,0.1529);
|
|
115
116
|
}
|
package/src/Geometry/Box.js
CHANGED
|
@@ -26,10 +26,11 @@ export default class Box {
|
|
|
26
26
|
normalToPoint(pointVec) {
|
|
27
27
|
const epsilon = 1e-3;
|
|
28
28
|
const n = pointVec.dim;
|
|
29
|
+
const En = Vec.e(n);
|
|
29
30
|
const grad = [];
|
|
30
31
|
const d = this.distanceToPoint(pointVec);
|
|
31
32
|
for (let i = 0; i < n; i++) {
|
|
32
|
-
grad.push(this.distanceToPoint(pointVec.add(
|
|
33
|
+
grad.push(this.distanceToPoint(pointVec.add(En(i).scale(epsilon))) - d)
|
|
33
34
|
}
|
|
34
35
|
let sign = Math.sign(d);
|
|
35
36
|
sign = sign === 0 ? 1 : sign;
|
package/src/Geometry/Triangle.js
CHANGED
|
@@ -6,7 +6,7 @@ import { deserialize as deserializeImage } from "../Tela/utils.js";
|
|
|
6
6
|
import { generateUniqueID } from "../Utils/Utils.js";
|
|
7
7
|
|
|
8
8
|
export default class Triangle {
|
|
9
|
-
constructor({ name, positions, colors, texCoords, normals, texture, emissive, material }) {
|
|
9
|
+
constructor({ name, positions, colors, texCoords, normals, texture, emissive, material, radius }) {
|
|
10
10
|
this.name = name;
|
|
11
11
|
this.colors = colors;
|
|
12
12
|
this.normals = normals;
|
|
@@ -15,6 +15,7 @@ export default class Triangle {
|
|
|
15
15
|
this.texCoords = texCoords;
|
|
16
16
|
this.emissive = emissive;
|
|
17
17
|
this.material = material;
|
|
18
|
+
this.radius = radius;
|
|
18
19
|
this.edges = [];
|
|
19
20
|
const n = this.positions.length;
|
|
20
21
|
for (let i = 0; i < n; i++) {
|
|
@@ -25,6 +26,16 @@ export default class Triangle {
|
|
|
25
26
|
const v = this.tangents[1];
|
|
26
27
|
const cross = u.cross(v);
|
|
27
28
|
this.faceNormal = Number.isFinite(cross) ? Vec3(0, 0, cross) : cross?.normalize();
|
|
29
|
+
|
|
30
|
+
// precompute inverse of matrix [u, v]^T [u, v]
|
|
31
|
+
const a = u.dot(u);
|
|
32
|
+
const b = u.dot(v);
|
|
33
|
+
const c = b;
|
|
34
|
+
const d = v.dot(v);
|
|
35
|
+
const detInv = 1 / (a * d - b * c);
|
|
36
|
+
this.isDegenerate = !Number.isFinite(detInv) || Number.isNaN(detInv)
|
|
37
|
+
this.invU1 = Vec2(d, -b).scale(detInv)
|
|
38
|
+
this.invU2 = Vec2(-c, a).scale(detInv);
|
|
28
39
|
}
|
|
29
40
|
|
|
30
41
|
getBoundingBox() {
|
|
@@ -34,11 +45,26 @@ export default class Triangle {
|
|
|
34
45
|
}
|
|
35
46
|
|
|
36
47
|
distanceToPoint(p) {
|
|
37
|
-
|
|
38
|
-
return
|
|
48
|
+
const r = p.sub(this.positions[0]);
|
|
49
|
+
if (this.isDegenerate) return r.length() - this.radius;
|
|
50
|
+
const x = Vec2(this.tangents[0].dot(r), this.tangents[1].dot(r));
|
|
51
|
+
let alpha = Vec2(this.invU1.dot(x), this.invU2.dot(x)).map(x => x < 0 ? 0 : x);
|
|
52
|
+
const sum = alpha.fold((e, x) => e + x, 0)
|
|
53
|
+
if (sum > 1) {
|
|
54
|
+
alpha = alpha.scale(1 / sum);
|
|
55
|
+
}
|
|
56
|
+
const pointOnTriangle = this.positions[0]
|
|
57
|
+
.add(
|
|
58
|
+
this.tangents[0].scale(alpha.x)
|
|
59
|
+
.add(
|
|
60
|
+
this.tangents[1].scale(alpha.y)
|
|
61
|
+
)
|
|
62
|
+
)
|
|
63
|
+
return p.sub(pointOnTriangle).length() - this.radius;
|
|
39
64
|
}
|
|
40
65
|
|
|
41
66
|
normalToPoint(p) {
|
|
67
|
+
// fixes problem in ray tracing
|
|
42
68
|
const r = p.sub(this.positions[0]);
|
|
43
69
|
const dot = this.faceNormal.dot(r);
|
|
44
70
|
return dot < 1e-3 ? this.faceNormal : this.faceNormal.scale(-1);
|
|
@@ -112,6 +138,7 @@ class TriangleBuilder {
|
|
|
112
138
|
this._colors = indx.map(() => Color.BLACK);
|
|
113
139
|
this._positions = indx.map(() => Vec3());
|
|
114
140
|
this._texCoords = [Vec2(), Vec2(1, 0), Vec2(0, 1)];
|
|
141
|
+
this._radius = 1;
|
|
115
142
|
this._emissive = false;
|
|
116
143
|
this._material = Diffuse();
|
|
117
144
|
}
|
|
@@ -121,6 +148,11 @@ class TriangleBuilder {
|
|
|
121
148
|
return this;
|
|
122
149
|
}
|
|
123
150
|
|
|
151
|
+
radius(radius) {
|
|
152
|
+
this._radius = radius;
|
|
153
|
+
return this;
|
|
154
|
+
}
|
|
155
|
+
|
|
124
156
|
positions(v1, v2, v3) {
|
|
125
157
|
if ([v1, v2, v3].some(x => !x)) return this;
|
|
126
158
|
this._positions = [v1, v2, v3];
|
|
@@ -163,6 +195,7 @@ class TriangleBuilder {
|
|
|
163
195
|
build() {
|
|
164
196
|
const attrs = {
|
|
165
197
|
name: this._name,
|
|
198
|
+
radius: this._radius,
|
|
166
199
|
colors: this._colors,
|
|
167
200
|
normals: this._normals,
|
|
168
201
|
positions: this._positions,
|