#import bevy_pbr::{
	pbr_fragment::pbr_input_from_standard_material,
	forward_io::{VertexOutput, FragmentOutput},
	mesh_view_bindings::globals,
	pbr_functions::{
		alpha_discard,
		apply_pbr_lighting,
		main_pass_post_lighting_processing
	},
}

struct MatExt {
	cutoff: f32,
}

@group(1) @binding(100)
var<uniform> mat_ext: MatExt;

fn random(st: vec2<f32>) -> f32 {
	var a = vec2(12.9898, 78.233);
	var b = 43758.5453123;
	return fract(sin(dot(st.xy, a)) * b);
}

fn noise(st: vec2<f32>) -> f32 {
	var i = floor(st);
	var f = fract(st);

	var a = random(i);
	var b = random(i + vec2(1.0, 0.0));
	var c = random(i + vec2(0.0, 1.0));
	var d = random(i + vec2(1.0, 1.0));

	var u = smoothstep(vec2(0.0), vec2(1.0), f);

	return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y;
}

const octaves: i32 = 6;

fn fbm(st: vec2<f32>) -> f32 {
	var _st       = st;
	var value     = 0.0;
	var amplitude = 0.5;
	var frequency = 0.0;

	for (var i = 0 ; i < octaves; i++) {
		value += amplitude * noise(_st);
		_st *= 2.0;
		amplitude *= 0.5;
	}

	return value;
}

@fragment
fn fragment(
	in: VertexOutput,
	@builtin(front_facing) is_front: bool,
) -> FragmentOutput {
	var pbr_input = pbr_input_from_standard_material(in, is_front);

	var out: FragmentOutput;
	out.color = apply_pbr_lighting(pbr_input);

	var pos = vec2(in.uv * 2.718);

	var n = fbm(pos);

	var cutoff = mat_ext.cutoff;

	if n > cutoff {
		discard;
	}

	if n > (cutoff - 0.01) {
        out.color = vec4(0.0, 1.0, 1.0, 1.0);
	}

	return out;
}