function* main(w, h, samplesCount = 4) {
const position = new Vec(-22, 5, 25);
const goal = new Vec(-3, 4, 0).sub(position).norm();
const left = new Vec(goal.z, 0, -goal.x).norm().mul(1 / w);
// Cross-product to get the up vector
const up = new Vec(
goal.y * left.z - goal.z * left.y,
goal.z * left.x - goal.x * left.z,
goal.x * left.y - goal.y * left.x
);
const imgData = new ImageData(w, h);
for(let x = w; x--;) {
for(let y = h; y--;) {
let color = new Vec;
for(let p = samplesCount; p--;) {
color = color.add(trace(
position,
goal
.add(left.mul(x - w / 2 + rng()))
.add(up.mul(y - h / 2 + rng()))
.norm()
));
}
// Reinhard tone mapping
color = color.mul(1 / samplesCount);
imgData.data.set([
color.x / (color.x + 1) * 255,
color.y / (color.y + 1) * 255,
color.z / (color.z + 1) * 255,
255
], imgData.data.length - (1 + x + y * w) * 4);
}
yield imgData;
}
}