Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Unlit HDRP Replacement Shader or RenderWithShader

Discussion in 'Graphics Experimental Previews' started by Dreamback, Jul 18, 2019.

  1. Dreamback

    Dreamback

    Joined:
    Jul 29, 2016
    Posts:
    220
    We have a need for a replacement shader with HDRP, where one camera renders everything in the scene with with a special shader (specifically, this shader uses a material property to color code each object with a specific flat color, with the output being used by a Compute Shader rather than displayed visually). Is there a way to enable this functionality with the HD Render Pipeline?
     
    urani_the_cat and ModLunar like this.
  2. Dreamback

    Dreamback

    Joined:
    Jul 29, 2016
    Posts:
    220
    I've found a way around this...kinda, but it's missing something. I used HDAdditionalCameraData.customRender to make my own very simple render pipeline, and in that pipeline I use DrawingSettings.overrideMaterial with a new material that uses my old non-HD replacement shader. Boom! Shader replaced during camera render.

    Unfortunately, it isn't getting any data from the original material - at scene load I set a material property storing which color to display on all materials in the scene, but that property is lost with DrawingSettings.overrideMaterial. Which makes sense, it's truly overriding the material, but I can't figure out a way to get/set those settings in the pipeline.
     
    Last edited: Jul 20, 2019
  3. Dreamback

    Dreamback

    Joined:
    Jul 29, 2016
    Posts:
    220
    Got it working - instead of setting properties on the Material, set a Material Properties Block on the Renderer.

    So here's my final solution to a Replacement Shader:
    • Set the material properties for your shader using MaterialPropertyBlock on the object renderer
    • Use HDAdditionalCameraData.customRender to make your own simple render pipeline
    • Create a material with your replacement shader on it, use DrawingSettings.overrideMaterial to set it in your pipeline
    • Profit!

    The shader on the overrided material will use the property settings from the Material Properties Block. All our HDRP/Lit shaders get replaced with our custom shader when using that code.
     
    Last edited: Jul 22, 2019
    Olmi, rukqoa, OCASM and 3 others like this.
  4. Dreamback

    Dreamback

    Joined:
    Jul 29, 2016
    Posts:
    220
    Darn, found another problem - from what I can tell, when using overrideMaterial you also lose the links to the textures, just like you use the other property settings. So if your replacement shader needs the textures that have been applied to the materials, this won't work for you (unless you apply those textures to a Materials Property Block as well).
     
    Last edited: Aug 27, 2019
  5. rukqoa

    rukqoa

    Joined:
    Apr 6, 2013
    Posts:
    10
    I stumbled upon this thread trying to add a replacement shader in an HDRP project and it helped me get started. I cobbled together some working-ish code for a barebones custom renderer and honestly I don't know how most of it works, but it does for me:

    Code (CSharp):
    1. public void RenderSpecial() {
    2.     HDAdditionalCameraData hdAdditionalCameraData = Camera.main.GetComponent<HDAdditionalCameraData>();
    3.     hdAdditionalCameraData.customRender += SpecialRenderer;
    4. }
    5.  
    6. public void RenderNormal() {
    7.     HDAdditionalCameraData hdAdditionalCameraData = Camera.main.GetComponent<HDAdditionalCameraData>();
    8.     hdAdditionalCameraData.customRender -= SpecialRenderer;
    9. }
    10.  
    11. public void SpecialRenderer(ScriptableRenderContext context, HDCamera camera) {
    12.     CommandBuffer cameraBuffer = new CommandBuffer {
    13.         name = "Render Camera"
    14.     };
    15.  
    16.     cameraBuffer.ClearRenderTarget(true, true, camera.backgroundColorHDR);
    17.  
    18.     cameraBuffer.BeginSample("Render Camera");
    19.     context.ExecuteCommandBuffer(cameraBuffer);
    20.     cameraBuffer.Clear();
    21.  
    22.     context.SetupCameraProperties(camera.camera);
    23.  
    24.     camera.camera.TryGetCullingParameters(out ScriptableCullingParameters cullingParameters);
    25.     CullingResults cullingResults = context.Cull(ref cullingParameters);
    26.  
    27.     DrawingSettings drawingSettings = new DrawingSettings();
    28.  
    29.     drawingSettings.SetShaderPassName(0, new ShaderTagId("DepthOnly"));
    30.     drawingSettings.SetShaderPassName(1, new ShaderTagId("SRPDefaultUnlit"));
    31.     drawingSettings.SetShaderPassName(2, new ShaderTagId("Vertex"));
    32.  
    33.     drawingSettings.overrideMaterial = myMaterial;  // set this
    34.  
    35.     FilteringSettings filteringSettings = new FilteringSettings(RenderQueueRange.all);
    36.     context.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings);
    37.  
    38.     context.DrawSkybox(camera.camera);
    39.  
    40.     cameraBuffer.EndSample("Render Camera");
    41.     context.ExecuteCommandBuffer(cameraBuffer);
    42.     cameraBuffer.Clear();
    43.  
    44.     context.Submit();
    45. }
    Hope this helps someone else.
     
  6. rukqoa

    rukqoa

    Joined:
    Apr 6, 2013
    Posts:
    10
    I'm also running into problems working with replacing VFX shaders. According to the compiled code for the VFX shaders, their lightmode should be ForwardOnly, but trying to replace the material on that pass name isn't doing anything, even when I try to literally copy the entire shader over. There must something special about them.

    Edit: Hm. When I don't try to override the shader, it seems to render regularly just fine with the exception that it can't handle me rotating my camera. Now I just have to figure out how to replace the material properly.
     
    Last edited: Sep 10, 2019
  7. pyjamaslug

    pyjamaslug

    Joined:
    Jul 5, 2017
    Posts:
    51
    I am very new to SRP/HDRP and am struggling to make sense of it. I need this same replacement shader equivalent but I am not even at the stage of being able to set up a special shader on my camera (in fact, is it a shader or a complete alternative render pipeline?). Can someone give me a simple guide to how I set up a scene with two cameras, one rendering with the HDRP path and the other using a custom path?
    I see the control on the camera that allows me to set a custom render path but then what?
    @rukqoa I see your script and its easy to follow but it is a fragment from a class - what is the class and where/how did you attach it to the camera?