Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Can depth-based fog be married with semi-transparent objects?

Discussion in 'Image Effects' started by benjmitch, Dec 21, 2021.

  1. benjmitch

    benjmitch

    Joined:
    Nov 27, 2019
    Posts:
    17
    Hi,

    I'm working with Unity 2021.2 and URP/deferred/Shader Graph, but I hope this is a more general question.

    I'm trying to render part of a world (the water) as semi-transparent, yet have the air above fogged (very simply) based on the scene depth, and I cannot figure a way to get the two things to co-exist.

    The objects (water) have clean edges, no feathering. That is, the surface's scene depth is well-defined, it's semi-transparent like glass, not like mist. I can see that depth-based fog on a "misty" object requires careful definition, but depth-based fog on a semi-transparent object doesn't seem problematic. The scene depth of the water surface is defined, I just can't get it to find its way to the fog computation.

    The semi-transparent elements render as desired, but they do not write the depth texture as far as I can tell. In any case, the fog renders as if they hadn't. Setting "depth write" to "force enabled" in Shader Graph Graph Settings makes no difference that I can detect, though it is reflected in "View Generated Shader" in the "Universal" branch(es). Should this be possible, is this the right thing to do and I'm just doing it wrong? Or does doing this just make no sense for a reason I can't guess?

    I can render the water opaque, which obviously doesn't meet the requirements, and the fog then works fine.

    Is it not possible to get a transparent-queue shader to write into the depth texture? If not, why not? Is the done thing, as I've seen hints of, to write into some other buffer, and then derive fog from that? Is this a "more complex" case and to achieve it I have to learn more? If it can't be done, is there a fundamental reason why not, is it not implemented, or is it a problem specific to the configuration I've chosen?

    I could create a second object of the same shape as the water object, make it opaque, and have it write the depth texture. But I'd have to render it after the transparent objects (since they read the depth buffer) and, in addition, it'd have to be invisible. I can't see how to do either, but I can see that this approach at least is feasible. Is this the way?

    This must be a common class of problem, I just can't find any post that really clears it up for me - can anyone advise me how to think about it, please, or point me at the right documentation?

    Thanks for any help