- Home /
Surface shader changing z value
Hello,
I want to make a surface shader and give bonus to its z values, eg make the illusion that its closer to the camera when doing ztest. For example, if 2 meshes are right onto each other, I want the mesh with my shader to hide the other mesh, because it has extra Z. If however its too far behind, it will be rendered behind.
I tried dding Offset attribute but it just doesn't work (not sure why) and it seems like its impossible to mix vertex shader with surface shader so I can't add a bonus to the output Z.
So how can I get the effect I want? Is it even possible?
Here's my shader (copied from Sprite/Diffuse of Unity) :
Shader "Custom/SpriteShaderLights"
{
Properties
{
[PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}
_Color("Tint", Color) = (1,1,1,1)
[MaterialToggle] PixelSnap("Pixel snap", Float) = 0
}
SubShader
{
Tags
{
"Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "Transparent"
"PreviewType" = "Plane"
"CanUseSpriteAtlas" = "True"
}
Cull Off
Lighting Off
ZWrite Off
Blend One OneMinusSrcAlpha
Offset -10, -10 // <-- DOESN'T WORK, NO MATTER WHAT VALUES I GIVE.
CGPROGRAM
#pragma surface surf Lambert vertex:vert nofog keepalpha
#pragma multi_compile _ PIXELSNAP_ON
#pragma shader_feature ETC1_EXTERNAL_ALPHA
sampler2D _MainTex;
fixed4 _Color;
sampler2D _AlphaTex;
struct Input
{
float2 uv_MainTex;
fixed4 color;
};
void vert(inout appdata_full v, out Input o)
{
#if defined(PIXELSNAP_ON)
v.vertex = UnityPixelSnap(v.vertex);
#endif
UNITY_INITIALIZE_OUTPUT(Input, o);
o.color = v.color * _Color;
}
fixed4 SampleSpriteTexture(float2 uv)
{
fixed4 color = tex2D(_MainTex, uv);
#if ETC1_EXTERNAL_ALPHA
color.a = tex2D(_AlphaTex, uv).r;
#endif //ETC1_EXTERNAL_ALPHA
return color;
}
void surf(Input IN, inout SurfaceOutput o)
{
fixed4 c = SampleSpriteTexture(IN.uv_MainTex) * IN.color;
o.Albedo = c.rgb * c.a;
o.Alpha = c.a;
}
ENDCG
}
Fallback "Transparent/VertexLit"
}
Offset is designed to solve the situation you describe (although I thought it only accepted values in the (-1, 1) range). To be clear, you're only applying this shader to one of your overlapping surfaces, right? (If you pull them both closer to camera, obviously they'll still z-fight). Otherwise, if you really can't adjust the z values of the vertices, you'll have to render the objects in different sorting layers/ render queues.
@tanoshimi I'm testing object with this shader against object without it, to offset should work.
Actually, you can still add a vertex shader when using surface shaders. You need to use a custom modifier function. See here: Unity Docs
For an example of using it, look for Normal Extrusion with Vertex $$anonymous$$odifier here: Docs
@inso$$anonymous$$x didn't notice this option, looks like a possible solution. I'll try it, thanks!
Your answer
Follow this Question
Related Questions
How to adapt this shader into a transparent one (alpha blend) 0 Answers
Header for material properties in inspector? 2 Answers
Fog not working in my Shader~ 0 Answers
Addition to Standard Shader stopping it from batching? 0 Answers
Unity 3d Sprite Shader (How do I limit Max Brightness to 1 with Multiple Lights Hitting) 0 Answers