import Vector2 from "../../../../core/geom/Vector2.js";
import { WebGLRendererPool } from "../../../graphics/render/RendererPool.js";
import { writeSample2DDataToDataTexture } from "../../../graphics/texture/sampler/writeSampler2DDataToDataTexture.js";
import heightMap2AOMap from "../../grid/HeightMap2AOMap.js";

/**
 * Bake a terrain ambient-occlusion / visibility lightmap into `texture`.
 *
 * Uses {@link heightMap2AOMap} which traces `rayCount` cosine-weighted rays
 * per output texel against a Hi-Z height pyramid of the heightmap. See
 * {@link AmbientOcclusionShader} for the tracer details and trade-offs.
 *
 * @param {THREE.DataTexture} texture  target lightmap (red channel written)
 * @param {Sampler2D} heightSampler    single-channel Float32 heightmap
 * @param {Vector2} [resolution]       output AO resolution; defaults to
 *   texture dimensions
 * @param {Vector2} [worldSize]        terrain XZ extent in world units;
 *   defaults to the AO resolution (= 1 world unit per output texel)
 * @param {number} [rayCount=64]       Monte Carlo samples per output texel.
 *   Higher = less noise, longer bake. Noise falls as 1 / sqrt(rayCount).
 * @returns {Promise<void>}
 */
export function buildLightTexture({
                                      texture,
                                      heightSampler,
                                      resolution = new Vector2(texture.image.width, texture.image.height),
                                      worldSize = resolution,
                                      rayCount = 64
                                  }) {

    return WebGLRendererPool.global.useAsync(async renderer => {
        console.time("generating AO map");
        const ao = heightMap2AOMap(
            renderer,
            heightSampler,
            resolution,
            worldSize,
            rayCount
        );
        console.timeEnd("generating AO map");

        writeSample2DDataToDataTexture(ao, texture);
    });
}
