Spine-Outline-Common.cginc 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. #ifndef SPINE_OUTLINE_COMMON_INCLUDED
  2. #define SPINE_OUTLINE_COMMON_INCLUDED
  3. float4 computeOutlinePixel(sampler2D mainTexture, float2 mainTextureTexelSize,
  4. float2 uv, float vertexColorAlpha,
  5. float OutlineWidth, float OutlineReferenceTexWidth, float OutlineMipLevel,
  6. float OutlineSmoothness, float ThresholdEnd, float OutlineOpaqueAlpha, float4 OutlineColor) {
  7. float4 texColor = fixed4(0, 0, 0, 0);
  8. #if !_USE_SCREENSPACE_OUTLINE_WIDTH
  9. // constant width in texture space
  10. float outlineWidthCompensated = OutlineWidth / (OutlineReferenceTexWidth * mainTextureTexelSize.x);
  11. float xOffset = mainTextureTexelSize.x * outlineWidthCompensated;
  12. float yOffset = mainTextureTexelSize.y * outlineWidthCompensated;
  13. #else
  14. float2 ddxUV = ddx(uv);
  15. float2 ddyUV = ddy(uv);
  16. float2 ddu = float2(ddxUV.x, ddyUV.x);
  17. float2 ddv = float2(ddxUV.y, ddyUV.y);
  18. float widthScale = OutlineWidth * _ScreenParams.x / OutlineReferenceTexWidth;
  19. float xOffset = length(ddu) * widthScale;
  20. float yOffset = length(ddv) * widthScale;
  21. #endif
  22. float xOffsetDiagonal = xOffset * 0.7;
  23. float yOffsetDiagonal = yOffset * 0.7;
  24. float pixelCenter = tex2D(mainTexture, uv).a;
  25. float4 uvCenterWithLod = float4(uv, 0, OutlineMipLevel);
  26. float pixelTop = tex2Dlod(mainTexture, uvCenterWithLod + float4(0, yOffset, 0, 0)).a;
  27. float pixelBottom = tex2Dlod(mainTexture, uvCenterWithLod + float4(0, -yOffset, 0, 0)).a;
  28. float pixelLeft = tex2Dlod(mainTexture, uvCenterWithLod + float4(-xOffset, 0, 0, 0)).a;
  29. float pixelRight = tex2Dlod(mainTexture, uvCenterWithLod + float4(xOffset, 0, 0, 0)).a;
  30. #if _USE8NEIGHBOURHOOD_ON
  31. float numSamples = 8;
  32. float pixelTopLeft = tex2Dlod(mainTexture, uvCenterWithLod + float4(-xOffsetDiagonal, yOffsetDiagonal, 0, 0)).a;
  33. float pixelTopRight = tex2Dlod(mainTexture, uvCenterWithLod + float4(xOffsetDiagonal, yOffsetDiagonal, 0, 0)).a;
  34. float pixelBottomLeft = tex2Dlod(mainTexture, uvCenterWithLod + float4(-xOffsetDiagonal, -yOffsetDiagonal, 0, 0)).a;
  35. float pixelBottomRight = tex2Dlod(mainTexture, uvCenterWithLod + float4(xOffsetDiagonal, -yOffsetDiagonal, 0, 0)).a;
  36. float average = (pixelTop + pixelBottom + pixelLeft + pixelRight +
  37. pixelTopLeft + pixelTopRight + pixelBottomLeft + pixelBottomRight)
  38. * vertexColorAlpha / numSamples;
  39. #else // 4 neighbourhood
  40. float numSamples = 4;
  41. float average = (pixelTop + pixelBottom + pixelLeft + pixelRight) * vertexColorAlpha / numSamples;
  42. #endif
  43. float thresholdStart = ThresholdEnd * (1.0 - OutlineSmoothness);
  44. float outlineAlpha = saturate(saturate((average - thresholdStart) / (ThresholdEnd - thresholdStart)) - pixelCenter);
  45. outlineAlpha = pixelCenter > OutlineOpaqueAlpha ? 0 : outlineAlpha;
  46. return lerp(texColor, OutlineColor, outlineAlpha);
  47. }
  48. float4 computeOutlinePixel(sampler2D mainTexture, float2 mainTextureTexelSize,
  49. float2 uv, float vertexColorAlpha,
  50. float OutlineWidth, float OutlineReferenceTexWidth, float OutlineMipLevel,
  51. float OutlineSmoothness, float ThresholdEnd, float4 OutlineColor) {
  52. return computeOutlinePixel(mainTexture, mainTextureTexelSize,
  53. uv, vertexColorAlpha, OutlineWidth, OutlineReferenceTexWidth, OutlineMipLevel,
  54. OutlineSmoothness, ThresholdEnd, 1.0, OutlineColor);
  55. }
  56. #endif