import { AbstractPostEffect } from '../posteffect/posteffect.js';
import '@zephyr3d/base';
import './primitive.js';
import { BoxShape } from '../shapes/box.js';
import '../shapes/cylinder.js';
import '../shapes/torus.js';
import '../shapes/plane.js';
import '../shapes/sphere.js';
import '../shapes/tetrahedron.js';

let _skyMotionVectorProgram = null;
let _skyMotionVectorBindGroup = null;
let _box = null;
function getSkyMotionVectorProgram(ctx) {
    if (!_skyMotionVectorProgram) {
        _skyMotionVectorProgram = ctx.device.buildRenderProgram({
            vertex (pb) {
                this.$inputs.pos = pb.vec3().attrib('position');
                this.VPMatrix = pb.mat4().uniform(0);
                this.prevVPMatrix = pb.mat4().uniform(0);
                this.cameraPos = pb.vec3().uniform(0);
                this.prevCameraPos = pb.vec3().uniform(0);
                pb.main(function() {
                    this.$l.worldPos = pb.add(this.$inputs.pos, this.cameraPos);
                    this.$l.prevWorldPos = pb.add(this.$inputs.pos, this.prevCameraPos);
                    this.$l.clipPos = pb.mul(this.VPMatrix, pb.vec4(this.worldPos, 1));
                    this.$l.prevClipPos = pb.mul(this.prevVPMatrix, pb.vec4(this.prevWorldPos, 1));
                    this.clipPos.z = this.clipPos.w;
                    this.$builtins.position = this.clipPos;
                    this.$outputs.currentPos = this.clipPos;
                    this.$outputs.prevPos = this.prevClipPos;
                });
            },
            fragment (pb) {
                this.$outputs.color = pb.vec4();
                pb.main(function() {
                    this.$l.motionVector = pb.mul(pb.sub(pb.div(this.$inputs.currentPos.xy, this.$inputs.currentPos.w), pb.div(this.$inputs.prevPos.xy, this.$inputs.prevPos.w)), 0.5);
                    this.$outputs.color = pb.vec4(this.motionVector, 0, 1);
                });
            }
        });
        _skyMotionVectorProgram.name = '@TAA_SkyMotionVector';
    }
    return _skyMotionVectorProgram;
}
function getBox() {
    if (!_box) {
        _box = new BoxShape({
            size: 2,
            needNormal: false,
            needUV: false
        });
    }
    return _box;
}
/**
 * Renders sky motion vectors into ctx.motionVectorTexture.
 * Must be called after opaque pass with ctx.motionVectorTexture set.
 * @internal
 */ function renderSkyMotionVectors(ctx) {
    if (!ctx.motionVectorTexture) {
        return;
    }
    const fb = ctx.device.pool.fetchTemporalFramebuffer(false, 0, 0, ctx.motionVectorTexture, ctx.depthTexture);
    const program = getSkyMotionVectorProgram(ctx);
    if (!_skyMotionVectorBindGroup) {
        _skyMotionVectorBindGroup = ctx.device.createBindGroup(program.bindGroupLayouts[0]);
    }
    const box = getBox();
    _skyMotionVectorBindGroup.setValue('VPMatrix', ctx.camera.viewProjectionMatrix);
    _skyMotionVectorBindGroup.setValue('prevVPMatrix', ctx.camera.prevVPMatrix);
    _skyMotionVectorBindGroup.setValue('cameraPos', ctx.camera.getWorldPosition());
    _skyMotionVectorBindGroup.setValue('prevCameraPos', ctx.camera.prevPosition);
    ctx.device.pushDeviceStates();
    ctx.device.setProgram(program);
    ctx.device.setBindGroup(0, _skyMotionVectorBindGroup);
    ctx.device.setRenderStates(AbstractPostEffect.getDefaultRenderState(ctx, 'le'));
    ctx.device.setFramebuffer(fb);
    box.draw();
    ctx.device.popDeviceStates();
    ctx.device.pool.releaseFrameBuffer(fb);
}

export { renderSkyMotionVectors };
//# sourceMappingURL=sky_motion_vector.js.map
