#ifndef SPINE_OUTLINE_COMMON_INCLUDED
#define SPINE_OUTLINE_COMMON_INCLUDED

float4 computeOutlinePixel(sampler2D mainTexture, float2 mainTextureTexelSize,
	float2 uv, float vertexColorAlpha,
	float OutlineWidth, float OutlineReferenceTexWidth, float OutlineMipLevel,
	float OutlineSmoothness, float ThresholdEnd, float OutlineOpaqueAlpha, float4 OutlineColor) {

	float4 texColor = fixed4(0, 0, 0, 0);

#if !_USE_SCREENSPACE_OUTLINE_WIDTH
	// constant width in texture space
	float outlineWidthCompensated = OutlineWidth / (OutlineReferenceTexWidth * mainTextureTexelSize.x);
	float xOffset = mainTextureTexelSize.x * outlineWidthCompensated;
	float yOffset = mainTextureTexelSize.y * outlineWidthCompensated;
#else
	float2 ddxUV = ddx(uv);
	float2 ddyUV = ddy(uv);
	float2 ddu = float2(ddxUV.x, ddyUV.x);
	float2 ddv = float2(ddxUV.y, ddyUV.y);
	float widthScale = OutlineWidth * _ScreenParams.x / OutlineReferenceTexWidth;
	float xOffset = length(ddu) * widthScale;
	float yOffset = length(ddv) * widthScale;
#endif
	float xOffsetDiagonal = xOffset * 0.7;
	float yOffsetDiagonal = yOffset * 0.7;

	float pixelCenter = tex2D(mainTexture, uv).a;

	float4 uvCenterWithLod = float4(uv, 0, OutlineMipLevel);
	float pixelTop = tex2Dlod(mainTexture, uvCenterWithLod + float4(0, yOffset, 0, 0)).a;
	float pixelBottom = tex2Dlod(mainTexture, uvCenterWithLod + float4(0, -yOffset, 0, 0)).a;
	float pixelLeft = tex2Dlod(mainTexture, uvCenterWithLod + float4(-xOffset, 0, 0, 0)).a;
	float pixelRight = tex2Dlod(mainTexture, uvCenterWithLod + float4(xOffset, 0, 0, 0)).a;
#if _USE8NEIGHBOURHOOD_ON
	float numSamples = 8;
	float pixelTopLeft = tex2Dlod(mainTexture, uvCenterWithLod + float4(-xOffsetDiagonal, yOffsetDiagonal, 0, 0)).a;
	float pixelTopRight = tex2Dlod(mainTexture, uvCenterWithLod + float4(xOffsetDiagonal, yOffsetDiagonal, 0, 0)).a;
	float pixelBottomLeft = tex2Dlod(mainTexture, uvCenterWithLod + float4(-xOffsetDiagonal, -yOffsetDiagonal, 0, 0)).a;
	float pixelBottomRight = tex2Dlod(mainTexture, uvCenterWithLod + float4(xOffsetDiagonal, -yOffsetDiagonal, 0, 0)).a;
	float average = (pixelTop + pixelBottom + pixelLeft + pixelRight +
		pixelTopLeft + pixelTopRight + pixelBottomLeft + pixelBottomRight)
		* vertexColorAlpha / numSamples;
#else // 4 neighbourhood
	float numSamples = 4;
	float average = (pixelTop + pixelBottom + pixelLeft + pixelRight) * vertexColorAlpha / numSamples;
#endif
	float thresholdStart = ThresholdEnd * (1.0 - OutlineSmoothness);
	float outlineAlpha = saturate((average - thresholdStart) / (ThresholdEnd - thresholdStart));
#if !_OUTLINE_FILL_INSIDE
	outlineAlpha = saturate(outlineAlpha - pixelCenter);
	outlineAlpha = pixelCenter > OutlineOpaqueAlpha ? 0.0 : outlineAlpha;
#else
	outlineAlpha = pixelCenter > OutlineOpaqueAlpha ? 1.0 : outlineAlpha;
#endif
	return lerp(texColor, OutlineColor, outlineAlpha);
}

float4 computeOutlinePixel(sampler2D mainTexture, float2 mainTextureTexelSize,
	float2 uv, float vertexColorAlpha,
	float OutlineWidth, float OutlineReferenceTexWidth, float OutlineMipLevel,
	float OutlineSmoothness, float ThresholdEnd, float4 OutlineColor) {

	return computeOutlinePixel(mainTexture, mainTextureTexelSize,
		uv, vertexColorAlpha, OutlineWidth, OutlineReferenceTexWidth, OutlineMipLevel,
		OutlineSmoothness, ThresholdEnd, 1.0, OutlineColor);
}

#endif
