@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
71 lines (49 loc) • 2.01 kB
JavaScript
import { max2 } from "../../../../../core/math/max2.js";
import { assert } from "../../../../../core/assert.js";
/**
* Relatively slow, but handles all cases
* @param {Sampler2D} input
* @param {Sampler2D} output
*/
export function sampler2d_scale_generic(input, output) {
assert.defined(input, 'input');
assert.defined(output, 'output');
const target_width = output.width;
const target_height = output.height;
// build kernel
const u_scale = input.width / target_width;
const v_scale = input.height / target_height;
const kernel_width = max2(1, Math.ceil(u_scale));
const kernel_height = max2(1, Math.ceil(v_scale));
const kernel_size = kernel_width * kernel_height;
const kernel_size_inv = 1 / kernel_size;
const itemSize = input.itemSize;
const sample = new Float32Array(itemSize);
let column_index;
let row_index;
let k_y;
let k_x;
let i;
for (column_index = 0; column_index < target_height; column_index++) {
const source_y = column_index * v_scale;
for (row_index = 0; row_index < target_width; row_index++) {
// figure out source offset
const source_x = row_index * u_scale;
const output_texel_address = (column_index * target_width + row_index) * itemSize;
// accumulate kernel samples
for (k_y = 0; k_y < kernel_height; k_y++) {
for (k_x = 0; k_x < kernel_width; k_x++) {
for (i = 0; i < itemSize; i++) {
sample[i] += input.sampleChannelBilinear(source_x + k_x, source_y + k_y, i);
}
}
}
for (i = 0; i < itemSize; i++) {
// dilute sample
output.data[output_texel_address + i] = sample[i] * kernel_size_inv;
//reset sample
sample[i] = 0;
}
}
}
}