Search Unity

Bug Sampling Custom Pass in SG is broken

Discussion in 'High Definition Render Pipeline' started by Passeridae, May 5, 2022.

  1. Passeridae

    Passeridae

    Joined:
    Jun 16, 2019
    Posts:
    395
    I've already pointed to this issue some time ago in this thread.
    Here's the problem:

    1. If I sample any buffer (_GBufferTexture0, _GBufferTexture1, _CameraMotionVectorsTexture, _WhateverTexture, etc.) in a full-screen custom pass.

    2. Sample it in any way: LOAD_TEXTURE2D_X, SAMPLE_TEXTURE2D_X, or using helpers
    DecodeMotionVector, DecodeFromNormalBuffer, etc.

    3. And use any injection point for the custom pass (keeping in mind that not all buffers are available at every points, yeah).

    4. And then write the result to the customColorBuffer (or my own render texture).

    5. And then sample it in any SG in any way: using the official Custom Color Node node or using a regular sampler, or using the global set from script and then my own custom function, etc.

    Each time and in any combination this results in artifacts described in the linked thread. My theory is that for some unimaginable reason SG shaders receive not the current frame, but the previous one. And obviously it lags behind. I've managed to suppress that lag a bit, using "UV - MotionVectors" instead of the regular "UV" for sampling custom color buffer. This supports my theory about the previous frame. This happens on any Unity version I've tried with any HDRP package I've tried. This bug is also observed by some other people that I've asked.

    It seems like something is fundamentally broken in sampling custom pass in SG from day one. This happens even with the official Custom Pass examples. For instance, this one has the described bug. It isn't easy to notice it in this particular case, though, because of the transparent material. But if you make it opaque it becomes more obvious. Especially if you move the camera fast enough.

    There's only one way of getting rid of this bug completely that I'm aware of: adding an empty drawrenderers custom pass that injects after the full-screen custom pass.

    This happens with and without TAA. So, temporal stuff has nothing to do with it. And this happens for both Deferred and Forward. Though, Lit is the only deferred mat in HDRP, so I guess it doesn't really matter. And this happens only when sampling it in Graphs. If I write directly to camera or sample in in another custom pass - everything is fine.
     
    Last edited: May 5, 2022
    Lymdun and ssurget like this.