@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
96 lines (69 loc) • 2.99 kB
JavaScript
import { assert } from "../../../../core/assert.js";
import TaskGroup from "../../../../core/process/task/TaskGroup.js";
import { actionTask } from "../../../../core/process/task/util/actionTask.js";
import { countTask } from "../../../../core/process/task/util/countTask.js";
import { promiseTask } from "../../../../core/process/task/util/promiseTask.js";
import { find_max_depth_radius_for_point } from "./find_max_depth_radius_for_point.js";
import { PathTracerProbeRenderer } from "./PathTracerProbeRenderer.js";
export class LightProbeVolumeBaker {
_ren = new PathTracerProbeRenderer();
/**
* Bake light probes
* @returns {TaskGroup}
* @param {LightProbeVolume} lpv
* @param {EntityComponentDataset} ecd
*/
bake(lpv, ecd) {
const renderer = this._ren;
const tPrepare = promiseTask(new Promise(async (resolve, reject) => {
renderer.build_scene(ecd);
await renderer.bake_start(ecd);
resolve();
}), 'Prepare');
const probe_count = lpv.count;
const tBakeIrradiance = countTask(0, probe_count, (probe_index) => {
this.bake_probe(renderer, lpv, probe_index);
});
tBakeIrradiance.estimatedDuration = probe_count;
tBakeIrradiance.promise().then(() => {
const duration = tBakeIrradiance.__executedCpuTime;
console.log(`Baked ${probe_count} probes in ${duration}ms, ~${(duration / probe_count).toFixed(2)}ms per probe`);
});
const tFinish = actionTask(() => {
renderer.bake_end();
lpv.incrementVersion();
});
tFinish.addDependency(tBakeIrradiance);
tBakeIrradiance.addDependency(tPrepare);
return new TaskGroup([
tPrepare, tBakeIrradiance, tFinish
], "LightProbeVolume Bake");
}
/**
*
* @param {PathTracerProbeRenderer} renderer
* @param {LightProbeVolume} lpv
* @param {number} probe_index
*/
bake_probe(renderer, lpv, probe_index) {
assert.isNonNegativeInteger(probe_index, 'probe_index');
const position_offset = probe_index * 3;
// Bake color
renderer.bake(
lpv.points, position_offset,
lpv.harmonics, probe_index * 9 * 3
);
// Bake depth
const max_distance = find_max_depth_radius_for_point(probe_index, lpv.mesh, lpv.points);
// bias a little to ensure we capture everything
const max_depth = max_distance * 1.01 + 1e-6;
const depth_resolution = lpv.depth_map_resolution;
const probe_element_count = depth_resolution * depth_resolution;
renderer.bake_depth_octahedral(
depth_resolution,
max_depth,
lpv.points, position_offset,
lpv.depth, probe_index * probe_element_count * 2
);
}
}