I am working on a transparent shader and am coming across an issue I’m hoping there is an easy solution to that I am simply not aware of. I am fading an object, but would like to essentially take the opaque view of the object and fade that. The transparent view shows rear faces and other geometry that I’d prefer to be hidden. In the screen shot, you can see the orange bricks coming through. Some of them are on the back of the object. Does anyone have an ideas?
Sorry I’m not sure exactly what I’m looking at as it looks a bit abstract, but could you maybe use alpha clip to fade your objects? Then they would pretty much fade like opaque objects… Without sorting artifacts. But I’m not sure if that’s the whole thing you are fading or what. It’s usually better to show a clear example case.
Could something like this work for you? (the fading object is the standard Unity sphere mesh)
I think that is what I am talking about. Here are more clear example. First is the object rendered as opaque. Next the same view with transparency. In the transparent view, you can see the little rectangular shape showing through. This is what I’m hoping to avoid.
Which renderer are you using? Standard, URP, HDRP? It would be good nowadays to tell that when posting graphics related issues as there’s so many things done in different ways on different renderers.
Good point. I’m using URP.
Try this graph, something similar should work. I just put it together quickly, so…
Expose the parameter to interface. On HDRP you have to enable alpha clip in that gear (settings) menu of the Master node but I think URP had it by default visible, if I remember correctly.
if it is one single mesh you may try to enable depth write.
Thanks for this. I’m thinking that I’m overcomplicating this. I eliminated the excess geometry and got something that is close to the effect I’m going for. Doing the alpha threshold dithering seems to work somewhat, but eliminating the geometry definitely gets the job done.
How does one go about enabling that?
when it comes to shader graph - hmm, get the shader code from the master node, create a new shader and paste it there.
but sorry, if it one mesh it won’t work…
Okay. Thanks.
This might help for Universal RP.
How to add a Z-test pass to any transparent object:
- Create a layer for your Z-tested transparent objects:
- Create an unlit transparent material with 0 alpha called ZTestOnly
- Select your Universal Pipeline Renderer asset:
- Add a new renderer feature. Name it whatever you want, but make sure the rest is filled out like so, with the Layer Mask set to whatever your layer is that you want a prepass on, and Material set to your unlit transparent material. Make sure “Depth” and “Write Depth” is checked and “Depth Test” is set to “Less Equal”
Then put whatever transparent object you want to have a ZTest pass on that layer.
Advantages over dithering:
No pixelated effect
Allows for additive or multiplicative blending
Disadvantages over dithering:
Other transparent objects will not render behind it
Does not work correctly with materials whose shaders have vertex modification
I could kiss you! I was trying this approach but couldn’t get it to work. This did precisely the trick. I’m not doing any vertex modification so this is ideal. Thanks so much!
So Ive been attempting to solve this problem aswell. Bit disapointed in URP seaming to take away shader passes, but I am happy to learn a new way if that is what Unity thinks is best.
I did notice however that this problem of a transparent mesh drawing over itself is solved by the default URP shaders…
(Left is simple custom transparent shader, Right the same terrible programmer art (points if you can guess what it is) but with the URP Unlit shader set to transparent mode)
So time to figure out how this default shader does this with out all the… “intricate”… setup proposed above. I found the default URP shader in question in the URP package (See below). It seams that the shader does include multiple passes includeing the ZWrite On ColorMask 0
depth only pass that I would have used for this job before URP. So how come this works for Unity shaders not custom ones? Would be nice to have access to this ability as it seams to still be possible within URP.
My guess is it is to do with the “DepthOnly” program #defines which dont seam to be docummented anywhere.
#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
Whole shader source code…
Shader "Universal Render Pipeline/Unlit"
{
Properties
{
[MainTexture] _BaseMap("Texture", 2D) = "white" {}
[MainColor] _BaseColor("Color", Color) = (1, 1, 1, 1)
_Cutoff("AlphaCutout", Range(0.0, 1.0)) = 0.5
// BlendMode
[HideInInspector] _Surface("__surface", Float) = 0.0
[HideInInspector] _Blend("__blend", Float) = 0.0
[HideInInspector] _AlphaClip("__clip", Float) = 0.0
[HideInInspector] _SrcBlend("Src", Float) = 1.0
[HideInInspector] _DstBlend("Dst", Float) = 0.0
[HideInInspector] _ZWrite("ZWrite", Float) = 1.0
[HideInInspector] _Cull("__cull", Float) = 2.0
// Editmode props
[HideInInspector] _QueueOffset("Queue offset", Float) = 0.0
// ObsoleteProperties
[HideInInspector] _MainTex("BaseMap", 2D) = "white" {}
[HideInInspector] _Color("Base Color", Color) = (0.5, 0.5, 0.5, 1)
[HideInInspector] _SampleGI("SampleGI", float) = 0.0 // needed from bakedlit
}
SubShader
{
Tags { "RenderType" = "Opaque" "IgnoreProjector" = "True" "RenderPipeline" = "UniversalPipeline" }
LOD 100
Blend [_SrcBlend][_DstBlend]
ZWrite [_ZWrite]
Cull [_Cull]
Pass
{
Name "Unlit"
HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma vertex vert
#pragma fragment frag
#pragma shader_feature _ALPHATEST_ON
#pragma shader_feature _ALPHAPREMULTIPLY_ON
// -------------------------------------
// Unity defined keywords
#pragma multi_compile_fog
#pragma multi_compile_instancing
#include "UnlitInput.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float2 uv : TEXCOORD0;
float fogCoord : TEXCOORD1;
float4 vertex : SV_POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
Varyings vert(Attributes input)
{
Varyings output = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_TRANSFER_INSTANCE_ID(input, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
output.vertex = vertexInput.positionCS;
output.uv = TRANSFORM_TEX(input.uv, _BaseMap);
output.fogCoord = ComputeFogFactor(vertexInput.positionCS.z);
return output;
}
half4 frag(Varyings input) : SV_Target
{
UNITY_SETUP_INSTANCE_ID(input);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
half2 uv = input.uv;
half4 texColor = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv);
half3 color = texColor.rgb * _BaseColor.rgb;
half alpha = texColor.a * _BaseColor.a;
AlphaDiscard(alpha, _Cutoff);
#ifdef _ALPHAPREMULTIPLY_ON
color *= alpha;
#endif
color = MixFog(color, input.fogCoord);
alpha = OutputAlpha(alpha);
return half4(color, alpha);
}
ENDHLSL
}
Pass
{
Tags{"LightMode" = "DepthOnly"}
ZWrite On
ColorMask 0
HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma target 2.0
#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
// -------------------------------------
// Material Keywords
#pragma shader_feature _ALPHATEST_ON
//--------------------------------------
// GPU Instancing
#pragma multi_compile_instancing
#include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl"
ENDHLSL
}
// This pass it not used during regular rendering, only for lightmap baking.
Pass
{
Name "Meta"
Tags{"LightMode" = "Meta"}
Cull Off
HLSLPROGRAM
// Required to compile gles 2.0 with standard srp library
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma vertex UniversalVertexMeta
#pragma fragment UniversalFragmentMetaUnlit
#include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitMetaPass.hlsl"
ENDHLSL
}
}
FallBack "Hidden/Universal Render Pipeline/FallbackError"
CustomEditor "UnityEditor.Rendering.Universal.ShaderGUI.UnlitShader"
}
I think it’s better to go for just any material settings for the unlit shader and to pass 1 in the Pass Index (which corresponds to DepthOnly pass).
The other thing I’ve noticed is I didn’t need any overrides, no material, no Depth override. Just Filters settings. In the newer version of URP there’s a Light Mode tags setting and I provided DepthOnly and it was enough. In the older version as on the screenshot above it matches Shader Passes. But you need to make sure, the shader has the DepthOnly pass.
Is there anyway we can have the same effect for built in?
I have just faced that issue and your approach helped, thanks a lot!
But I can see that it works only with unlit materials, is it possible to have a similar solution for Lit materials?