Working on a 2D effect in LWRP, and the goal is having a depth blur with shader graph and the Post Processing is on the camera. Now here's the trouble: When swithced to “Opaque”, the blur is right on everything, but no alpha cut out; When swithced to “Transparent”, it's cut out nicly, but everything using this shader is blurred as the farthest one, just like the default unlit shader. How can I get both???
Transparent objects aren't included in the depth texture used by depth of field and post process effects in general. You should be using an alpha tested opaque shader. Set the alpha clip threshold to something not zero, like 0.5.
Alpha tested edges will always be a bit less clean then geometry edges or alpha blending, but that might be as good as you'll get.
@bgolus Hi PayneLee and Bgolus I am struggling with depth of field post effect in LWRP 2D. I copied sprite-Lit shader and added ZWrite On but it doesn't work. What should I charge to the shader so that depth of field starts working?
Because ZWrite On or Off is irrelevant for depth of field to work. First it needs to be in the opaque queue range (0-2500), and second it needs to write to the depth texture. The depth buffer used during rendering (what setting the ZWrite controls) and the depth texture used by various post process effects are separate things. Specifically the depth texture is generated by rendering the scene once with a shader that only writes to the depth buffer, and then Unity copies that depth buffer to a texture that can be sampled from. The camera then renders the scene normally with a totally different depth buffer. For the built in rendering paths, this reuses the ShadowCaster pass also used to generate the shadow maps (which are also depth only renders that get converted into textures, just from the point of view of the light rather than the camera). For the LWRP it has a new DepthOnly pass for this. AFAIK none of the built in Sprite shaders have the DepthOnly pass, so none of them will work with the LWRP even if you change the material's queue or make them write to the depth buffer (which, again, is totally separate from the depth texture). You'd have to modify the sprite shader to add a proper DepthOnly pass, or use a non-sprite specific shader that is already setup properly.
@bgolus really lots of stuff to learn! I've been reading lots of your post Bgolus. great to learn. I will learn more about depthOnly pass and dig into it to make my lwrp 2d sprite gets blur with DOF. @Payne_Lee Could you also explain how you made DOF working with your lwrp 2d sprite setup. Thank you guys!!
@bgolus Hi Bgolus. I am back with shader modified I changed RenderType to Opaque. and added DepthOnly pass ( copied from another post from your answer to someone) And I am using 2d Renderer I still can't get the depth of field working. ( everything is just blur even if the sprite is 15 unit away from camera, the distance doesn't count from post effect. When I use ForwardRendereer, the depth and everything works. it just doesn't work with 2d Renderer what else should I try Bgolus? Thank you! Code (CSharp): Shader "JcLwrp2DSprite" { Properties { _MainTex("Diffuse", 2D) = "white" {} _MaskTex("Mask", 2D) = "white" {} _NormalMap("Normal Map", 2D) = "bump" {} // Legacy properties. They're here so that materials using this shader can gracefully fallback to the legacy sprite shader. [HideInInspector] _Color("Tint", Color) = (1,1,1,1) [HideInInspector] _RendererColor("RendererColor", Color) = (1,1,1,1) [HideInInspector] _Flip("Flip", Vector) = (1,1,1,1) [HideInInspector] _AlphaTex("External Alpha", 2D) = "white" {} [HideInInspector] _EnableExternalAlpha("Enable External Alpha", Float) = 0 } HLSLINCLUDE #include "Core.hlsl" ENDHLSL SubShader { Tags {"Queue" = "Geometry" "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" } //Blend SrcAlpha OneMinusSrcAlpha //Cull Off //ZWrite On Pass { Name "DepthOnly" Tags{"LightMode" = "DepthOnly"} //DepthOnly ZWrite On ColorMask 0 Cull Off 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 #pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A //-------------------------------------- // GPU Instancing #pragma multi_compile_instancing #include "LitInput.hlsl" #include "DepthOnlyPass.hlsl" ENDHLSL } Pass { Tags { "LightMode" = "Universal2D" } HLSLPROGRAM #pragma prefer_hlslcc gles #pragma vertex CombinedShapeLightVertex #pragma fragment CombinedShapeLightFragment #pragma multi_compile USE_SHAPE_LIGHT_TYPE_0 __ #pragma multi_compile USE_SHAPE_LIGHT_TYPE_1 __ #pragma multi_compile USE_SHAPE_LIGHT_TYPE_2 __ #pragma multi_compile USE_SHAPE_LIGHT_TYPE_3 __ struct Attributes { float3 positionOS : POSITION; float4 color : COLOR; float2 uv : TEXCOORD0; }; struct Varyings { float4 positionCS : SV_POSITION; float4 color : COLOR; float2 uv : TEXCOORD0; float2 lightingUV : TEXCOORD1; }; #include "Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/LightingUtility.hlsl" TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex); TEXTURE2D(_MaskTex); SAMPLER(sampler_MaskTex); TEXTURE2D(_NormalMap); SAMPLER(sampler_NormalMap); half4 _MainTex_ST; half4 _NormalMap_ST; #if USE_SHAPE_LIGHT_TYPE_0 SHAPE_LIGHT(0) #endif #if USE_SHAPE_LIGHT_TYPE_1 SHAPE_LIGHT(1) #endif #if USE_SHAPE_LIGHT_TYPE_2 SHAPE_LIGHT(2) #endif #if USE_SHAPE_LIGHT_TYPE_3 SHAPE_LIGHT(3) #endif Varyings CombinedShapeLightVertex(Attributes v) { Varyings o = (Varyings)0; o.positionCS = TransformObjectToHClip(v.positionOS); o.uv = TRANSFORM_TEX(v.uv, _MainTex); float4 clipVertex = o.positionCS / o.positionCS.w; o.lightingUV = ComputeScreenPos(clipVertex).xy; o.color = v.color; return o; } #include "Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/CombinedShapeLightShared.hlsl" half4 CombinedShapeLightFragment(Varyings i) : SV_Target { half4 main = i.color * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv); half4 mask = SAMPLE_TEXTURE2D(_MaskTex, sampler_MaskTex, i.uv); return CombinedShapeLightShared(main, mask, i.lightingUV); } ENDHLSL } Pass { Tags { "LightMode" = "NormalsRendering"} HLSLPROGRAM #pragma prefer_hlslcc gles #pragma vertex NormalsRenderingVertex #pragma fragment NormalsRenderingFragment struct Attributes { float3 positionOS : POSITION; float4 color : COLOR; float2 uv : TEXCOORD0; float4 tangent : TANGENT; }; struct Varyings { float4 positionCS : SV_POSITION; float4 color : COLOR; float2 uv : TEXCOORD0; float3 normalWS : TEXCOORD1; float3 tangentWS : TEXCOORD2; float3 bitangentWS : TEXCOORD3; }; TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex); TEXTURE2D(_NormalMap); SAMPLER(sampler_NormalMap); float4 _NormalMap_ST; // Is this the right way to do this? Varyings NormalsRenderingVertex(Attributes attributes) { Varyings o = (Varyings)0; o.positionCS = TransformObjectToHClip(attributes.positionOS); o.uv = TRANSFORM_TEX(attributes.uv, _NormalMap); o.uv = attributes.uv; o.color = attributes.color; o.normalWS = TransformObjectToWorldDir(float3(0, 0, -1)); o.tangentWS = TransformObjectToWorldDir(attributes.tangent.xyz); o.bitangentWS = cross(o.normalWS, o.tangentWS) * attributes.tangent.w; return o; } #include "Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/NormalsRenderingShared.hlsl" float4 NormalsRenderingFragment(Varyings i) : SV_Target { float4 mainTex = i.color * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv); float3 normalTS = UnpackNormal(SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, i.uv)); return NormalsRenderingShared(mainTex, normalTS, i.tangentWS.xyz, i.bitangentWS.xyz, i.normalWS.xyz); } ENDHLSL } Pass { Tags { "LightMode" = "UniversalForward" "Queue"="Transparent" "RenderType"="Transparent"} HLSLPROGRAM #pragma prefer_hlslcc gles #pragma vertex UnlitVertex #pragma fragment UnlitFragment struct Attributes { float3 positionOS : POSITION; float4 color : COLOR; float2 uv : TEXCOORD0; }; struct Varyings { float4 positionCS : SV_POSITION; float4 color : COLOR; float2 uv : TEXCOORD0; }; TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex); float4 _MainTex_ST; Varyings UnlitVertex(Attributes attributes) { Varyings o = (Varyings)0; o.positionCS = TransformObjectToHClip(attributes.positionOS); o.uv = TRANSFORM_TEX(attributes.uv, _MainTex); o.uv = attributes.uv; o.color = attributes.color; return o; } float4 UnlitFragment(Varyings i) : SV_Target { float4 mainTex = i.color * SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv); return mainTex; } ENDHLSL } } Fallback "Sprites/Default" }
Well, the last question you need to answer is ... does Unity's post processing stack support DoF with an orthographic camera? I honestly have no idea. I also don't know if the 2D Renderer generates a depth texture. Try using some default LWRP lit materials on some meshes in your 2D project and see if DoF works on them. If they don't then you might be out of luck either way.
oh I am using Perspective now. Yep I will try with default LWRP lit material with sphere to see if it generates depth texture with 2d renderer. it its 00:47 and need to go to bed for tomorrow work! I will let you know tomorrow! Thanks @bgolus
so when it is URP > ForwardRenderer with URP/Lit material. it works and Change to 2D renderer, with 3d sphere with URP/Lit, doesn't seem to generate depth texture. I will bring this up in 2D forum to ask and if 2D renderer can be updated with depth texture feature. Thank you @bgolus