When I look through a transparent shader I wrote with the help of a tutorial, sometimes other things using that same shader cannot be seen. Is this a shader problem or like a Unity settings problem? Thank you.
PS I’d love to show a picture but it looks like I have to first upload it to some website and then I share the URL? That should be made easier like on Stack Exchange forums.
Shader "LeafCutoutShader"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
_Color("Color", Color) = (1,1,1,1)
}
SubShader
{
Tags { "LightMode" = "ForwardBase" "IGNOREPROJECTOR" = "true" "RenderType" = "Transparent" "Queue" = "Transparent+500" "DisableBatching" = "LodFading" }
LOD 100
Pass
{
//ZTest Off
Blend SrcAlpha OneMinusSrcAlpha
Cull Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_instancing
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
#include "UnityLightingCommon.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float4 color : COLOR;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
float4 color : COLOR0;
UNITY_VERTEX_INPUT_INSTANCE_ID // necessary only if you want to access instanced properties in fragment Shader.
};
sampler2D _MainTex;
float4 _MainTex_ST;
UNITY_INSTANCING_BUFFER_START(Props)
UNITY_DEFINE_INSTANCED_PROP(float4, _Color)
UNITY_INSTANCING_BUFFER_END(Props)
v2f vert(appdata v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, o); // necessary only if you want to access instanced properties in the fragment Shader.
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
// sample the texture
fixed4 col = UNITY_ACCESS_INSTANCED_PROP(Props, _Color * _LightColor0) * tex2D(_MainTex, i.uv);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
UNITY_SETUP_INSTANCE_ID(i); // necessary only if any instanced properties are going to be accessed in the fragment Shader.
return col;
}
ENDCG
}
}
}
Add ZWrite Off
below where you have Cull Off
so that your shader isn’t writing to the depth buffer.
1 Like
Thank you well it looks a little better now but there is a new problem where some of the faces that are behind other faces render in front of them, which looks really weird lol
Yeah that’s a common issue when trying to render a model transparent that overlaps itself. The render order of the triangles of the mesh are not sorted by depth, since that would be large overhead.
You could turn ZWrite back on, but you’ll want to remove the “+500” you have there on the Transparent queue so that all your transparencies are rendered at the same time by object depth.
You won’t see both layers of the object overlapping itself anymore though in that case.
There are more advanced transparency solutions that can be found on the net though but they usually include more complicated setups or changes to rendering pipeline.
1 Like
I turned ZWrite back on and removed the +500 from the transparent queue but now it’s back to how it was before. Since I don;t have a pic to show you I want to make sure it’s not something with the UV’s? The object is a bunch of leaves with the same uv coordinates for each leaf that were all joined together in Blender after arranging them how I wanted.
I know the issue you’re referring to and it’s an issue with traditional rasterization. Because all your leaves are merged into one model, the order the transparent polygons are rendered isn’t going to be sorted from back to front, unlike when they are separate objects. So when a face that happens to be behind another face is actually rendered after it, you end up with an incorrect looking order.
Now one option would be to make sure the mesh is split so each leaf is a separate mesh object… but this isn’t very efficient, though instancing can help there, and there would usually still be some odd clipping issues.
Another option would be to just not use semi-transparency for your leaves. Use AlphaCutout instead of Transparency and discard the pixel if the alpha value is too low. Here is your shader with that change:
Shader "LeafCutoutShader"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
_Color("Color", Color) = (1,1,1,1)
_Cutoff("Transparency Cutoff", Range(0, 1)) = 0.5
}
SubShader
{
Tags { "LightMode"="ForwardBase" "IGNOREPROJECTOR"="true" "RenderType"="Opaque" "Queue"="AlphaTest" "DisableBatching" = "LodFading" }
LOD 100
Pass
{
Cull Off
ZWrite On
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_instancing
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
#include "UnityLightingCommon.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float4 color : COLOR;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
float4 color : COLOR0;
UNITY_VERTEX_INPUT_INSTANCE_ID // necessary only if you want to access instanced properties in fragment Shader.
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _Cutoff;
UNITY_INSTANCING_BUFFER_START(Props)
UNITY_DEFINE_INSTANCED_PROP(float4, _Color)
UNITY_INSTANCING_BUFFER_END(Props)
v2f vert(appdata v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, o); // necessary only if you want to access instanced properties in the fragment Shader.
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
// sample the texture
float4 col = tex2D(_MainTex, i.uv);
//Tint out texture by our tint color, ensuring our Alpha value is also adjusted by our Tint's alpha before we clip()
col *= UNITY_ACCESS_INSTANCED_PROP(Props, _Color) * _LightColor0;
clip(col.a - _Cutoff); //If our color's alpha value, minus our _Cutoff value, is less than 0, 'discard' this pixel.
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
UNITY_SETUP_INSTANCE_ID(i); // necessary only if any instanced properties are going to be accessed in the fragment Shader.
return col;
}
ENDCG
}
}
}
2 Likes
That works perfectly! Wow dude thanks you are awesome. I’m new to shaders but that seems like the most logical way of doing it, I mean, I would’ve assumed that was what the shader was doing in the background but apparently not lol. But anyway thanks again my big brained friend, I’ll mark this as solved.
1 Like