UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

96 lines (69 loc) 2.99 kB
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 ); } }