@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
72 lines (55 loc) • 2.3 kB
JavaScript
import { array_copy } from "../../../../../core/collection/array/array_copy.js";
import { Ray3 } from "../../../../../core/geom/3d/ray/Ray3.js";
import { sh3_basis_at } from "../../../../../core/geom/3d/sphere/harmonics/sh3_basis_at.js";
import { sh3_vector_accumulate } from "../../../../../core/geom/3d/sphere/harmonics/sh3_vector_accumulate.js";
import { vector_scale_array } from "../../../../../core/geom/vec/vector_scale_array.js";
import { clamp01 } from "../../../../../core/math/clamp01.js";
import { OctahedralUvEncoder } from "../../../impostors/octahedral/grid/OctahedralUvEncoder.js";
/**
*
* @param {number[]} result
* @param {number} result_offset
* @param {PathTracedScene} scene
* @param {number} position_x
* @param {number} position_y
* @param {number} position_z
* @param {number} max_depth
* @param {number} resolution
*/
export function sh3_bake_depth(
result, result_offset,
scene,
position_x, position_y, position_z,
max_depth = 2,
resolution = 12
) {
const ray = new Ray3();
const ray_hit = [];
const basis = new Float32Array(9);
const sh = new Float32Array(9);
ray.origin.set(position_x, position_y, position_z);
ray.tMax = max_depth;
const encoder = new OctahedralUvEncoder();
for (let y = 0; y < resolution; y++) {
for (let x = 0; x < resolution; x++) {
const u = x / (resolution - 1);
const v = y / (resolution - 1);
encoder.uv_to_unit(ray.direction, [u, v])
let distance = scene.trace(ray_hit, ray);
if (distance < 0) {
distance = 100;
}
distance = clamp01(1 - distance / max_depth);
sh3_basis_at(ray.direction.x, ray.direction.y, ray.direction.z, basis);
sh3_vector_accumulate(
sh, 0,
basis, 0,
[distance], 0, 1
);
}
}
// Note that we do not scale the depth samples by sphere surface area as we are not attempting to approximate radiance
const normalization_weight = 1 / resolution * resolution;
vector_scale_array(sh, 0, sh, 0, 27, normalization_weight);
array_copy(sh, 0, result, result_offset, 9);
}