Skip to content

Commit

Permalink
fix unrolling, update to work with Unity 2017.3
Browse files Browse the repository at this point in the history
  • Loading branch information
elringus committed Feb 5, 2018
1 parent 1916356 commit 72a31f2
Showing 1 changed file with 45 additions and 32 deletions.
77 changes: 45 additions & 32 deletions Assets/SpriteGlow/SpriteOutline.shader
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Draws an HDR outline over the sprite borders.
// Based on Sprites/Default shader from Unity 2017.2.
// Based on Sprites/Default shader from Unity 2017.3.

Shader "Sprites/Outline"
{
Expand All @@ -13,10 +13,10 @@ Shader "Sprites/Outline"
[PerRendererData] _AlphaTex("External Alpha", 2D) = "white" {}
[PerRendererData] _EnableExternalAlpha("Enable External Alpha", Float) = 0

[HideInInspector] _IsOutlineEnabled("Enable Outline", float) = 0
[HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,1,1)
[HideInInspector] _OutlineSize("Outline Size", float) = 1
[HideInInspector] _AlphaThreshold("Alpha Threshold", Float) = 0.01
[MaterialToggle] _IsOutlineEnabled("Enable Outline", float) = 0
[HDR] _OutlineColor("Outline Color", Color) = (1,1,1,1)
_OutlineSize("Outline Size", Range (1, 10)) = 1
_AlphaThreshold("Alpha Threshold", Range (0, 1)) = 0.01
}

SubShader
Expand Down Expand Up @@ -54,29 +54,36 @@ Shader "Sprites/Outline"
#endif

#ifdef UNITY_INSTANCING_ENABLED
UNITY_INSTANCING_CBUFFER_START(PerDrawSprite)
fixed4 unity_SpriteRendererColorArray[UNITY_INSTANCED_ARRAY_SIZE];
float4 unity_SpriteFlipArray[UNITY_INSTANCED_ARRAY_SIZE];
UNITY_INSTANCING_CBUFFER_END
#define _RendererColor unity_SpriteRendererColorArray[unity_InstanceID]
#define _Flip unity_SpriteFlipArray[unity_InstanceID]
#endif

UNITY_INSTANCING_CBUFFER_START(SpriteOutline)
UNITY_DEFINE_INSTANCED_PROP(float, _IsOutlineEnabled)
UNITY_INSTANCING_BUFFER_START(PerDrawSprite)
UNITY_DEFINE_INSTANCED_PROP(fixed4, unity_SpriteRendererColorArray)
UNITY_DEFINE_INSTANCED_PROP(fixed2, unity_SpriteFlipArray)
UNITY_INSTANCING_BUFFER_END(PerDrawSprite)
#define _RendererColor UNITY_ACCESS_INSTANCED_PROP(PerDrawSprite, unity_SpriteRendererColorArray)
#define _Flip UNITY_ACCESS_INSTANCED_PROP(PerDrawSprite, unity_SpriteFlipArray)

UNITY_INSTANCING_BUFFER_START(PerDrawSpriteOutline)
UNITY_DEFINE_INSTANCED_PROP(float, _IsOutlineEnabled)
UNITY_DEFINE_INSTANCED_PROP(fixed4, _OutlineColor)
UNITY_DEFINE_INSTANCED_PROP(float, _OutlineSize)
UNITY_DEFINE_INSTANCED_PROP(float, _AlphaThreshold)
UNITY_INSTANCING_CBUFFER_END
UNITY_DEFINE_INSTANCED_PROP(float, _OutlineSize)
UNITY_DEFINE_INSTANCED_PROP(float, _AlphaThreshold)
UNITY_INSTANCING_BUFFER_END(PerDrawSpriteOutline)
#endif

CBUFFER_START(UnityPerDrawSprite)
#ifndef UNITY_INSTANCING_ENABLED
fixed4 _RendererColor;
float4 _Flip;
fixed2 _Flip;
#endif
float _EnableExternalAlpha;
CBUFFER_END

CBUFFER_START(UnityPerDrawSpriteOutline)
#ifndef UNITY_INSTANCING_ENABLED
fixed4 _OutlineColor;
float _IsOutlineEnabled, _OutlineSize, _AlphaThreshold;
#endif
CBUFFER_END

sampler2D _MainTex, _AlphaTex;
float4 _MainTex_TexelSize;
fixed4 _Color;
Expand Down Expand Up @@ -107,7 +114,7 @@ Shader "Sprites/Outline"
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(vertexOutput);

#ifdef UNITY_INSTANCING_ENABLED
vertexInput.Vertex.xy *= _Flip.xy;
vertexInput.Vertex.xy *= _Flip;
#endif

vertexOutput.Vertex = UnityObjectToClipPos(vertexInput.Vertex);
Expand All @@ -128,24 +135,27 @@ Shader "Sprites/Outline"
// Won't draw if effect is disabled, outline size is zero or sampled fragment is tranpsarent.
if (isOutlineEnabled * outlineSize * sampledColor.a == 0) return 0;

float2 texDdx = ddx(texCoord);
float2 texDdy = ddy(texCoord);

// Looking for a transparent pixel (sprite border from inside) around computed fragment with given depth (_OutlineSize).
// Also checking if sampled fragment is out of the texture space (UV is out of 0-1 range); considering such fragment as sprite border.
for (int i = 1; i <= SAMPLE_DEPTH_LIMIT; i++)
{
float2 pixelUpTexCoord = texCoord + float2(0, i * _MainTex_TexelSize.y);
fixed pixelUpAlpha = pixelUpTexCoord.y > 1.0 ? 0.0 : tex2D(_MainTex, pixelUpTexCoord).a;
fixed pixelUpAlpha = pixelUpTexCoord.y > 1.0 ? 0.0 : tex2Dgrad(_MainTex, pixelUpTexCoord, texDdx, texDdy).a;
if (pixelUpAlpha <= alphaThreshold) return 1;

float2 pixelDownTexCoord = texCoord - float2(0, i * _MainTex_TexelSize.y);
fixed pixelDownAlpha = pixelDownTexCoord.y < 0.0 ? 0.0 : tex2D(_MainTex, pixelDownTexCoord).a;
fixed pixelDownAlpha = pixelDownTexCoord.y < 0.0 ? 0.0 : tex2Dgrad(_MainTex, pixelDownTexCoord, texDdx, texDdy).a;
if (pixelDownAlpha <= alphaThreshold) return 1;

float2 pixelRightTexCoord = texCoord + float2(i * _MainTex_TexelSize.x, 0);
fixed pixelRightAlpha = pixelRightTexCoord.x > 1.0 ? 0.0 : tex2D(_MainTex, pixelRightTexCoord).a;
fixed pixelRightAlpha = pixelRightTexCoord.x > 1.0 ? 0.0 : tex2Dgrad(_MainTex, pixelRightTexCoord, texDdx, texDdy).a;
if (pixelRightAlpha <= alphaThreshold) return 1;

float2 pixelLeftTexCoord = texCoord - float2(i * _MainTex_TexelSize.x, 0);
fixed pixelLeftAlpha = pixelLeftTexCoord.x < 0.0 ? 0.0 : tex2D(_MainTex, pixelLeftTexCoord).a;
fixed pixelLeftAlpha = pixelLeftTexCoord.x < 0.0 ? 0.0 : tex2Dgrad(_MainTex, pixelLeftTexCoord, texDdx, texDdy).a;
if (pixelLeftAlpha <= alphaThreshold) return 1;

if (i > outlineSize) break;
Expand All @@ -162,23 +172,26 @@ Shader "Sprites/Outline"
if (isOutlineEnabled * outlineSize == 0) return 0;
if (sampledColor.a > alphaThreshold) return 0;

float2 texDdx = ddx(texCoord);
float2 texDdy = ddy(texCoord);

// Looking for an opaque pixel (sprite border from outise) around computed fragment with given depth (_OutlineSize).
for (int i = 1; i <= SAMPLE_DEPTH_LIMIT; i++)
{
float2 pixelUpTexCoord = texCoord + float2(0, i * _MainTex_TexelSize.y);
fixed pixelUpAlpha = tex2D(_MainTex, pixelUpTexCoord).a;
fixed pixelUpAlpha = tex2Dgrad(_MainTex, pixelUpTexCoord, texDdx, texDdy).a;
if (pixelUpAlpha > alphaThreshold) return 1;

float2 pixelDownTexCoord = texCoord - float2(0, i * _MainTex_TexelSize.y);
fixed pixelDownAlpha = tex2D(_MainTex, pixelDownTexCoord).a;
fixed pixelDownAlpha = tex2Dgrad(_MainTex, pixelDownTexCoord, texDdx, texDdy).a;
if (pixelDownAlpha > alphaThreshold) return 1;

float2 pixelRightTexCoord = texCoord + float2(i * _MainTex_TexelSize.x, 0);
fixed pixelRightAlpha = tex2D(_MainTex, pixelRightTexCoord).a;
fixed pixelRightAlpha = tex2Dgrad(_MainTex, pixelRightTexCoord, texDdx, texDdy).a;
if (pixelRightAlpha > alphaThreshold) return 1;

float2 pixelLeftTexCoord = texCoord - float2(i * _MainTex_TexelSize.x, 0);
fixed pixelLeftAlpha = tex2D(_MainTex, pixelLeftTexCoord).a;
fixed pixelLeftAlpha = tex2Dgrad(_MainTex, pixelLeftTexCoord, texDdx, texDdy).a;
if (pixelLeftAlpha > alphaThreshold) return 1;

if (i > outlineSize) break;
Expand Down Expand Up @@ -206,10 +219,10 @@ Shader "Sprites/Outline"
fixed4 color = SampleSpriteTexture(vertexOutput.TexCoord) * vertexOutput.Color;
color.rgb *= color.a;

int isOutlineEnabled = UNITY_ACCESS_INSTANCED_PROP(_IsOutlineEnabled);
fixed4 outlineColor = UNITY_ACCESS_INSTANCED_PROP(_OutlineColor);
int outlineSize = UNITY_ACCESS_INSTANCED_PROP(_OutlineSize);
float alphaThreshold = UNITY_ACCESS_INSTANCED_PROP(_AlphaThreshold);
int isOutlineEnabled = UNITY_ACCESS_INSTANCED_PROP(PerDrawSpriteOutline, _IsOutlineEnabled);
fixed4 outlineColor = UNITY_ACCESS_INSTANCED_PROP(PerDrawSpriteOutline, _OutlineColor);
int outlineSize = UNITY_ACCESS_INSTANCED_PROP(PerDrawSpriteOutline, _OutlineSize);
float alphaThreshold = UNITY_ACCESS_INSTANCED_PROP(PerDrawSpriteOutline, _AlphaThreshold);

#ifdef SPRITE_OUTLINE_OUTSIDE
int shouldDrawOutline = ShouldDrawOutlineOutside(color, vertexOutput.TexCoord, isOutlineEnabled, outlineSize, alphaThreshold);
Expand Down

0 comments on commit 72a31f2

Please sign in to comment.