@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
83 lines (60 loc) • 2.62 kB
JavaScript
/**
*
* @param {Float32Array} output
* @param {Float32Array} input
* @param {number[]} resolution
*/
export function v3_grid_apply_diffusion(output, input, resolution) {
let sum = 0;
const res_x = resolution[0];
const res_y = resolution[1];
const res_z = resolution[2];
const slice_size = res_y * res_x;
// TODO consider taking inspiration from blur filters and performing convolution in 3 separate steps, one per axis. This would require fewer samples in total and potentially offer better cache utilization
const last_z_slice_offset = (res_z - 1) * slice_size;
const last_y_line_offset = (res_y - 1) * res_x;
for (
let current_z_slice_offset = 0;
current_z_slice_offset <= last_z_slice_offset;
current_z_slice_offset += slice_size
) {
for (
let current_y_line_offset = 0;
current_y_line_offset <= last_y_line_offset;
current_y_line_offset += res_x
) {
for (let x = 0; x < res_x; x++) {
let sample_count = 1;
sum = 0;
// sample cells around
if (current_z_slice_offset > 0) {
sample_count++;
sum += input[current_z_slice_offset - slice_size + current_y_line_offset + x]
}
if (current_y_line_offset > 0) {
sample_count++;
sum += input[current_z_slice_offset + current_y_line_offset - res_x + x]
}
if (x > 0) {
sample_count++;
sum += input[current_z_slice_offset + current_y_line_offset + (x - 1)]
}
const current = current_z_slice_offset + current_y_line_offset + x;
sum += input[current];
if (x < res_x - 1) {
sample_count++;
sum += input[current_z_slice_offset + current_y_line_offset + (x + 1)]
}
if (current_y_line_offset < last_y_line_offset) {
sample_count++;
sum += input[current_z_slice_offset + current_y_line_offset + res_x + x]
}
if (current_z_slice_offset < last_z_slice_offset) {
sample_count++;
sum += input[current_z_slice_offset + slice_size + current_y_line_offset + x]
}
output[current] = sum / sample_count;
}
}
}
}