"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module WebGL
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.createEVSMProgram = createEVSMProgram;
const AttributeMap_1 = require("../AttributeMap");
const RenderFlags_1 = require("../RenderFlags");
const ShaderBuilder_1 = require("../ShaderBuilder");
const Texture_1 = require("../Texture");
const Fragment_1 = require("./Fragment");
const SolarShadowMapping_1 = require("./SolarShadowMapping");
// This shader reads the depth texture, converts it to EVSM values, then averages those down 4 to 1
// Positions are in NDC [-1..1]. Compute UV params in [0..1]
const computeTexCoord = "v_texCoord = (rawPosition.xy + 1.0) * 0.5;";
const computePosition = "return rawPos;";
const computeEVSM = `
  const float sampleWeight = 0.25;
  vec4 average = vec4(0.0);
  vec2 tc = v_texCoord - u_stepSize * 0.5; // v_texCoord starts in between the 4 texels

  float depth = TEXTURE(u_depthTexture, tc).r;
  vec2 vsmDepth = warpDepth(depth, u_evsmExponent);
  average += sampleWeight * vec4(vsmDepth.xy, vsmDepth.xy * vsmDepth.xy);

  tc.x += u_stepSize.x;
  depth = TEXTURE(u_depthTexture, tc).r;
  vsmDepth = warpDepth(depth, u_evsmExponent);
  average += sampleWeight * vec4(vsmDepth.xy, vsmDepth.xy * vsmDepth.xy);

  tc.y += u_stepSize.y;
  depth = TEXTURE(u_depthTexture, tc).r;
  vsmDepth = warpDepth(depth, u_evsmExponent);
  average += sampleWeight * vec4(vsmDepth.xy, vsmDepth.xy * vsmDepth.xy);

  tc.x -= u_stepSize.x;
  depth = TEXTURE(u_depthTexture, tc).r;
  vsmDepth = warpDepth(depth, u_evsmExponent);
  average += sampleWeight * vec4(vsmDepth.xy, vsmDepth.xy * vsmDepth.xy);

  return average;
`;
/** @internal */
function createEVSMProgram(context) {
    const builder = new ShaderBuilder_1.ProgramBuilder(AttributeMap_1.AttributeMap.findAttributeMap(undefined, false));
    const vert = builder.vert;
    const frag = builder.frag;
    vert.set(10 /* VertexShaderComponent.ComputePosition */, computePosition);
    builder.addInlineComputedVarying("v_texCoord", 3 /* VariableType.Vec2 */, computeTexCoord);
    frag.addUniform("u_depthTexture", 8 /* VariableType.Sampler2D */, (prog) => {
        prog.addGraphicUniform("u_depthTexture", (uniform, params) => {
            const geom = params.geometry;
            Texture_1.Texture2DHandle.bindSampler(uniform, geom.depthTexture, RenderFlags_1.TextureUnit.Zero);
        });
    });
    frag.addUniform("u_stepSize", 3 /* VariableType.Vec2 */, (prog) => {
        prog.addGraphicUniform("u_stepSize", (uniform, params) => {
            const geom = params.geometry;
            uniform.setUniform2fv(geom.stepSize);
        });
    }, 3 /* VariablePrecision.High */);
    (0, SolarShadowMapping_1.addEvsmExponent)(frag);
    frag.addFunction(SolarShadowMapping_1.warpDepth);
    frag.set(1 /* FragmentShaderComponent.ComputeBaseColor */, computeEVSM);
    frag.set(18 /* FragmentShaderComponent.AssignFragData */, Fragment_1.assignFragColor);
    builder.vert.headerComment = "//!V! EVSMFromDepth";
    builder.frag.headerComment = "//!F! EVSMFromDepth";
    return builder.buildProgram(context);
}
//# sourceMappingURL=EVSMFromDepth.js.map