Search Unity

Question How to overlap two textures.

Discussion in 'Shader Graph' started by pineapuru, Jul 18, 2021.

  1. pineapuru

    pineapuru

    Joined:
    Mar 21, 2018
    Posts:
    46
    Hey everyone. I've been trying to have two textures one on top of each other, just like layers on photoshop, I have tried many ways but can't get it to work, it is a transparent shader and I wish I could control the opacity of these images, but I can't get it to work correctly.

    Can someone give me any suggestions? I've tried the Blend node with Overwrite but if I fade a texture out, its colors are still on the lower texture even though the texture isn't there. I've tried the add node but the color also adds and it becomes one, multiply node, the same. :(
     
  2. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,314
    You can try Lerp - it is linear interpolation between two inputs.
     
  3. pineapuru

    pineapuru

    Joined:
    Mar 21, 2018
    Posts:
    46
    Using lerp made it look very weird, I'm not sure I'm doing anything correctly at all, at this point lol. Wouldn't Lerp make it fade into one to another?
     
  4. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,314
    I understood you blend two color textures, yes lerp "fade" between them, but what exactly do you need?
    If you need to combine black and white textures to create mask then you could just add them and saturate the result.
    In case of normal color textures you should just "lerp" between layers by using alpha like this:
    Code (CSharp):
    1. lerp(layer1, layer2, layer2Alpha)
     
  5. pineapuru

    pineapuru

    Joined:
    Mar 21, 2018
    Posts:
    46
    Sorry if my description was confusing.

    As I mentioned, I'm trying to make the textures be on top of each other, just like layers on photoshop, where I can manage their tiling, offset, color and alpha individually.

    I made this quick image to exemplify.
     
  6. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,314
    Ok I understand. I am definitely not shader expert, but this is what I would do:

    The most simple version, just two images on top of each other would be something like this
    simple_lerp.png
    but I guess this would not produce correct results in all cases, especially if you add additional opacity control.
    I guess this should be good enough:
    blend.png

    By the way all 4 channels are lerped in this image, but actually you need to lerp only RGB.

    // edit: This might be enough for your case as result is very similar, but it still does not work exactly like in photoshop, the thing is I don't know how to blend alpha exactly like photostop does. If you make 3 overlaping layers in PS with 50% opacity, overlaping pixels will be lighter and lighter (or darker - depends what is your texture), but currently in my graph it will be just highest alpha of these textures.
     
    Last edited: Jul 19, 2021
  7. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,314
    Actually I was curious how to do it correctly and what you need is just to construct standard transparency blend mode:
    Code (CSharp):
    1. Blend SrcAlpha OneMinusSrcAlpha
    I think this should be correct now:
    blends.png

    Sorry for confusion in previous posts.
     
  8. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,348
    I just wanted to note, this isn’t correct either. A Lerp node produces exactly the same math as the “standard transparency” example. If you’d used a split node on the previous Lerp based example to get the alpha channel you would have gotten the same result as your latest one. And if you look at the alpha on the latest version you’ll see there’s a dark edge between the ball and book where they overlap, and that should not be there.

    For overlapping some textures within a shader, Lerp is what you want, as the resulting alpha doesn’t actually matter anymore. If you need to use the color and alpha as an output for a transparent material, you want to do something slightly different. At least for the alpha.

    You can use the above graph, or the original Lerp based example, to get the Base Color value. But for the alpha you want to do:
    baseAlpha * (1-blendAlpha) + blendAlpha


    Then there’s one more step. You’ll want to set the Master Stack’s Blending to Premultiply in the Graph Settings window.
     
  9. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,314
    Crap, you are right. For some reason lerp didn't work before as expected, so I thought it is a bit different somehow, but now I remember what I did wrong - I skipped the part with lerping from black color and this produced wrong results.

    So I guess SrcAlpha OneMinusSrcAlpha can be used only on plain RGB, but to to keep alpha correct it can't be multiplied twice, what actually makes sense as value should "stack" to 1.
     
  10. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,348
    Here's my Graph using some sub graphs to clean up stuff:
    upload_2021-7-21_11-18-15.png

    PremultiplyColorByAlpha sub graph:
    upload_2021-7-21_11-18-34.png

    PremultipliedAlphaBlend sub graph:
    upload_2021-7-21_11-19-42.png


    If you for some reason need this for a material that's using Blend -> Alpha, then you can use a hack to get the RGB color values back to what that blend node needs. Divide the color by the alpha before outputting it. Note you'll want to clamp the alpha to some very small value above zero before dividing to prevent a divide by zero.
    upload_2021-7-21_11-25-1.png


    upload_2021-7-21_11-27-33.png
     
    henners999 likes this.
  11. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,348
    Something didn't quite feel right with the above example images, and then I was reminded by @Torbach78 's post that the Blend -> Premultiply option is broken and exactly the same as Blend -> Alpha. Hopefully someday this will be the "right" way to do it, but for now use the alpha blending divide by alpha "fix" and Blend -> Alpha.

    Note that neither will 100% match Photoshop if your project is using Color Space -> Linear because then it'll be doing the alpha blending in linear space (both in the shader and in the final rendering of the object to the screen). If you need an exact match to Photoshop, change the color space of your project to Gamma in the Project Settings.
     
    Sinister-Design likes this.
  12. Torbach78

    Torbach78

    Joined:
    Aug 10, 2013
    Posts:
    296
    since the Source texture get's multiplied by it's own Alpha you have to have a very bright RGB to retain colors on feathering objects as well.. otherwise Source * SourceAlpha creates black halos on VFX that feather.

    A blue laser sprite would need pure blue filling the texture field where the transparency is approaching 100% otherwise photoshop is going to turn those feathering edges 'whiter' as it compresses small color values onto a 'white' background.

    And you need to make sure you don't use photoshops native PNG* file format which does undesirable run-line compression changes to RGB based on Transparency (note the streaks of black/white on your sprites as well as the bounding boxes of black and white)
    (*or use TGA file format)
    premult_photoshop.png

    for blending you recreate the blend mode concept in the shaderGraph either premult or alpha concept

    book_Color + basketball_Color * Inv_Book_Alpha = output
    that is exactly how a premult would work if the book is on black background

    book_Color * book_alpha + basketball_Color * Inv_Book_Alpha = output
    that is how an alpha blend would work if the book RGB is made in photoshop using transparency

    your math is correct here


    the issue is the halo of black on the book is often caused by erroneous PNG data from photoshop compression.
    Because `Source * SrcAlpha` the RGB source gets double dark edging.

    trying to blend alpha causes dark outlines unless texture and the alpha are adjusted knowing that there will be the multiplication process [Source * SrcAlpha]

    It is another reason I use Premultiplication exclusively: And yes the ongoing bug mentioned is frustrating.
     
    Last edited: Jul 23, 2021
    ASMRPL2022ZBI likes this.
  13. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,314
    I always use VFX graph and premultiply works correct there (I think), so I never noticed that this is broken in standard master stack. It's sick they didn't fix such a bug for a whole year.
     
    Sinister-Design likes this.
  14. Torbach78

    Torbach78

    Joined:
    Aug 10, 2013
    Posts:
    296
    i think this is a URP issue, the unlit.txt code error i found is because I use the Unlit Master node in URP not HDR nor PBR.

    I have not been diligent to see if it works in the other pipelines.. it probably does which is why the bug is a bit overlooked for URP