@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
110 lines (83 loc) • 3.58 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_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);
}
}