alelievr / HDRP-Custom-Passes

A bunch of custom passes made for HDRP
MIT License
1.31k stars 138 forks source link

Example for additional pass #13

Closed kenamis closed 4 years ago

kenamis commented 4 years ago

Hi, is there a good example or recommendation on how to render another pass in a shader (without a new material), or another shader entirely?

I'm trying to do an unlit render of objects with a color id map on each object to a RenderTexture (to look up later), in addition to the regular lit pass. I know I could use the Graphics api to re-render all those objects, but as far as I know, that's extra unnecessary work.

In the current examples with DrawRenderers, it looks like you need to use another material, which means then I can't have per-instance texture inputs. I also can't specify another pass without specifying a material. Do I need to make a new custom pass that takes all filtered objects, reads the current shader the object and renders with a named pass?

Thanks

andybak commented 4 years ago

Did you close this because you solved it? If so some insight would be valuable for others.

kenamis commented 4 years ago

Yes. It was embarrassingly simple after I started reading through the code. It's essentially exactly the same as the DrawRenderers but without the override material or pass index. The thing that was tripping me up was I had a lightmode tag in my shader. I set it to the name of my pass, which fixed the issue, but I think shouldn't need it at all for an unlit shader (I need to look in to this further).

[System.Serializable]
class ColorID : CustomPass
{
    public string passName;
    public LayerMask layerMask = -1;

    ShaderTagId shaderTagId;

    // It can be used to configure render targets and their clear state. Also to create temporary render target textures.
    // When empty this render pass will render to the active camera render target.
    // You should never call CommandBuffer.SetRenderTarget. Instead call <c>ConfigureTarget</c> and <c>ConfigureClear</c>.
    // The render pipeline will ensure target setup and clearing happens in an performance manner.
    protected override void Setup(ScriptableRenderContext renderContext, CommandBuffer cmd)
    {
        // Setup code here
        shaderTagId = new ShaderTagId(passName);
    }

    protected override void Execute(ScriptableRenderContext renderContext, CommandBuffer cmd, HDCamera camera, CullingResults cullingResult)
    {
        if (string.IsNullOrEmpty(passName))
            return;

        // Executed every frame for all the camera inside the pass volume
        RendererListDesc result = new RendererListDesc(shaderTagId, cullingResult, camera.camera)
        {
            rendererConfiguration = PerObjectData.None,
            renderQueueRange = RenderQueueRange.all,
            sortingCriteria = SortingCriteria.CommonOpaque,
            excludeObjectMotionVectors = false,
            layerMask = layerMask,
        };

        HDUtils.DrawRendererList(renderContext, cmd, RendererList.Create(result));
    }

    protected override void Cleanup()
    {
        // Cleanup code
    }
}