Search Unity

Question How to access Scene Colour texture Pre-Transparent queue? (Custom function?)

Discussion in 'Shader Graph' started by Tset_Tsyung, Sep 2, 2021.

  1. Tset_Tsyung

    Tset_Tsyung

    Joined:
    Jan 12, 2016
    Posts:
    411
    Hey all,

    Using Unity 2020.3.12f1 (can change -just experimenting at this stage) with URP 10.5.1 and Shader Graph 10.5.1.

    I'd like to create a refraction effect for some ice - this will only be used once and far away from the camera.

    Using the Scene Color node is problematic as it's only availble during the Transparent stage (according to the docs), meaning that it captures all objects and therefore as I adjust the UV coords to mimic refraction I'm picking up objects that were rendered closer to the camera, not just those rendered behind the 'ice' object. As the object is rather large, Reflection probes aren't really suitable (I believe, could be wrong).

    I'm thinking of getting the camera's render texture during the rendering process (provided it's rendering far to near?), but I only want to intercept mid-render (I don't want to render out a full scene render again).

    Is this possible?

    N.B. I was looking at RenderBuffer, but this documentation states that the native texture is, for me on a PC at least, unavailable.

    I'm hoping to plug holes in my knowledge (not just learn to 'do a thing'), so if theres a couple of good 'beginner' (more programmer than artist, but branching out) books or guides on this subject that would be greatly appreciated.

    Kindest regards,


    Mike
     
  2. Sinterklaas

    Sinterklaas

    Joined:
    Jun 6, 2018
    Posts:
    93
    This is difficult to do for a couple of reasons, and it has to do with the way Unity sorts its draw calls. For a simple refraction effect, you need a texture with whatever is behind an object, and then move uvs around so it looks similar to true refraction. Sounds pretty simple, right?

    The problem lies in the fact that, for each camera in a scene, Unity first renders all opaque objects front-to-back, and then renders all transparent objects back-to-front. There is a reason for this: rendering opaque objects front-to-back means that you can typically cull a lot of fragments in a busy scene, offering a significant performance boost. Transparent objects cannot do this however, since their color needs to be blended with whatever is behind it, so they are rendered in the opposite order.

    With this in mind, getting the color of whatever is behind an opaque object suddenly becomes impossible, since whatever is behind them hasn't been rendered yet. This is why the scene color node doesn't do anything for opaque objects.

    One solution would be to draw everything in a back-to-front order, though there are two problems with this: Unity by default doesn't allow transparent objects to write to the _CameraOpaqueTexture that is used behind-the-scenes in the scene color node, and second performance would probably be pretty bad.

    The easiest way that I can think of to achieve this effect is probably using multiple cameras, but beware because it will get messy, and you'd still be left with the problem of only opaque objects being refracted.
     
    LeeYoungBum likes this.
  3. Tset_Tsyung

    Tset_Tsyung

    Joined:
    Jan 12, 2016
    Posts:
    411
    Yes I suddenly realised this last night when trying to sleep ha ha. But it's good to have it confirmed.


    I'm glad you mentioned this, as I wasnt sure this would work. Thankfully, I was only goint to have 1 (maybe 2) refractive objects in this particular scene... but even then I'd have to do more research and testing. I can see some issues with trying to set the near clipping plane to the start of the refractive object when another object is partially within the range of that cliping plane and just in front... but then again backface culling should solve a big chunk of those issues...

    Thank you for your time and effot Sinterklass. Having someone more knowledge close off some avenues of random thinking really helps :D. I noticed that HDRP has a refaction option in their transparent shaders. Does this do something similar with rendering behind the objects first?

    Mike
     
  4. Sinterklaas

    Sinterklaas

    Joined:
    Jun 6, 2018
    Posts:
    93
    I'm afraid I don't know anything about that (I'm mostly an URP user). Looking at the reference page, it seems to only be an option for transparent shaders. If that is the case, you'll probably get similar artifacts where objects in front of the refractor will be refracted too. But like I said, I'm not an expert, so give it a try and see how it performs.