127 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
			
		
		
	
	
			127 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
| // AUTOGENERATED COPYRIGHT HEADER START
 | |
| // Copyright (C) 2021-2023 Michael Fabian 'Xaymar' Dirks <info@xaymar.com>
 | |
| // AUTOGENERATED COPYRIGHT HEADER END
 | |
| 
 | |
| #include "shared.effect"
 | |
| 
 | |
| uniform texture2d InputA<
 | |
| 	bool automatic = true;
 | |
| >;
 | |
| 
 | |
| uniform float2 CornerTL<
 | |
| 	string name = "Corner: Top Left";
 | |
| 	string field_type = "slider";
 | |
| 	string suffix = " %";
 | |
| 	float2 minimum = {-100., -100.};
 | |
| 	float2 maximum = {-200., -200.};
 | |
| 	float2 step = {.01, .01};
 | |
| 	float2 scale = {.01, .01};
 | |
| > = {0., 0.};
 | |
| 
 | |
| uniform float2 CornerTR<
 | |
| 	string name = "Corner: Top Right";
 | |
| 	string field_type = "slider";
 | |
| 	string suffix = " %";
 | |
| 	float2 minimum = {-100., -100.};
 | |
| 	float2 maximum = {-200., -200.};
 | |
| 	float2 step = {.01, .01};
 | |
| 	float2 scale = {.01, .01};
 | |
| > = {100., 0.};
 | |
| 
 | |
| uniform float2 CornerBL<
 | |
| 	string name = "Corner: Bottom Left";
 | |
| 	string field_type = "slider";
 | |
| 	string suffix = " %";
 | |
| 	float2 minimum = {-100., -100.};
 | |
| 	float2 maximum = {-200., -200.};
 | |
| 	float2 step = {.01, .01};
 | |
| 	float2 scale = {.01, .01};
 | |
| > = {0., 100.};
 | |
| 
 | |
| uniform float2 CornerBR<
 | |
| 	string name = "Corner: Bottom Right";
 | |
| 	string field_type = "slider";
 | |
| 	string suffix = " %";
 | |
| 	float2 minimum = {-100., -100.};
 | |
| 	float2 maximum = {-200., -200.};
 | |
| 	float2 step = {.01, .01};
 | |
| 	float2 scale = {.01, .01};
 | |
| > = {100., 100.};
 | |
| 
 | |
| //------------------------------------------------------------------------------
 | |
| // Technique: Corner Pin
 | |
| //------------------------------------------------------------------------------
 | |
| //
 | |
| // Credits:
 | |
| // - Inigo Quilez: https://www.iquilezles.org/www/articles/ibilinear/ibilinear.htm
 | |
| //
 | |
| // Parameters:
 | |
| // - InputA: RGBA Texture
 | |
| // - CornerTL: Corner "A"
 | |
| // - CornerTR: Corner "B"
 | |
| // - CornerBL: Corner "D"
 | |
| // - CornerBR: Corner "C"
 | |
| 
 | |
| float cross2d(in float2 a, in float2 b) {
 | |
| 	return (a.x * b.y) - (a.y * b.x);
 | |
| };
 | |
| 
 | |
| float2 inverse_bilinear(in float2 p, in float2 a, in float2 b, in float2 c, in float2 d) {
 | |
| 	float2 result = float2(-1., -1.);
 | |
| 
 | |
| 	float2 e = b - a;
 | |
| 	float2 f = d - a;
 | |
| 	float2 g = a-b+c-d;
 | |
| 	float2 h = p-a;
 | |
| 
 | |
| 	float k2 = cross2d(g, f);
 | |
| 	float k1 = cross2d(e, f) + cross2d(h, g);
 | |
| 	float k0 = cross2d(h, e);
 | |
| 
 | |
| 	if (abs(k2) < .001) { // Edges are likely parallel, so this is a linear equation.
 | |
| 		result = float2(
 | |
| 			(h.x * k1 + f.x * k0) / (e.x * k1 - g.x * k0),
 | |
| 			-k0 / k1
 | |
| 		);
 | |
| 	} else { // It's a quadratic equation.
 | |
| 		float w = k1 * k1 - 4.0 * k0 * k2;
 | |
| 		if (w < 0.0) { // Prevent GPUs from going insane.
 | |
| 			return result;
 | |
| 		}
 | |
| 		w = sqrt(w);
 | |
| 
 | |
| 		float ik2 = 0.5/k2;
 | |
| 		float v = (-k1 - w) * ik2;
 | |
| 		float u = (h.x - f.x * v) / (e.x + g.x * v);
 | |
| 
 | |
| 		if (u < 0.0 || u > 1.0 || v < 0.0 || v > 1.0) {
 | |
| 			v = (-k1 + w) * ik2;
 | |
| 			u = (h.x - f.x * v) / (e.x + g.x * v);
 | |
| 		}
 | |
| 
 | |
| 		result = float2(u, v);
 | |
| 	}
 | |
| 
 | |
| 	return result;
 | |
| };
 | |
| 
 | |
| float4 PSCornerPin(VertexData vtx) : TARGET {
 | |
| 	// Convert from screen coords to potential Quad UV coordinates.
 | |
| 	float2 uv = inverse_bilinear((vtx.uv * 2.) - 1., CornerTL, CornerTR, CornerBR, CornerBL);
 | |
| 
 | |
| 	if (max(abs(uv.x - .5), abs(uv.y - .5)) >= .5) {
 | |
| 		return float4(0, 0, 0, 0);
 | |
| 	}
 | |
| 
 | |
| 	return InputA.Sample(BlankSampler, uv);
 | |
| };
 | |
| 
 | |
| technique CornerPin
 | |
| {
 | |
| 	pass
 | |
| 	{
 | |
| 		vertex_shader = DefaultVertexShader(vtx);
 | |
| 		pixel_shader = PSCornerPin(vtx);
 | |
| 	};
 | |
| };
 |