Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Custom Render Pass & Custom buffers

Discussion in 'High Definition Render Pipeline' started by Ziboo, Oct 10, 2019.

  1. Ziboo

    Ziboo

    Joined:
    Aug 30, 2011
    Posts:
    356
    Hi,

    I'm using the new Custom Pass feature in HDRP.
    https://github.com/Unity-Technologies/ScriptableRenderPipeline/pull/4317

    My goal is to render the all image in Black and White except for certain objects.

    I created a FullScreenCustomPass with a shader that output the grayscale version of the image.

    Now, I would need to not do that on the objects I tag.

    If I can avoid using Layers to do it, that would be great.

    I saw that there is a "SampleCustomColor(float2 uv)" in the shader template for FullScreenPass.

    It seems that I could write to a custom buffer, which would be perfect for my case.

    I could write red on every objects I want to isolate from the grayscale.

    But I didn't find anything on how, where, to write to the custom buffer.

    Can someone have an insight on that ?

    Or maybe a better solution ?

    Thank you
     
    Last edited: Oct 10, 2019
    Kaldrin likes this.
  2. antoinel_unity

    antoinel_unity

    Unity Technologies

    Joined:
    Jan 7, 2019
    Posts:
    229
    Hello,

    Concerning the HDRP custom pass feature, there are some example of how to implement some effects here: https://github.com/alelievr/HDRP-Custom-Passes, The closest effect to what you want to acheve is the Slight Blur which have a mask faeture to not blur some objects.

    You can use the DrawRenderers custom pass to render only objects you want to render in color and store them in the custom buffer allocated by HDRP, once you have that, you can sample the buffer into the fullscreen pass using SampleCustomColor. The only problem is that you can't filter objects by anything else than the layer.

    If you don't mind writing some C#, you could create a new custom pass type which calls direcrtly the DrawRenderers function (There is an exmaple in the Slight Blur effect I pointed), then you will have access to all the filter available in the API. If you don't want to use layers, you still have the rendering layer mask that you can setup on the Renderer.

    One more thing, it may be a bit early but here is the V1 of the doc for custom passes i've been working on: https://github.com/Unity-Technologi...high-definition/Documentation~/Custom-Pass.md.
     
    eizenhorn likes this.
  3. Ziboo

    Ziboo

    Joined:
    Aug 30, 2011
    Posts:
    356
    Thanks Antoine !
    I'll check that ASAP.
     
  4. iamarugin

    iamarugin

    Joined:
    Dec 17, 2014
    Posts:
    861
    @antoinel_unity I am trying to copy the result of DrawRenderersCustomPass to the render texture, to use it in the UI. I am trying the following code:
    Code (CSharp):
    1. public class RenderToTexturePass : DrawRenderersCustomPass {
    2.         public RenderTexture renderTexture;
    3.  
    4.         protected override void Execute(ScriptableRenderContext renderContext, CommandBuffer cmd, HDCamera hdCamera, CullingResults cullingResult) {
    5.             base.Execute(renderContext, cmd, hdCamera, cullingResult);
    6.  
    7.             GetCustomBuffers(out RTHandle color, out _);
    8.  
    9.             cmd.CopyTexture(color, renderTexture);
    10.         }
    11.     }
    The render texture and the color buffer formats (r16g16b16a16_SFloat) and width/height are the same . But I am getting the following error in the console:
    Code (CSharp):
    1. Graphics.CopyTexture called with mismatching texture types (src=5 dst=2)
    2.  
    What am I missing?
     
  5. antoinel_unity

    antoinel_unity

    Unity Technologies

    Joined:
    Jan 7, 2019
    Posts:
    229
    In HDRP, when you allocate a render target, you must use the RTHandle system that automatically handles screen resizing, support of VR and reuse between different cameras.
    Here is an example of an RTHandle allocation:
    Code (CSharp):
    1. RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, useDynamicScale: true, name: "Buffer Debug Name");
    The error you have is due to the dimension of the texture you're copying, i guess your RenderTexture is a Tex2D but the color buffer of the camera which is a RTHandle is a Tex2DArray (for VR support). Also since RTHandles supports multiple camera of different size, when you do a copy, it may result in unused memory being copied, to avoid that you can do a copy of only the size of the current camera (Note tat you have access to the RThandle size in the property struct).
     
  6. Elynwir

    Elynwir

    Joined:
    Nov 3, 2019
    Posts:
    1
    @antoinel_unity I'm trying to understand the custom pass API, basing my work off the examples you have provided. In my case, I need an outline on a single object, not a whole layer, and I can't put it in a separate layer (because I'm using it for physics logic). You mentioned using the rendering layer mask but I can't figure out how to actually use this. I tried replacing this block of code
    Code (CSharp):
    1. void DrawOutlineMeshes(ScriptableRenderContext renderContext, CommandBuffer cmd, HDCamera hdCamera, CullingResults cullingResult) {
    2.     var result = new RendererListDesc(shaderTags, cullingResult, hdCamera.camera) {
    3.         // We need the lighting render configuration to support rendering lit objects
    4.         rendererConfiguration = PerObjectData.LightProbe | PerObjectData.LightProbeProxyVolume | PerObjectData.Lightmaps,
    5.         renderQueueRange = RenderQueueRange.all,
    6.         sortingCriteria = SortingCriteria.BackToFront,
    7.         excludeObjectMotionVectors = false,
    8.         layerMask = outlineLayer,
    9.     };
    10.     CoreUtils.SetRenderTarget(cmd, outlineBuffer, ClearFlag.Color);
    11.     HDUtils.DrawRendererList(renderContext, cmd, RendererList.Create(result));
    12. }
    with the following:
    Code (CSharp):
    1. void DrawOutlineMeshes(ScriptableRenderContext renderContext, CommandBuffer cmd, HDCamera hdCamera, CullingResults cullingResult) {
    2.     DrawingSettings drawingSettings = new DrawingSettings() {
    3.         perObjectData=(PerObjectData.LightProbe | PerObjectData.LightProbeProxyVolume | PerObjectData.Lightmaps),
    4.         sortingSettings=new SortingSettings(hdCamera.camera),
    5.     };
    6.     FilteringSettings filteringSettings = FilteringSettings.defaultValue;
    7.     CoreUtils.SetRenderTarget(cmd, outlineBuffer, ClearFlag.Color);
    8.     renderContext.ExecuteCommandBuffer(cmd);
    9.     cmd.Clear();
    10.     renderContext.DrawRenderers(cullingResult, ref drawingSettings, ref filteringSettings);
    11. }
    and tried all kinds of variations of the filter/drawing settings, but I couldn't get the outlines to actually show up. I'm not sure if my renderingLayerMask was wrong, since I couldn't expose this as an enum field in the editor - I ended up opening the debug mode inspector, copying the uint value of the mask of a renderer, and pasting it into my code, to no avail.

    My question is: what am I doing wrong here? Or alternatively, is there a way to specify a list of renderers explicitly?
     
  7. punk

    punk

    Joined:
    Jun 28, 2013
    Posts:
    399
    @Elynwir and anyone else that comes here I just figured this out

    Code (CSharp):
    1.         void DrawOutlineMeshes(ScriptableRenderContext renderContext, CommandBuffer cmd, HDCamera hdCamera, CullingResults cullingResult)
    2.         {
    3.             var result = new RendererListDesc(shaderTags, cullingResult, hdCamera.camera)
    4.             {
    5.                 // We need the lighting render configuration to support rendering lit objects
    6.                 rendererConfiguration = PerObjectData.LightProbe | PerObjectData.LightProbeProxyVolume | PerObjectData.Lightmaps,
    7.                 renderQueueRange = RenderQueueRange.all,
    8.                 sortingCriteria = SortingCriteria.BackToFront,
    9.                 excludeObjectMotionVectors = false
    10.             };
    11.  
    12.             CoreUtils.SetRenderTarget(cmd, outlineBuffer, ClearFlag.Color);
    13.  
    14.             RendererList renderList = RendererList.Create(result);
    15.             renderList.filteringSettings.renderingLayerMask = 1 << 7;
    16.  
    17.             HDUtils.DrawRendererList(renderContext, cmd, renderList);
    18.         }
     
    Hubster likes this.