as soon as you enable decals URP will perform a depthnormal pass upfront.
in case “accurate gbuffer normals” are unchecked the generated normal buffer will match 1:1 the gbuffer2.rgb output generated in the gbuffer pass later on.
according to renderdoc the normal buffer in the depthnormal pass is bound to _GBuffer2 - which does not cleared before the gbuffer pass.
so wouldn’t it be a nice win to simply skip normals in the gbuffer pass and simply sample them from the already existing _GBuffer2 in order to calculate ambient in case decals are enabled and “accurate gbuffer normals” are unchecked?
furthermore i could not find any code that would disable alpha testing and set ZTest to Equal in case the depth buffer is rendered upfront - some nice performance improvement HDRP offers.
Yea I agree this would be good optimization, the only concern that this might require additional variant.
Could you eleborate on this a bit more? Is it for decals?
no, it is not related to decals.
this is related to alpha testing.
when doing alpha testing you loose early z out.
so a common way to get early z testing back in is to do a depth prepass.
the depth prepass of course uses alpha testing but usually is a rather cheap pass as only one texture is used, no shadow coords have to be calculated, no gi, no fog coords, no sh lighting …
the the “regular” shader uses no alpha testing at all but fully relies on “ZTest Equal”.
we use it all across the board in HDRP as you get zero overdraw! even fully opaques benefit from it as the rendering order and sorting might not always be perfects.
and adding a depth prepass to the built in rendering pipeline and rendering out a lot of “alpha tested” grass using a depth prepass on metal gave me a nice 25% performance increase.
proper depth prepass support in urp is something i have requested for years now
and now we are pretty close to it!
ah, the decal stuff. it is getting even worse if you check “accurate normals” and have custom shaders which come with their own lighting and therefore declare: Tags{“LightMode” = “UniversalForwardOnly”}
in this case the depthprepass has to output 8bit rgb normals to make decals work.
and you have to add a dummy gbuffer pass which only fixes the normals from rgb to octha encoded.
this is more than annoying!
so make decals use:
#pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT
when reading the depthnormal texture.
so all passes and shaders uses the same encoding: decals and ssao.
having decals rely on normals as rgb but ssao rely on octha encoded normals does not really make much sense - unless you fill your entire screen with decals.
unlike decals ssoa will touch any pixel on screen and always do the expansive octha decode.
or use “PackFloat2To888” across the board and store the sign of the reconstructed 3rd component of the normal in the highest bit of the smoothness component. 128 smoothness values still are a lot 
you may even switch smoothness and material flags. so gbuffer2.a stores the material flags.
just do anything but stop rendering out the normals twice!
just think of a rather expensive shader like terrain.
another possibility:
skip octa encoded normals and add the option to use crytek’s best fitting normals on really smooth materials where you need more precision.
this would be on a per material basis - which i think fits well with urp being the high performance pipeline. let the user decide where high quality normals are needed.
just imagine a car driving through a forest environment. the car would make you enable hq normals but right now you even pay their costs on the terrain or pretty rough rocks.