Search Unity

Built-In Pipeline Decals: G-Buffer with Ambient Lighting

Discussion in 'General Graphics' started by adamgryu, Nov 18, 2020.

  1. adamgryu

    adamgryu

    Joined:
    Mar 1, 2014
    Posts:
    188
    Hello! I'm looking for a decal solution for the built-in pipeline.

    I'm starting with this as the base for my decal system:
    https://blogs.unity3d.com/2015/02/06/extending-unity-5-rendering-pipeline-command-buffers/

    It uses Command Buffers to write the decal to the G-Buffer before the deferred lighting pass.

    This is a great starting point - but the decals don't work unless the surface is lit by some light. Thus, surfaces in shadow or scenes with just ambient light won't work. I'm also not sure if the decals incorporate the ambient light into their lighting.

    Is anyone able to point me in a direction to take these decals and add ambient support to them?

    EDIT: Also, is there any way to make the decals only specific to certain layers? Perhaps this isn't a good starting point if these decals are drawn on top of characters too.
     
    Last edited: Nov 18, 2020
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    The "trick" is you have to manually get and assign the ambient lighting from lighting probes before applying them. There are now tools to help with that in the more recent versions of Unity too.
    https://docs.unity3d.com/ScriptRefe...ulateInterpolatedLightAndOcclusionProbes.html

    This does mean if your projecting onto meshes have light maps, they won't accurately reflect that as it's using the dynamic object lighting. And there's not a perfect way to work around that either. It requires changing all deferred shaders to render their ambient lighting out without pre-multiplying it by the albedo, and then adding a pass to multiply the light accumulation buffer (which is what the ambient lighting is rendered into) by the albedo after applying decals but before deferred lighting occurs. The side effect of this is emissive and baked specular will be broken. Alternatively you could use a replacement shader pass that only renders the baked lighting of static meshes to a texture that you sample when applying the decals.

    I'm honestly not even sure if the HDRP handles this correctly for baked lighting. Most engines that use a lot of decals either live with the ambient lighting not quite matching, don't use any baked lightmaps, or use some form of volumetric based baked lighting rather than traditional light maps.
     
    adamgryu likes this.
  3. adamgryu

    adamgryu

    Joined:
    Mar 1, 2014
    Posts:
    188
    Ah, thanks for the input. I was planning on not using baked lightmaps, so that probably wouldn't be an issue.

    So I'd imagine I'd just have to call that function and pass it into the material through a property block?
    I could also probably live with the ambient lighting not being right if I need to.

    When I was researching this last night, I got the impression that it would be difficult to also stop the decals from overlapping on dynamic objects (such as my character) - is that also true?

    I started to lean towards baked mesh decals, although they don't have that nice property of absorbing the underlying materials normals and etc.
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    The documentation page I linked to has a good example of exactly how to use it. Alternatively, if you're not using any placed light probes in your scene you can access the default scene probe via
    RenderSettings.ambientProbe
    and use that instead of calculating the interpolated probe, which in a scene without light probes will always just be the above (unless you have non-important directional lights in the scene, which are baked into the SH at runtime).
    https://docs.unity3d.com/ScriptReference/RenderSettings-ambientProbe.html

    Yes. You'll want to keep the decals as close to the surface as possible. Or you'll need to render out a custom mask of some kind. Stencils would be great for this, but Unity makes using stencils in the deferred pipeline nearly impossible.

    Mesh decals get around this by being effectively pre-projected onto the surface, and there's not actually any reason they can't have the same ability to "conform" to the underlying surface gbuffers.