UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

110 lines (83 loc) 3.58 kB
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_dering_optimize_positive } from "../../../../core/geom/3d/sphere/harmonics/sh3_dering_optimize_positive.js"; import { sh3_vector_accumulate } from "../../../../core/geom/3d/sphere/harmonics/sh3_vector_accumulate.js"; import { randomPointOnSphere } from "../../../../core/geom/random/randomPointOnSphere.js"; import { vector_scale_array } from "../../../../core/geom/vec/vector_scale_array.js"; import { seededRandom } from "../../../../core/math/random/seededRandom.js"; import { PathTracedScene } from "../path_tracer/PathTracedScene.js"; import { PathTracer } from "../path_tracer/PathTracer.js"; import { populate_path_traced_scene_from_ecd } from "../path_tracer/populate_path_traced_scene_from_ecd.js"; import { bake_octahedral_depth_map } from "./depth/octahedral/bake_octahedral_depth_map.js"; import { ProbeRenderer } from "./ProbeRenderer.js"; const __shared_buffer = new ArrayBuffer((27 + 9) * 8); const sh_basis = new Float64Array(__shared_buffer, 0, 9); const coefficients = new Float64Array(__shared_buffer, 9 * 8, 27); const ray = new Ray3(); const sampled_irradiance = new Float32Array(3); export class PathTracerProbeRenderer extends ProbeRenderer { tracer = new PathTracer(); max_bounce_count = 5; // sample_count = 256; sample_count = 4096; // sample_count = 40960; random = seededRandom(0); scene = new PathTracedScene() /** * * @param {number} resolution * @param {number} max_depth * @param {number[]} position * @param {number} position_offset * @param {number[]} output * @param {number} output_offset */ bake_depth_octahedral( resolution, max_depth, position, position_offset, output, output_offset ) { bake_octahedral_depth_map( output, output_offset, this.scene, position, position_offset, resolution, max_depth, 16 ); } bake(position, position_offset, output, output_offset) { const tracer = this.tracer; array_copy(position, position_offset, ray, 0, 3); coefficients.fill(0); const max_bounce = this.max_bounce_count; for (let i = 0; i < this.sample_count; i++) { randomPointOnSphere(this.random, ray, 3); ray.tMax = Infinity; ray.tMin = 0; tracer.path_trace(sampled_irradiance, ray, 1, max_bounce, this.random, this.scene); sh3_basis_at(ray[3], ray[4], ray[5], sh_basis); // accumulate sh3_vector_accumulate( coefficients, 0, sh_basis, 0, sampled_irradiance, 0, 3 ); } // Area of a unit sphere is (4*PI) const normalization_weight = (4 * Math.PI) / this.sample_count; vector_scale_array(coefficients, 0, coefficients, 0, 27, normalization_weight); sh3_dering_optimize_positive(coefficients, 0, coefficients, 0, 3); array_copy(coefficients, 0, output, output_offset, 27); } bake_end() { } bake_start() { } build_scene(ecd) { const scene = this.scene; populate_path_traced_scene_from_ecd(ecd, scene); } }