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

Question How to render meshes to a render texture immediately using URP?

Discussion in 'Universal Render Pipeline' started by CDF, Oct 11, 2021.

  1. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,282
    Hi, So I'm struggling to figure out how to render some meshes to a render texture immediately in URP.
    In the built-in pipeline you can build a command buffer and call Graphics.ExecuteCommandBuffer
    However, in URP, doing this results in pink materials.

    I want to just draw some objects to a texture at any time and have that function return a Texture2D.

    I see that using RenderPipelineManager.beginContextRendering does work, but that means I can't return a texture immediately.

    What do I need to do, in order to render some meshes at anytime to a texture in URP?
     
  2. RyanKeable

    RyanKeable

    Joined:
    Oct 16, 2013
    Posts:
    62
  3. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,282
    Hmm, doesn't that mean you need a ScriptableRenderFeature added to the pipeline?

    I don't want a persistent render feature added. I just want to render some meshes to a texture on some event.
    Like pressing a button.

    How can you inject a ScriptableRenderPass, execute it and get the results in a single call?
     
    febucci likes this.
  4. j_chai

    j_chai

    Joined:
    Jun 30, 2021
    Posts:
    35
    Most likely a terrible idea, but this worked for me:
    Add an Action to RenderPipelineManager.beginCameraRendering, as an example I'm calling mine "RenderNow", containing something like:
    Code (CSharp):
    1. private void RenderNow(ScriptableRenderContext context, Camera camera)
    2. {
    3.     // initialize [_renderingCamera] with the perspective you want to render from
    4.     if (camera == _renderingCamera)
    5.     {
    6.         var cmd = CommandBufferPool.Get();
    7.         // Set RT
    8.         // cmd.SetRenderTarget(rt);
    9.         // Clear RT
    10.         // cmd.ClearRenderTarget(true, true, Color.black);
    11.         // Your renderer and Material here, any Draw function from the command buffer should be usable
    12.         // cmd.DrawRenderer(renderer, material);
    13.         context.ExecuteCommandBuffer(cmd);
    14.         CommandBufferPool.Release(cmd);
    15.     }
    16. }
    Disable the [_renderingCamera] GameObject, and call _renderingCamera.Render whenever you want to render.
     
  5. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,282
    Thanks.

    Turns out Graphics.DrawMesh works within that callback, and is more useful to me, as I can specify the layer and camera to draw the meshes into.

    Basically, I'm trying to render a static preview of some meshes isolated from other scene elements (lighting, shadows) etc. So while the command buffer method does work, it unfortunately includes lighting and shadow information from the current scene.

    Would be nice if there was a way to render some meshes excluded from all scene lighting and provide my own lighting setup... maybe it's possible for a command buffer to override some internal values, like light color, light direction, shadow map etc. But not sure
     
  6. j_chai

    j_chai

    Joined:
    Jun 30, 2021
    Posts:
    35
    I'm not sure if you can override Unity's shader values using command buffers either, but one option is to guard the lighting, GI, etc, calculation just like how you can define [SHADERGRAPH_PREVIEW] in shadergraph shaders.
    You'll either need to modify the URP package or modify your custom shader,
    but you can have something like this in your shader code:
    Code (CSharp):
    1. #ifdef STATIC_PREVIEW
    2. Light GetMainLight()
    3. {
    4.     Light output = (Light)0;
    5.     output.direction = half3(0, 0, 1);
    6.     output.color = half3(1, 1, 1);
    7.     // ...
    8.     return output;
    9. }
    10. #else
    11. Light GetMainLight()
    12. {
    13.     // Unity's GetMainLight function
    14. }
    15. #endif
    You could then use Material.EnableKeyword before calling Graphics.DrawMesh.
    Don't forget to add #pragma multi_compile or shader_feature if you use this method.
     
    CDF likes this.
  7. BOXOPHOBIC

    BOXOPHOBIC

    Joined:
    Jul 17, 2015
    Posts:
    481
    Hey, this might help: https://www.dropbox.com/s/oxa85e0vfauscpc/renderwithoutcamera2.unitypackage?dl=0

    It is rendering unlit objects or particles to a render texture in a defined volume, from top down, basicaly like an ortographic camera. It can be turned into a perspective cam by modifing some matrix I used, and it can save the overhead from adding a new camera and save some layers.

    This is some early experimentation I used while developing my asset, the veg engine, I m not sure what s the state on it, it might me messy...

    If you want to suppot all pipelines with an unlit shader, a nice trick is to remove the LightMode tag. I hope it helps :)
     
  8. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,282
    Thanks, I'll check this out
     
  9. qpuilie

    qpuilie

    Joined:
    Jan 14, 2020
    Posts:
    69
    Hi,I am also plagued by the same problem.I want to render terrain depth in single rendertexture use "DepthOnlyPass".
    Currently I only found one way to successfully write Mesh to RenderTexture:
    It won't work if i don't use callbacks.
    Did you find a solution?

    Thanks.
     

    Attached Files:

  10. dsfgddsfgdsgd

    dsfgddsfgdsgd

    Joined:
    Jan 24, 2014
    Posts:
    16
    This is great thanks so much for sharing