• RuntimesUnity
  • Custom Shader Alpha Problem

I added PASS to the Spine-Skeleton shader to add a holographic effect.
(3rd PASS)
`
Shader "Spine/Skeleton-R-Hologram" {
Properties {
_Cutoff ("Shadow alpha cutoff", Range(0,1)) = 0.1
[NoScaleOffset] MainTex ("Main Texture", 2D) = "black" {}
[Toggle(
STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0
[HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0
[HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default

	// Outline properties are drawn via custom editor.
	[HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0
	[HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1)
	[HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024
	[HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25
	[HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0
	[HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1
	[HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0

	_Brightness ("Brightness", Range(0,4)) = 1
	_Fade ("Fade", Range(0,1)) = 0
	_RimColor ("Tint", Color) = (0.5,0.5,0.5,1)	
	_RimStrenght ("Rim strength", Range(0,2)) = 0
	_RimFalloff ("Rim falloff", Range(0,1)) = 1	
	_Color ("Tint", Color) = (0.5,0.5,0.5,1)
	_Scanlines ("Scanlines", 2D) = "white" {}
	_ScanStr ("Strength", Range(0,1)) = 1
}

SubShader {
	Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" }

	Fog { Mode Off }
	Cull Off
	ZWrite Off
	ZTest [unity_GUIZTestMode]
	Blend One OneMinusSrcAlpha
	Lighting Off

	Stencil {
		Ref[_StencilRef]
		Comp[_StencilComp]
		Pass Keep
	}

	Pass {
		Name "Normal"

		CGPROGRAM
		#pragma shader_feature _ _STRAIGHT_ALPHA_INPUT
		#pragma vertex vert
		#pragma fragment frag
		#include "UnityCG.cginc"
		#include "UnityUI.cginc"
		sampler2D _MainTex;

		struct VertexInput {
			float4 vertex : POSITION;
			float2 uv : TEXCOORD0;
			float4 vertexColor : COLOR;
		};

		struct VertexOutput {
			float4 pos : SV_POSITION;
			float2 uv : TEXCOORD0;
			float4 vertexColor : COLOR;
		};

		VertexOutput vert (VertexInput v) {
			VertexOutput o;
			o.pos = UnityObjectToClipPos(v.vertex);
			o.uv = v.uv;
			o.vertexColor = v.vertexColor;
			return o;
		}

		float4 frag (VertexOutput i) : SV_Target {
			float4 texColor = tex2D(_MainTex, i.uv);

			#if defined(_STRAIGHT_ALPHA_INPUT)
			texColor.rgb *= texColor.a;
			#endif

			return (texColor * i.vertexColor);
		}
		ENDCG
	}

	Pass {
		Name "Caster"
		Tags { "LightMode"="ShadowCaster" }
		Offset 1, 1
		ZWrite On
		ZTest LEqual

		Fog { Mode Off }
		Cull Off
		Lighting Off

		CGPROGRAM
		#pragma vertex vert
		#pragma fragment frag
		#pragma multi_compile_shadowcaster
		#pragma fragmentoption ARB_precision_hint_fastest
		#include "UnityCG.cginc"
		sampler2D _MainTex;
		fixed _Cutoff;

		struct VertexOutput {
			V2F_SHADOW_CASTER;
			float4 uvAndAlpha : TEXCOORD1;
		};

		VertexOutput vert (appdata_base v, float4 vertexColor : COLOR) {
			VertexOutput o;
			o.uvAndAlpha = v.texcoord;
			o.uvAndAlpha.a = vertexColor.a;
			TRANSFER_SHADOW_CASTER(o)
			return o;
		}

		float4 frag (VertexOutput i) : SV_Target {
			fixed4 texcol = tex2D(_MainTex, i.uvAndAlpha.xy);
			clip(texcol.a * i.uvAndAlpha.a - _Cutoff);
			SHADOW_CASTER_FRAGMENT(i)
		}
		ENDCG
	}

	Pass
	{
		zwrite off
		blend one one
		cull off
		CGPROGRAM
		#pragma vertex vert
		#pragma fragment frag 
		#include "UnityCG.cginc"
		#pragma multi_compile
		sampler2D _MainTex, _Scanlines;
		float4 _Color, _RimColor, _MainTex_ST, _Scanlines_ST;
		float _Fade, _RimStrenght, _Brightness, _RimFalloff, _ScanStr;
		
		struct appdata 
		{
			float4 vertex : POSITION;
			float4 normal : NORMAL;
			float4 color : COLOR;
			float2 uv_main : TEXCOORD0;
		};
		struct v2f
		{
			float4 vertex : SV_POSITION;
			float4 color : COLOR;
			float2 uv_main : TEXCOORD0;
			float2 scanlines_uv : TEXCOORD1;
		};
		v2f vert (appdata v)
		{
			v2f o;
			o.vertex = UnityObjectToClipPos(v.vertex);
			o.uv_main = TRANSFORM_TEX(v.uv_main, _MainTex);
			float4 screenPosOrigin = ComputeScreenPos(UnityObjectToClipPos(half4(0,0,0,1)));
			float4 screenPos = ComputeScreenPos(o.vertex);		
			float dis = length(ObjSpaceViewDir(half4(0,0,0,0)));				
			float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
			float2 flicker_uv = screenPos.xy / screenPos.w - screenPosOrigin.xy / screenPosOrigin.w;
			flicker_uv.y = worldPos.y; // y-on világkoordináta, flicker térbleiséghez kell
			o.scanlines_uv = flicker_uv * _Scanlines_ST.xy + frac(_Time.x*_Scanlines_ST.zw);
			float3 viewDir = normalize(ObjSpaceViewDir(v.vertex));
            float fresnel_rim = 1 - abs(dot(v.normal, viewDir));
			float fresnel_dissolve = 1 - dot(v.normal, viewDir);
            o.color = _Color*max(0,lerp(1,(0.5-fresnel_dissolve),_Fade*2.0)) + lerp(0,smoothstep(1 - _RimFalloff, 1.0, fresnel_rim), _RimStrenght) * _RimColor * 2.0;		
			return o;
		}
		fixed4 frag (v2f i) : SV_Target
		{
			fixed4 main = tex2D(_MainTex, i.uv_main) * _Brightness;
			fixed4 rim = i.color;
			fixed4 pri = tex2D (_Scanlines, i.scanlines_uv) * _ScanStr;
			fixed4 msk = fixed4(0,0,0,0);
			return main * max(pri,msk) * rim * fixed4(0.5,0.5,0.5,0.5);
		}
		ENDCG
	}
}
CustomEditor "SpineShaderWithOutlineGUI"

}
`
However, the images in the back appear to overlap. Is there a way to fix this?

Related Discussions
...

To address the issue of overlapping images in the back when using a custom shader with a holographic effect in Spine, you should consider the depth and transparency handling of your shader. The problem might be related to how the shader manages depth write (ZWrite) and blending modes. Since your third pass has ZWrite Off and uses additive blending (Blend One OneMinusSrcAlpha), it does not write to the depth buffer, causing all rendered objects to appear on top without proper depth testing.

One approach to mitigate this issue is to adjust the depth write settings for your passes. For semi-transparent effects, managing depth can be challenging because you want to maintain the visual integrity of the holographic effect while ensuring that objects are rendered in the correct order. Here are a few suggestions:

  1. Depth Sorting: Ensure that your objects are sorted in the correct order before being rendered. This is crucial for transparent objects and can sometimes resolve issues without needing to change shader properties.

  2. Alpha Clipping: For the passes where you have ZWrite Off, consider using alpha clipping to discard fragments below a certain alpha threshold. This won't solve all overlapping issues but can help in situations where fully transparent pixels should not contribute to the depth.

  3. Depth Write for Solid Parts: If parts of your holographic effect are solid (non-transparent), you could modify the shader to write these parts to the depth buffer (ZWrite On for those fragments). This requires careful handling to avoid visual artifacts.

  4. Soft Particles: If your holographic effect is used in a 3D space (e.g., with Unity's particle systems), enabling Soft Particles can help blend the holographic effect more naturally with the environment. This technique uses the depth buffer to soften the edges of particles when they intersect with solid geometry.

  5. Custom Depth Handling: For advanced control, you might implement custom depth handling in your shader. This could involve writing custom depth values or using a separate pass to write to a custom depth texture. This approach requires a good understanding of Unity's rendering pipeline and shader programming.

Remember, the right solution depends on the specific requirements of your project and the visual effect you aim to achieve. Experimenting with different approaches and understanding the limitations of each will help you find the best solution for your holographic effect.

@dylee If the above posting by Spinebot does not resolve your issue, could you please show some screenshots of what is going wrong? What exactly do you mean by "the images in the back appear to overlap"?