import { GLSL3, ShaderMaterial, Vector2 } from "three";

export function makeReductionShader() {
    return new ShaderMaterial({
        vertexShader: `
            void main() {
                gl_Position = vec4( position, 1.0 );
            }
        `,
        fragmentShader: `
            uniform sampler2D source_texture;
            
            uniform vec2 source_resolution;
            uniform vec2 destination_resolution;
            
            out highp float out_value;
            
            float reduce(float a, float b, float c, float d){
                return max( a, max( b, max( c, d ) ) );
            }
            
            void main() {
                 vec2 source_uv = gl_FragCoord.xy / destination_resolution;
                 vec2 uv_mapping = source_resolution/destination_resolution;
                 
                 ivec2 source_texel_uv_0 = ivec2( source_uv * source_resolution);
                 
                 float d0 = texelFetch(source_texture, source_texel_uv_0, 0).x;
                 float d1 = texelFetch(source_texture, source_texel_uv_0 + ivec2( uv_mapping.x, 0 ), 0).x;
                 float d2 = texelFetch(source_texture, source_texel_uv_0 + ivec2( 0, uv_mapping.y ), 0).x;
                 float d3 = texelFetch(source_texture, source_texel_uv_0 + ivec2( uv_mapping.x, uv_mapping.y ), 0).x;
                 
                 out_value = reduce(d0, d1, d2, d3);
            }
        `,
        depthTest: false,
        depthWrite: false,
        uniforms: {
            source_texture: {
                value: null
            },
            destination_resolution: {
                value: new Vector2()
            },
            source_resolution: {
                value: new Vector2()
            }
        },
        glslVersion: GLSL3
    });
}
