// Generated by ShaderCompiler from ResizeCleanEdge.shader. Do not edit manually.
#pragma once

#include "ShaderCompilerTypes.h"
#if defined(WITH_RHI_D3D11)
#	include "D3d11GeneratedShaders.h"
#endif
#if defined(WITH_RHI_VULKAN)
#	include "VulkanGeneratedShaders.h"
#endif

#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Jazz2::ShadersGen
{
#if defined(WITH_RHI_GL) && !defined(RHI_GL_PROFILE_ES2)
	inline constexpr char ResizeCleanEdge_Vs[] =
R"__SHDR__(#line 1

out vec2 v_px;
out vec2 size;

uniform mat4 uProjectionMatrix;
uniform mat4 uViewMatrix;

layout (std140) uniform InstanceBlock
{
	mat4 modelMatrix;
	vec4 color;
	vec4 texRect;
	vec2 spriteSize;
};



vec3 highestColor = vec3(1.,1.,1.);
float similarThreshold = 0.0;
float lineWidth = 1.0;

const float scale = 4.0;
const mat3 yuv_matrix = mat3(vec3(0.299, 0.587, 0.114), vec3(-0.169, -0.331, 0.5), vec3(0.5, -0.419, -0.081));

void main()
{
	vec2 aPosition = vec2(1.0 - float(gl_VertexID >> 1), float(gl_VertexID % 2));
	vec4 position = vec4(aPosition.x * spriteSize.x, aPosition.y * spriteSize.y, 0.0, 1.0);

	gl_Position = uProjectionMatrix * uViewMatrix * modelMatrix * position;

	size = texRect.xy + 0.0001;
	v_px = aPosition.xy * size;
}
)__SHDR__";
#endif

#if defined(WITH_RHI_GL) && defined(RHI_GL_PROFILE_ES2)
	inline constexpr char ResizeCleanEdge_Vs100[] =
R"__SHDR__(attribute vec2 aQuadCorner;
#line 1

varying vec2 v_px;
varying vec2 size;

uniform mat4 uProjectionMatrix;
uniform mat4 uViewMatrix;

	uniform mat4 modelMatrix;
	uniform vec4 color;
	uniform vec4 texRect;
	uniform vec2 spriteSize;



vec3 highestColor = vec3(1.,1.,1.);
float similarThreshold = 0.0;
float lineWidth = 1.0;

const float scale = 4.0;
const mat3 yuv_matrix = mat3(vec3(0.299, 0.587, 0.114), vec3(-0.169, -0.331, 0.5), vec3(0.5, -0.419, -0.081));

void main()
{
	vec2 aPosition = vec2(1.0 - (1.0 - aQuadCorner.x), aQuadCorner.y);
	vec4 position = vec4(aPosition.x * spriteSize.x, aPosition.y * spriteSize.y, 0.0, 1.0);

	gl_Position = uProjectionMatrix * uViewMatrix * modelMatrix * position;

	size = texRect.xy + 0.0001;
	v_px = aPosition.xy * size;
}
)__SHDR__";
#endif

#if defined(WITH_RHI_GL) && !defined(RHI_GL_PROFILE_ES2)
	inline constexpr char ResizeCleanEdge_Fs[] =
R"__SHDR__(#line 1

#ifdef GL_ES
precision mediump float;
#endif

in vec2 v_px;
in vec2 size;

uniform sampler2D uTexture;

#define SLOPE
#define CLEANUP

vec3 highestColor = vec3(1.,1.,1.);
float similarThreshold = 0.0;
float lineWidth = 1.0;

const float scale = 4.0;
const mat3 yuv_matrix = mat3(vec3(0.299, 0.587, 0.114), vec3(-0.169, -0.331, 0.5), vec3(0.5, -0.419, -0.081));

bool similar(vec4 col1, vec4 col2){
	return (col1.a == 0. && col2.a == 0.) || distance(col1, col2) <= similarThreshold;
}

bool similar3(vec4 col1, vec4 col2, vec4 col3){
	return similar(col1, col2) && similar(col2, col3);
}

bool similar4(vec4 col1, vec4 col2, vec4 col3, vec4 col4){
	return similar(col1, col2) && similar(col2, col3) && similar(col3, col4);
}

bool higher(vec4 thisCol, vec4 otherCol){
	if(similar(thisCol, otherCol)) return false;
	if(thisCol.a == otherCol.a){
//		return yuv(thisCol.rgb).x > yuv(otherCol.rgb).x;
//		return distance(yuv(thisCol.rgb), yuv(highestColor)) < distance(yuv(otherCol.rgb), yuv(highestColor));
		return distance(thisCol.rgb, highestColor) < distance(otherCol.rgb, highestColor);
	} else {
		return thisCol.a > otherCol.a;
	}
}

float cd(vec4 col1, vec4 col2){
	return distance(col1.rgba, col2.rgba);
}

float distToLine(vec2 testPt, vec2 pt1, vec2 pt2, vec2 dir){
  vec2 lineDir = pt2 - pt1;
  vec2 perpDir = vec2(lineDir.y, -lineDir.x);
  vec2 dirToPt1 = pt1 - testPt;
  return (dot(perpDir, dir) > 0.0 ? 1.0 : -1.0) * (dot(normalize(perpDir), dirToPt1));
}

vec4 sliceDist(vec2 point, vec2 mainDir, vec2 pointDir, vec4 ub, vec4 u, vec4 uf, vec4 uff, vec4 b, vec4 c, vec4 f, vec4 ff, vec4 db, vec4 d, vec4 df, vec4 dff, vec4 ddb, vec4 dd, vec4 ddf){
	//clamped range prevents inacccurate identity (no change) result, feel free to disable if necessary
	#ifdef SLOPE
	float minWidth = 0.45;
	float maxWidth = 1.142;
	#else
	float minWidth = 0.0;
	float maxWidth = 1.4;
	#endif
	float _lineWidth = max(minWidth, min(maxWidth, lineWidth));
	point = mainDir * (point - 0.5) + 0.5; //flip point

	//edge detection
	float distAgainst = 4.0*cd(f,d) + cd(uf,c) + cd(c,db) + cd(ff,df) + cd(df,dd);
	float distTowards = 4.0*cd(c,df) + cd(u,f) + cd(f,dff) + cd(b,d) + cd(d,ddf);
	bool shouldSlice =
	  (distAgainst < distTowards)
	  || (distAgainst < distTowards + 0.001) && !higher(c, f); //equivalent edges edge case
	if(similar4(f, d, b, u) && similar4(uf, df, db, ub) && !similar(c, f)){ //checkerboard edge case
		shouldSlice = false;
	}
	if(!shouldSlice) return vec4(-1.0);

	//only applicable for very large lineWidth (>1.3)
//	if(similar3(c, f, df)){ //don't make slice for same color
//		return vec4(-1.0);
//	}
	float dist = 1.0;
	bool flip = false;
	vec2 center = vec2(0.5,0.5);

	#ifdef SLOPE
	if(similar3(f, d, db) && !similar3(f, d, b) && !similar(uf, db)){ //lower shallow 2:1 slant
		if(similar(c, df) && higher(c, f)){ //single pixel wide diagonal, dont flip

		} else {
			//priority edge cases
			if(higher(c, f)){
				flip = true;
			}
			if(similar(u, f) && !similar(c, df) && !higher(c, u)){
				flip = true;
			}
		}

		if(flip){
			dist = _lineWidth-distToLine(point, center+vec2(1.5, -1.0)*pointDir, center+vec2(-0.5, 0.0)*pointDir, -pointDir); //midpoints of neighbor two-pixel groupings
		} else {
			dist = distToLine(point, center+vec2(1.5, 0.0)*pointDir, center+vec2(-0.5, 1.0)*pointDir, pointDir); //midpoints of neighbor two-pixel groupings
		}

		//cleanup slant transitions
		#ifdef CLEANUP
		if(!flip && similar(c, uf) && !(similar3(c, uf, uff) && !similar3(c, uf, ff) && !similar(d, uff))){ //shallow
			float dist2 = distToLine(point, center+vec2(2.0, -1.0)*pointDir, center+vec2(-0.0, 1.0)*pointDir, pointDir);
			dist = min(dist, dist2);
		}
		#endif

		dist -= (_lineWidth/2.0);
		return dist <= 0.0 ? ((cd(c,f) <= cd(c,d)) ? f : d) : vec4(-1.0);
	} else if(similar3(uf, f, d) && !similar3(u, f, d) && !similar(uf, db)){ //forward steep 2:1 slant
		if(similar(c, df) && higher(c, d)){ //single pixel wide diagonal, dont flip

		} else {
			//priority edge cases
			if(higher(c, d)){
				flip = true;
			}
			if(similar(b, d) && !similar(c, df) && !higher(c, d)){
				flip = true;
			}
		}

		if(flip){
			dist = _lineWidth-distToLine(point, center+vec2(0.0, -0.5)*pointDir, center+vec2(-1.0, 1.5)*pointDir, -pointDir); //midpoints of neighbor two-pixel groupings
		} else {
			dist = distToLine(point, center+vec2(1.0, -0.5)*pointDir, center+vec2(0.0, 1.5)*pointDir, pointDir); //midpoints of neighbor two-pixel groupings
		}

		//cleanup slant transitions
		#ifdef CLEANUP
		if(!flip && similar(c, db) && !(similar3(c, db, ddb) && !similar3(c, db, dd) && !similar(f, ddb))){ //steep
			float dist2 = distToLine(point, center+vec2(1.0, 0.0)*pointDir, center+vec2(-1.0, 2.0)*pointDir, pointDir);
			dist = min(dist, dist2);
		}
		#endif

		dist -= (_lineWidth/2.0);
		return dist <= 0.0 ? ((cd(c,f) <= cd(c,d)) ? f : d) : vec4(-1.0);
	} else
	#endif
	if(similar(f, d)) { //45 diagonal
		if(similar(c, df) && higher(c, f)){ //single pixel diagonal along neighbors, dont flip
			if(!similar(c, dd) && !similar(c, ff)){ //line against triple color stripe edge case
				flip = true;
			}
		} else {
			//priority edge cases
			if(higher(c, f)){
				flip = true;
			}
			if(!similar(c, b) && similar4(b, f, d, u)){
				flip = true;
			}
		}
		//single pixel 2:1 slope, dont flip
		if((( (similar(f, db) && similar3(u, f, df)) || (similar(uf, d) && similar3(b, d, df)) ) && !similar(c, df))){
			flip = true;
		}

		if(flip){
			dist = _lineWidth-distToLine(point, center+vec2(1.0, -1.0)*pointDir, center+vec2(-1.0, 1.0)*pointDir, -pointDir); //midpoints of own diagonal pixels
		} else {
			dist = distToLine(point, center+vec2(1.0, 0.0)*pointDir, center+vec2(0.0, 1.0)*pointDir, pointDir); //midpoints of corner neighbor pixels
		}

		//cleanup slant transitions
		#if defined(SLOPE) && defined(CLEANUP)
		if(!flip && similar3(c, uf, uff) && !similar3(c, uf, ff) && !similar(d, uff)){ //shallow
			float dist2 = distToLine(point, center+vec2(1.5, 0.0)*pointDir, center+vec2(-0.5, 1.0)*pointDir, pointDir);
			dist = max(dist, dist2);
		}

		if(!flip && similar3(ddb, db, c) && !similar3(dd, db, c) && !similar(ddb, f)){ //steep
			float dist2 = distToLine(point, center+vec2(1.0, -0.5)*pointDir, center+vec2(0.0, 1.5)*pointDir, pointDir);
			dist = max(dist, dist2);
		}
		#endif

		dist -= (_lineWidth/2.0);
		return dist <= 0.0 ? ((cd(c,f) <= cd(c,d)) ? f : d) : vec4(-1.0);
	}
	#ifdef SLOPE
	else if(similar3(ff, df, d) && !similar3(ff, df, c) && !similar(uff, d)){ //far corner of shallow slant

		if(similar(f, dff) && higher(f, ff)){ //single pixel wide diagonal, dont flip

		} else {
			//priority edge cases
			if(higher(f, ff)){
				flip = true;
			}
			if(similar(uf, ff) && !similar(f, dff) && !higher(f, uf)){
				flip = true;
			}
		}
		if(flip){
			dist = _lineWidth-distToLine(point, center+vec2(2.5, -1.0)*pointDir, center+vec2(0.5, 0.0)*pointDir, -pointDir); //midpoints of neighbor two-pixel groupings
		} else {
			dist = distToLine(point, center+vec2(2.5, 0.0)*pointDir, center+vec2(0.5, 1.0)*pointDir, pointDir); //midpoints of neighbor two-pixel groupings
		}

		dist -= (_lineWidth/2.0);
		return dist <= 0.0 ? ((cd(f,ff) <= cd(f,df)) ? ff : df) : vec4(-1.0);
	} else if(similar3(f, df, dd) && !similar3(c, df, dd) && !similar(f, ddb)){ //far corner of steep slant
		if(similar(d, ddf) && higher(d, dd)){ //single pixel wide diagonal, dont flip

		} else {
			//priority edge cases
			if(higher(d, dd)){
				flip = true;
			}
			if(similar(db, dd) && !similar(d, ddf) && !higher(d, dd)){
				flip = true;
			}
//			if(!higher(d, dd)){
//				return vec4(1.0);
//				flip = true;
//			}
		}

		if(flip){
			dist = _lineWidth-distToLine(point, center+vec2(0.0, 0.5)*pointDir, center+vec2(-1.0, 2.5)*pointDir, -pointDir); //midpoints of neighbor two-pixel groupings
		} else {
			dist = distToLine(point, center+vec2(1.0, 0.5)*pointDir, center+vec2(0.0, 2.5)*pointDir, pointDir); //midpoints of neighbor two-pixel groupings
		}
		dist -= (_lineWidth/2.0);
		return dist <= 0.0 ? ((cd(d,df) <= cd(d,dd)) ? df : dd) : vec4(-1.0);
	}
	#endif
	return vec4(-1.0);
}

out vec4 COLOR;

void main() {
	vec2 local = fract(v_px);
	vec2 px = ceil(v_px);

	vec2 pointDir = floor(local + 0.5)*2.0-1.0;

	//neighbor pixels
	//Up, Down, Forward, and Back
	//relative to quadrant of current location within pixel

	vec4 uub = texture(uTexture, (px+vec2(-1.0,-2.0)*pointDir)/size);
	vec4 uu  = texture(uTexture, (px+vec2( 0.0,-2.0)*pointDir)/size);
	vec4 uuf = texture(uTexture, (px+vec2( 1.0,-2.0)*pointDir)/size);

	vec4 ubb = texture(uTexture, (px+vec2(-2.0,-2.0)*pointDir)/size);
	vec4 ub  = texture(uTexture, (px+vec2(-1.0,-1.0)*pointDir)/size);
	vec4 u   = texture(uTexture, (px+vec2( 0.0,-1.0)*pointDir)/size);
	vec4 uf  = texture(uTexture, (px+vec2( 1.0,-1.0)*pointDir)/size);
	vec4 uff = texture(uTexture, (px+vec2( 2.0,-1.0)*pointDir)/size);

	vec4 bb  = texture(uTexture, (px+vec2(-2.0, 0.0)*pointDir)/size);
	vec4 b   = texture(uTexture, (px+vec2(-1.0, 0.0)*pointDir)/size);
	vec4 c   = texture(uTexture, (px+vec2( 0.0, 0.0)*pointDir)/size);
	vec4 f   = texture(uTexture, (px+vec2( 1.0, 0.0)*pointDir)/size);
	vec4 ff  = texture(uTexture, (px+vec2( 2.0, 0.0)*pointDir)/size);

	vec4 dbb = texture(uTexture, (px+vec2(-2.0, 1.0)*pointDir)/size);
	vec4 db  = texture(uTexture, (px+vec2(-1.0, 1.0)*pointDir)/size);
	vec4 d   = texture(uTexture, (px+vec2( 0.0, 1.0)*pointDir)/size);
	vec4 df  = texture(uTexture, (px+vec2( 1.0, 1.0)*pointDir)/size);
	vec4 dff = texture(uTexture, (px+vec2( 2.0, 1.0)*pointDir)/size);

	vec4 ddb = texture(uTexture, (px+vec2(-1.0, 2.0)*pointDir)/size);
	vec4 dd  = texture(uTexture, (px+vec2( 0.0, 2.0)*pointDir)/size);
	vec4 ddf = texture(uTexture, (px+vec2( 1.0, 2.0)*pointDir)/size);

	vec4 col = c;

	//c_orner, b_ack, and u_p slices
	// (slices from neighbor pixels will only ever reach these 3 quadrants
	vec4 c_col = sliceDist(local, vec2( 1.0, 1.0), pointDir, ub, u, uf, uff, b, c, f, ff, db, d, df, dff, ddb, dd, ddf);
	vec4 b_col = sliceDist(local, vec2(-1.0, 1.0), pointDir, uf, u, ub, ubb, f, c, b, bb, df, d, db, dbb, ddf, dd, ddb);
	vec4 u_col = sliceDist(local, vec2( 1.0,-1.0), pointDir, db, d, df, dff, b, c, f, ff, ub, u, uf, uff, uub, uu, uuf);

	if(c_col.r >= 0.0){
		col = c_col;
	}
	if(b_col.r >= 0.0){
		col = b_col;
	}
	if(u_col.r >= 0.0){
		col = u_col;
	}

	COLOR = col;
}

)__SHDR__";
#endif

#if defined(WITH_RHI_GL) && defined(RHI_GL_PROFILE_ES2)
	inline constexpr char ResizeCleanEdge_Fs100[] =
R"__SHDR__(#line 1

precision mediump float;

varying vec2 v_px;
varying vec2 size;

uniform sampler2D uTexture;

#define SLOPE
#define CLEANUP

vec3 highestColor = vec3(1.,1.,1.);
float similarThreshold = 0.0;
float lineWidth = 1.0;

const float scale = 4.0;
const mat3 yuv_matrix = mat3(vec3(0.299, 0.587, 0.114), vec3(-0.169, -0.331, 0.5), vec3(0.5, -0.419, -0.081));

bool similar(vec4 col1, vec4 col2){
	return (col1.a == 0. && col2.a == 0.) || distance(col1, col2) <= similarThreshold;
}

bool similar3(vec4 col1, vec4 col2, vec4 col3){
	return similar(col1, col2) && similar(col2, col3);
}

bool similar4(vec4 col1, vec4 col2, vec4 col3, vec4 col4){
	return similar(col1, col2) && similar(col2, col3) && similar(col3, col4);
}

bool higher(vec4 thisCol, vec4 otherCol){
	if(similar(thisCol, otherCol)) return false;
	if(thisCol.a == otherCol.a){
//		return yuv(thisCol.rgb).x > yuv(otherCol.rgb).x;
//		return distance(yuv(thisCol.rgb), yuv(highestColor)) < distance(yuv(otherCol.rgb), yuv(highestColor));
		return distance(thisCol.rgb, highestColor) < distance(otherCol.rgb, highestColor);
	} else {
		return thisCol.a > otherCol.a;
	}
}

float cd(vec4 col1, vec4 col2){
	return distance(col1.rgba, col2.rgba);
}

float distToLine(vec2 testPt, vec2 pt1, vec2 pt2, vec2 dir){
  vec2 lineDir = pt2 - pt1;
  vec2 perpDir = vec2(lineDir.y, -lineDir.x);
  vec2 dirToPt1 = pt1 - testPt;
  return (dot(perpDir, dir) > 0.0 ? 1.0 : -1.0) * (dot(normalize(perpDir), dirToPt1));
}

vec4 sliceDist(vec2 point, vec2 mainDir, vec2 pointDir, vec4 ub, vec4 u, vec4 uf, vec4 uff, vec4 b, vec4 c, vec4 f, vec4 ff, vec4 db, vec4 d, vec4 df, vec4 dff, vec4 ddb, vec4 dd, vec4 ddf){
	//clamped range prevents inacccurate identity (no change) result, feel free to disable if necessary
	#ifdef SLOPE
	float minWidth = 0.45;
	float maxWidth = 1.142;
	#else
	float minWidth = 0.0;
	float maxWidth = 1.4;
	#endif
	float _lineWidth = max(minWidth, min(maxWidth, lineWidth));
	point = mainDir * (point - 0.5) + 0.5; //flip point

	//edge detection
	float distAgainst = 4.0*cd(f,d) + cd(uf,c) + cd(c,db) + cd(ff,df) + cd(df,dd);
	float distTowards = 4.0*cd(c,df) + cd(u,f) + cd(f,dff) + cd(b,d) + cd(d,ddf);
	bool shouldSlice =
	  (distAgainst < distTowards)
	  || (distAgainst < distTowards + 0.001) && !higher(c, f); //equivalent edges edge case
	if(similar4(f, d, b, u) && similar4(uf, df, db, ub) && !similar(c, f)){ //checkerboard edge case
		shouldSlice = false;
	}
	if(!shouldSlice) return vec4(-1.0);

	//only applicable for very large lineWidth (>1.3)
//	if(similar3(c, f, df)){ //don't make slice for same color
//		return vec4(-1.0);
//	}
	float dist = 1.0;
	bool flip = false;
	vec2 center = vec2(0.5,0.5);

	#ifdef SLOPE
	if(similar3(f, d, db) && !similar3(f, d, b) && !similar(uf, db)){ //lower shallow 2:1 slant
		if(similar(c, df) && higher(c, f)){ //single pixel wide diagonal, dont flip

		} else {
			//priority edge cases
			if(higher(c, f)){
				flip = true;
			}
			if(similar(u, f) && !similar(c, df) && !higher(c, u)){
				flip = true;
			}
		}

		if(flip){
			dist = _lineWidth-distToLine(point, center+vec2(1.5, -1.0)*pointDir, center+vec2(-0.5, 0.0)*pointDir, -pointDir); //midpoints of neighbor two-pixel groupings
		} else {
			dist = distToLine(point, center+vec2(1.5, 0.0)*pointDir, center+vec2(-0.5, 1.0)*pointDir, pointDir); //midpoints of neighbor two-pixel groupings
		}

		//cleanup slant transitions
		#ifdef CLEANUP
		if(!flip && similar(c, uf) && !(similar3(c, uf, uff) && !similar3(c, uf, ff) && !similar(d, uff))){ //shallow
			float dist2 = distToLine(point, center+vec2(2.0, -1.0)*pointDir, center+vec2(-0.0, 1.0)*pointDir, pointDir);
			dist = min(dist, dist2);
		}
		#endif

		dist -= (_lineWidth/2.0);
		return dist <= 0.0 ? ((cd(c,f) <= cd(c,d)) ? f : d) : vec4(-1.0);
	} else if(similar3(uf, f, d) && !similar3(u, f, d) && !similar(uf, db)){ //forward steep 2:1 slant
		if(similar(c, df) && higher(c, d)){ //single pixel wide diagonal, dont flip

		} else {
			//priority edge cases
			if(higher(c, d)){
				flip = true;
			}
			if(similar(b, d) && !similar(c, df) && !higher(c, d)){
				flip = true;
			}
		}

		if(flip){
			dist = _lineWidth-distToLine(point, center+vec2(0.0, -0.5)*pointDir, center+vec2(-1.0, 1.5)*pointDir, -pointDir); //midpoints of neighbor two-pixel groupings
		} else {
			dist = distToLine(point, center+vec2(1.0, -0.5)*pointDir, center+vec2(0.0, 1.5)*pointDir, pointDir); //midpoints of neighbor two-pixel groupings
		}

		//cleanup slant transitions
		#ifdef CLEANUP
		if(!flip && similar(c, db) && !(similar3(c, db, ddb) && !similar3(c, db, dd) && !similar(f, ddb))){ //steep
			float dist2 = distToLine(point, center+vec2(1.0, 0.0)*pointDir, center+vec2(-1.0, 2.0)*pointDir, pointDir);
			dist = min(dist, dist2);
		}
		#endif

		dist -= (_lineWidth/2.0);
		return dist <= 0.0 ? ((cd(c,f) <= cd(c,d)) ? f : d) : vec4(-1.0);
	} else
	#endif
	if(similar(f, d)) { //45 diagonal
		if(similar(c, df) && higher(c, f)){ //single pixel diagonal along neighbors, dont flip
			if(!similar(c, dd) && !similar(c, ff)){ //line against triple color stripe edge case
				flip = true;
			}
		} else {
			//priority edge cases
			if(higher(c, f)){
				flip = true;
			}
			if(!similar(c, b) && similar4(b, f, d, u)){
				flip = true;
			}
		}
		//single pixel 2:1 slope, dont flip
		if((( (similar(f, db) && similar3(u, f, df)) || (similar(uf, d) && similar3(b, d, df)) ) && !similar(c, df))){
			flip = true;
		}

		if(flip){
			dist = _lineWidth-distToLine(point, center+vec2(1.0, -1.0)*pointDir, center+vec2(-1.0, 1.0)*pointDir, -pointDir); //midpoints of own diagonal pixels
		} else {
			dist = distToLine(point, center+vec2(1.0, 0.0)*pointDir, center+vec2(0.0, 1.0)*pointDir, pointDir); //midpoints of corner neighbor pixels
		}

		//cleanup slant transitions
		#if defined(SLOPE) && defined(CLEANUP)
		if(!flip && similar3(c, uf, uff) && !similar3(c, uf, ff) && !similar(d, uff)){ //shallow
			float dist2 = distToLine(point, center+vec2(1.5, 0.0)*pointDir, center+vec2(-0.5, 1.0)*pointDir, pointDir);
			dist = max(dist, dist2);
		}

		if(!flip && similar3(ddb, db, c) && !similar3(dd, db, c) && !similar(ddb, f)){ //steep
			float dist2 = distToLine(point, center+vec2(1.0, -0.5)*pointDir, center+vec2(0.0, 1.5)*pointDir, pointDir);
			dist = max(dist, dist2);
		}
		#endif

		dist -= (_lineWidth/2.0);
		return dist <= 0.0 ? ((cd(c,f) <= cd(c,d)) ? f : d) : vec4(-1.0);
	}
	#ifdef SLOPE
	else if(similar3(ff, df, d) && !similar3(ff, df, c) && !similar(uff, d)){ //far corner of shallow slant

		if(similar(f, dff) && higher(f, ff)){ //single pixel wide diagonal, dont flip

		} else {
			//priority edge cases
			if(higher(f, ff)){
				flip = true;
			}
			if(similar(uf, ff) && !similar(f, dff) && !higher(f, uf)){
				flip = true;
			}
		}
		if(flip){
			dist = _lineWidth-distToLine(point, center+vec2(2.5, -1.0)*pointDir, center+vec2(0.5, 0.0)*pointDir, -pointDir); //midpoints of neighbor two-pixel groupings
		} else {
			dist = distToLine(point, center+vec2(2.5, 0.0)*pointDir, center+vec2(0.5, 1.0)*pointDir, pointDir); //midpoints of neighbor two-pixel groupings
		}

		dist -= (_lineWidth/2.0);
		return dist <= 0.0 ? ((cd(f,ff) <= cd(f,df)) ? ff : df) : vec4(-1.0);
	} else if(similar3(f, df, dd) && !similar3(c, df, dd) && !similar(f, ddb)){ //far corner of steep slant
		if(similar(d, ddf) && higher(d, dd)){ //single pixel wide diagonal, dont flip

		} else {
			//priority edge cases
			if(higher(d, dd)){
				flip = true;
			}
			if(similar(db, dd) && !similar(d, ddf) && !higher(d, dd)){
				flip = true;
			}
//			if(!higher(d, dd)){
//				return vec4(1.0);
//				flip = true;
//			}
		}

		if(flip){
			dist = _lineWidth-distToLine(point, center+vec2(0.0, 0.5)*pointDir, center+vec2(-1.0, 2.5)*pointDir, -pointDir); //midpoints of neighbor two-pixel groupings
		} else {
			dist = distToLine(point, center+vec2(1.0, 0.5)*pointDir, center+vec2(0.0, 2.5)*pointDir, pointDir); //midpoints of neighbor two-pixel groupings
		}
		dist -= (_lineWidth/2.0);
		return dist <= 0.0 ? ((cd(d,df) <= cd(d,dd)) ? df : dd) : vec4(-1.0);
	}
	#endif
	return vec4(-1.0);
}


void main() {
	vec4 COLOR;
	vec2 local = fract(v_px);
	vec2 px = ceil(v_px);

	vec2 pointDir = floor(local + 0.5)*2.0-1.0;

	//neighbor pixels
	//Up, Down, Forward, and Back
	//relative to quadrant of current location within pixel

	vec4 uub = texture2D(uTexture, (px+vec2(-1.0,-2.0)*pointDir)/size);
	vec4 uu  = texture2D(uTexture, (px+vec2( 0.0,-2.0)*pointDir)/size);
	vec4 uuf = texture2D(uTexture, (px+vec2( 1.0,-2.0)*pointDir)/size);

	vec4 ubb = texture2D(uTexture, (px+vec2(-2.0,-2.0)*pointDir)/size);
	vec4 ub  = texture2D(uTexture, (px+vec2(-1.0,-1.0)*pointDir)/size);
	vec4 u   = texture2D(uTexture, (px+vec2( 0.0,-1.0)*pointDir)/size);
	vec4 uf  = texture2D(uTexture, (px+vec2( 1.0,-1.0)*pointDir)/size);
	vec4 uff = texture2D(uTexture, (px+vec2( 2.0,-1.0)*pointDir)/size);

	vec4 bb  = texture2D(uTexture, (px+vec2(-2.0, 0.0)*pointDir)/size);
	vec4 b   = texture2D(uTexture, (px+vec2(-1.0, 0.0)*pointDir)/size);
	vec4 c   = texture2D(uTexture, (px+vec2( 0.0, 0.0)*pointDir)/size);
	vec4 f   = texture2D(uTexture, (px+vec2( 1.0, 0.0)*pointDir)/size);
	vec4 ff  = texture2D(uTexture, (px+vec2( 2.0, 0.0)*pointDir)/size);

	vec4 dbb = texture2D(uTexture, (px+vec2(-2.0, 1.0)*pointDir)/size);
	vec4 db  = texture2D(uTexture, (px+vec2(-1.0, 1.0)*pointDir)/size);
	vec4 d   = texture2D(uTexture, (px+vec2( 0.0, 1.0)*pointDir)/size);
	vec4 df  = texture2D(uTexture, (px+vec2( 1.0, 1.0)*pointDir)/size);
	vec4 dff = texture2D(uTexture, (px+vec2( 2.0, 1.0)*pointDir)/size);

	vec4 ddb = texture2D(uTexture, (px+vec2(-1.0, 2.0)*pointDir)/size);
	vec4 dd  = texture2D(uTexture, (px+vec2( 0.0, 2.0)*pointDir)/size);
	vec4 ddf = texture2D(uTexture, (px+vec2( 1.0, 2.0)*pointDir)/size);

	vec4 col = c;

	//c_orner, b_ack, and u_p slices
	// (slices from neighbor pixels will only ever reach these 3 quadrants
	vec4 c_col = sliceDist(local, vec2( 1.0, 1.0), pointDir, ub, u, uf, uff, b, c, f, ff, db, d, df, dff, ddb, dd, ddf);
	vec4 b_col = sliceDist(local, vec2(-1.0, 1.0), pointDir, uf, u, ub, ubb, f, c, b, bb, df, d, db, dbb, ddf, dd, ddb);
	vec4 u_col = sliceDist(local, vec2( 1.0,-1.0), pointDir, db, d, df, dff, b, c, f, ff, ub, u, uf, uff, uub, uu, uuf);

	if(c_col.r >= 0.0){
		col = c_col;
	}
	if(b_col.r >= 0.0){
		col = b_col;
	}
	if(u_col.r >= 0.0){
		col = u_col;
	}

	COLOR = col;
	gl_FragColor = COLOR;
}

)__SHDR__";
#endif

	inline constexpr ShaderCompiler::Uniform ResizeCleanEdge_Uniforms[] = {
		{ "uProjectionMatrix", ShaderCompiler::UniformType::Mat4, 0 },
		{ "uViewMatrix", ShaderCompiler::UniformType::Mat4, 0 },
	};

	inline constexpr ShaderCompiler::BlockMember ResizeCleanEdge_Block0_Members[] = {
		{ "modelMatrix", ShaderCompiler::UniformType::Mat4, 0, 0 },
		{ "color", ShaderCompiler::UniformType::Vec4, 0, 64 },
		{ "texRect", ShaderCompiler::UniformType::Vec4, 0, 80 },
		{ "spriteSize", ShaderCompiler::UniformType::Vec2, 0, 96 },
	};

	inline constexpr ShaderCompiler::UniformBlock ResizeCleanEdge_Blocks[] = {
		{ "InstanceBlock", 112, 0, 4, ResizeCleanEdge_Block0_Members },
	};

	inline constexpr ShaderCompiler::TextureBinding ResizeCleanEdge_Textures[] = {
		{ "uTexture", 0 },
	};

	inline constexpr ShaderCompiler::ProgramVariant ResizeCleanEdge_Variants[] = {
		{ "", "",
#if defined(WITH_RHI_GL) && !defined(RHI_GL_PROFILE_ES2)
			ResizeCleanEdge_Vs, ResizeCleanEdge_Fs,
#else
			nullptr, nullptr,
#endif
			2, ResizeCleanEdge_Uniforms, 1, ResizeCleanEdge_Blocks, 1, ResizeCleanEdge_Textures, 0, nullptr,
#if defined(WITH_RHI_GL) && defined(RHI_GL_PROFILE_ES2)
			ResizeCleanEdge_Vs100, ResizeCleanEdge_Fs100,
#else
			nullptr, nullptr,
#endif
#if defined(WITH_RHI_D3D11)
			ResizeCleanEdge_VsHlsl, ResizeCleanEdge_FsHlsl,
			ResizeCleanEdge_VsDxbc, ResizeCleanEdge_VsDxbcSize, ResizeCleanEdge_FsDxbc, ResizeCleanEdge_FsDxbcSize,
#else
			nullptr, nullptr,
			nullptr, 0, nullptr, 0,
#endif
#if defined(WITH_RHI_VULKAN)
			ResizeCleanEdge_VkVs, ResizeCleanEdge_VkVsSize, ResizeCleanEdge_VkFs, ResizeCleanEdge_VkFsSize },
#else
			nullptr, 0, nullptr, 0 },
#endif
	};

	inline constexpr ShaderCompiler::Program ResizeCleanEdge = { "ResizeCleanEdge", 0, 1, ResizeCleanEdge_Variants };
}
#endif
