Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Feature Request Override default behaviour of decal opacity.

Discussion in 'Shader Graph' started by Qriva, Mar 3, 2024.

  1. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,352
    Is there any way to override how the opacity of decal projector is used in URP?
    I would like to use this value to fade decal but in custom way - for example using erosion or animate something additional. I don't understand why yet another feature is set in stone.

    upload_2024-3-3_22-24-53.png
     
  2. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,352
    It is even worse. I could consider opacity as "by design" way to control the opacity by artist, but it looks like there is literally no workaround to what I want to do. Decal projector has no renderer, so I can't even use material property blocks to pass my custom data. I am not even the first person with the same problem.
     
  3. Remy_Unity

    Remy_Unity

    Unity Technologies

    Joined:
    Oct 3, 2017
    Posts:
    709
    To control the material on the decal, you need to create and assign an instance of the original material, and modify its properties, instead of using material property blocks.

    As for the opacity, it is a global opacity applied when the decal writes into the decal buffer, you can not modify how it works, but you can leave it to 1 and control the opacity through the material shader alpha output.
     
    FredMoreau likes this.
  4. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,352
    No, we are supposed to use material property blocks, because decals are instanced.
    This is what documentation says:
    That means that if I want to reduce draw calls of my decal projectors I must assign the same material instance in all of them and enable GPU instancing in this material.
    However, if I create new instance then by definition there will be no instancing and SRP batcher also can't help here, so the only way is to add property block. The problem is that decal projector has no renderer, so we can't do that...
    To summarize, yes obviously I could create new material instance for each projector, but in such a case I get a draw call for every single decal in my game.
     
  5. Remy_Unity

    Remy_Unity

    Unity Technologies

    Joined:
    Oct 3, 2017
    Posts:
    709
    Sorry for the confusion, I was sure that URP handled decals similarly to HDRP, but it's not the case.

    After digging into the code, I better understand the issue. Indeed URP decals use property blocks, but "internally" to pass the decal component settings to the material: https://github.com/Unity-Technologi...ime/Decal/Entities/DecalEntityManager.cs#L293

    So, in order to add yourself settings to the property block, you'd have to "hook" into all that process :/

    Sorry, I don't see any other easy solution for you.
     
  6. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,352
    Sorry to vent my frustration, but URP came out without decals, and this feature was not available like for 2 years, then finally decal projector has been added, but it turned out it's partly useles as there is no support for light layers, so if you added some decal on the ground it was displayed on characters for example, so we had to wait another year.

    At this point I guess there is no improvement planned for 2023 right? If yes, then I dobut they will add any support in this version, so in the best case even if they consider this feature we have to wait yet another year (not counting this one).

    We can even use custom shader graph to create decal shaders, but we can't use any shader properties in normal way. For example I would like to add some "seed" property, to make decals more random per instance, but I can't even do that.
    The only other "hack" I can see is to use vfx graph to spawn every single decal, however vfx graph does not support light layers, at least in 2022.

    Does doing that requires to modify URP? can it be done in relatively easy, non too hacky way?
     
  7. Remy_Unity

    Remy_Unity

    Unity Technologies

    Joined:
    Oct 3, 2017
    Posts:
    709
    While some classes and fields are public or internal (can be accessed using asmrefs), others are private ... this DrawInstanced method that seems to be the one setting the property block for each decals for example.
    So this would probably need to modify URP to inject your custom values to the property block here.


    You could generate the seed based on the decal instance informations ? Like the position for example.
     
  8. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,352
    Yes, but it's not perfect, for example it will not work if I move decal.

    Well, that is sad. In any case this is my feature request - make it possible to set decal properties without breaking instancing.