I would like to mask an outline postprocess shader by the shadow map on screen, so that the outline only appears on lit parts of the scene. Is there a macro or a trick to get this texture? I read about commandbuffers, but really have no starting point, of how to get there, if its even possible-
I just found the solution! So I was also searching for a way to sample the screen space shadow texture with a commandbuffer and noticed, that they use this technique in the 3D GameKit from Unity! And it just seems to work straight out of the box this way! I saw many questions about this and nobody ever posted his working code, so here ya go! Code that should be attached to the main directional light: Code (CSharp): using UnityEditor; using UnityEngine; using UnityEngine.Rendering; namespace Gamekit3D { [ExecuteInEditMode] public class CopyShadowMap : MonoBehaviour { CommandBuffer cb = null; void OnEnable() { var light = GetComponent<Light>(); if (light) { cb = new CommandBuffer(); cb.name = "CopyShadowMap"; cb.SetGlobalTexture("_DirectionalShadowMask", new RenderTargetIdentifier(BuiltinRenderTextureType.CurrentActive)); light.AddCommandBuffer(UnityEngine.Rendering.LightEvent.AfterScreenspaceMask, cb); } } void OnDisable() { var light = GetComponent<Light>(); if (light) { light.RemoveCommandBuffer(UnityEngine.Rendering.LightEvent.AfterScreenspaceMask, cb); } } } } And in the shader, access the map likes this: Code (CSharp): sampler2D _DirectionalShadowMask; and in the surf/fragment shader: Code (CSharp): float shadowmask = tex2D(_DirectionalShadowMask,screenUV).b; Theres also this Macro written there, but I'm not sure for what it's used: Code (CSharp): UNITY_DECLARE_SHADOWMAP(_DirectionalShadowMap); (I just didnt used it and it still worked) Also thanks to @bgolus for clearing this up: That's for defining a shadow map texture object ... which technically the screen space shadow texture is not so can be ignored. You've already defined it as a sampler2D, which is what it is. Anyways, I hope this helps someone!
Bumping this because I have an issue. The solution above works, except if I set: Code (CSharp): camera.depthTextureMode = DepthTextureMode.DepthNormals; In that case, it seems like the current active render target in AfterScreenspaceMask is no longer the screenspace shadowmask, but instead _CameraDepthNormalsTexture. I have a feeling this may be a bug because the documentation states: But I'm no shader expert. (tested in Unity 2018.4.14f1 & 2019.3.10f1) @bgolus Do you know if this is a known limitation?
Sounds like a bug to me, yeah. The depth normal texture should only be the current target when using CameraEvent.AfterDepthNormalsTexture on a camera command buffer. Report it with a repro.
Submitted. Case 1245576. The conditions for it to happen seem to be: Only one camera in the scene Rendering path set to Deferred DepthNormals texture enabled via script