bsh0608

Hi I'm developing using Spine and unity

I have problem I use sprite fog shader.

this is fog shader
Shader "Sprites/Sprite_Fog"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
[MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
_FogAmplify ("Fog AmplifyValue", Range(1,10)) = 1
}

SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Opaque"
//"RenderType"="Transparent"
//"RenderType" = "TransparentCutout"
//"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}

Cull Off
Lighting Off
ZWrite Off

Blend One OneMinusSrcAlpha

Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#pragma multi_compile _ PIXELSNAP_ON
#pragma multi_compile _ ETC1_EXTERNAL_ALPHA
#include "UnityCG.cginc"

struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
};

struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
half2 fogDepth : TEXCOORD1;
};

fixed4 _Color;
uniform half unity_FogDensity;
float _EnableExternalAlpha;
float _FogAmplify;

v2f vert(appdata_t IN)
{
v2f OUT;

UNITY_SETUP_INSTANCE_ID(IN);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);

#ifdef UNITY_INSTANCING_ENABLED
IN.vertex.xy *= _Flip.xy;
#endif

OUT.vertex = UnityObjectToClipPos(IN.vertex);
OUT.texcoord = IN.texcoord;

// fogDepth.x = length(mul (UNITY_MATRIX_MV, IN.vertex).xyz);
//OUT.fogDepth.x = mul (UNITY_MATRIX_MV, IN.vertex).z;
OUT.fogDepth.x = UnityObjectToViewPos(IN.vertex).z;
OUT.fogDepth.y = OUT.fogDepth.x * unity_FogDensity;

OUT.color = IN.color * _Color;
#ifdef PIXELSNAP_ON
OUT.vertex = UnityPixelSnap (OUT.vertex);
#endif

return OUT;
}

sampler2D _MainTex;
sampler2D _AlphaTex;

fixed4 SampleSpriteTexture (float2 uv)
{
fixed4 color = tex2D (_MainTex, uv);

#if ETC1_EXTERNAL_ALPHA
fixed4 alpha = tex2D(_AlphaTex, uv);
color.a = lerp(color.a, alpha.r, _EnableExternalAlpha);
#endif //ETC1_EXTERNAL_ALPHA

return color;
}

fixed4 frag(v2f IN) : SV_Target
{
fixed4 c = SampleSpriteTexture (IN.texcoord) * IN.color;
float fogAmt = IN.fogDepth.y * IN.fogDepth.y *_FogAmplify;
fogAmt = exp(-fogAmt);
c.rgb = lerp(unity_FogColor, c.rgb, fogAmt) * c.a;
return c;
}
ENDCG
}
}


//FallBack "Mobile/VertexLit"
}
when I export spine Data checked Premultiply alpha state, I can see black edges.
surely I can use uncheck premultiply alpha but I'm curious that is only way?
if I use unity fog, I never use PMA?

I don't know about shader and English. sorry for that

thank you

Yours sincerely,
Attachments
blackege.PNG
bsh0608
Posts: 2

Pharan

If you're writing the fog blending yourself, you need to premultiply the fog color with the alpha before lerping.
If the sampled color from the sprite was already exported as PMA, there's no need to multiply it with the alpha again. Doing that would cause dark edges.

so I think the lerp would be something like:
c.rgb = lerp(unity_FogColor * c.a, c.rgb, fogAmt);
I didn't test this myself but I think that should do it.
User avatar
Pharan

Pharan
Posts: 4542

bsh0608

Thank you Pharan
Lerp that you gave is work perfectly! :love:
Can I add questions?
between Premultiply alpha and straight alpha there is performance difference?
which one is better? and how much better?

Thank you so much Pharan
bsh0608
Posts: 2

Pharan

Normally, the performance difference should be negligible.
But note that Unity's Sprite shader actually does PMA, but it doesn't require a PMA'ed texture.
It just does the PMA on the samples from the texture per frame. I'm actually not sure how much of a difference that makes too.
User avatar
Pharan

Pharan
Posts: 4542


Return to Unity