Search Unity

Discussion A better way to handle projectors, or an alternative to them?

Discussion in 'General Graphics' started by zacharyhunterlund, Jul 29, 2022.

  1. zacharyhunterlund

    zacharyhunterlund

    Joined:
    Mar 7, 2021
    Posts:
    54
    Hello,

    I am aware of the usage of Projectors in Unity, which are often used for things such as blob shadows or decals.

    However, there is a major problem with the way decals work. After rendering the mesh that is being projected onto once, Unity then renders the mesh again with the projectors affecting it, essentially doubling the amount of triangles it has to tender.

    Obviously, this could greatly impact game performance, especially if all terrain is batched into a single large mesh. I am wondering if there could be a way to make projectors work without needing to draw the entire mesh again? Here are two proposals I have:

    - Rather than re-drawing the entire mesh, just re-draw the triangles that the projector is projecting onto.

    - Better yet, just draw the projection as it would look on the mesh.

    Do you think either of these could work? Or perhaps something that could work even better?
     
  2. c0d3_m0nk3y

    c0d3_m0nk3y

    Joined:
    Oct 21, 2021
    Posts:
    675
    With deferred rendering, you can simply render a box with a shader that blends the decal with the g-buffer.

    If you don't want to write it yourself, you could buy this
    https://assetstore.unity.com/packag...fects/decalicious-deferred-decal-system-74175

    With forward rendering it's much harder. AFAIK, rendering the mesh multiple times is like Half Life did it back in the days. Alternatively, you could store the decals in clusters along with the lights and then iterate over them in the pixel shader:
    http://www.aortiz.me/2018/12/21/CG.html#tiled-shading--forward
    https://wickedengine.net/2017/10/12/forward-decal-rendering/

    If anybody knows a better approach for forward rendering, I'd like to know too.
     
    Last edited: Jul 29, 2022
  3. c0d3_m0nk3y

    c0d3_m0nk3y

    Joined:
    Oct 21, 2021
    Posts:
    675
  4. joshuacwilde

    joshuacwilde

    Joined:
    Feb 4, 2018
    Posts:
    731
    If the decal doesn't need to interact with gbuffer type stuff (normals, albedo, etc) then you can use the deferred approach (you can easily get access to the depth buffer during transparent rendering, so you can project the decal against the depth buffer, as is done in deferred rendering).
     
  5. c0d3_m0nk3y

    c0d3_m0nk3y

    Joined:
    Oct 21, 2021
    Posts:
    675
    But it would basically mean that decals are applied after lighting, wouldn't it?

    Let's imagine you're applying a white decal onto a surface that's in an area with very little light. Wouldn't the decal be way too bright then?
     
    zacharyhunterlund likes this.
  6. c0d3_m0nk3y

    c0d3_m0nk3y

    Joined:
    Oct 21, 2021
    Posts:
    675
    Just noticed that I haven't properly answered your question. So it is possible to do this, but it means that all meshes must be cpu-readable. Unless you do it in a compute shader, maybe.
    https://www.gamedeveloper.com/programming/how-to-project-decals

    However, it might be a good approach if you can do it offline (if both the mesh and decal is static)
     
    Last edited: Jul 29, 2022
    zacharyhunterlund likes this.