Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Non-overlapping transparency for several objects

Discussion in 'Editor & General Support' started by BrightBit, Sep 29, 2014.

  1. BrightBit

    BrightBit

    Joined:
    Jan 22, 2013
    Posts:
    243
    I would like to recreate a certain effect where multiple transparent objects won't create lesser transparent areas where they are overlapping each other. The following image illustrates what I would like to avoid:



    Minecraft is a great example to show you what I would like to achieve:



    The fountain has no overlapping water and it's not possible to artificially create those artifacts from the image above in Minecraft. A friend of mine told me that this effect might be possible by using the stencil buffer which in Unity is a Pro only feature. I'm curious if he's right with that. Minecraft (Vanilla) doesn't use shaders, so can you use the stencil buffer with the fixed function pipeline?
     
  2. BrightBit

    BrightBit

    Joined:
    Jan 22, 2013
    Posts:
    243
  3. BrightBit

    BrightBit

    Joined:
    Jan 22, 2013
    Posts:
    243
    I even wrote a Tweet to Notch himself, now. Yes, I am desperate. :(

    Is there a way to combine the results of two framebuffers? Like combining the results of two cameras? That way I could render everything except the water first and then render the water only (but non-transparent, i.e. opaque). After that I would combine both images where the water "framebuffer" will be treated as semi-transparent...
     
  4. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    It's actually covered in the docs. And Stencil buffer is no longer exclusively a pro feature.
    http://docs.unity3d.com/Manual/SL-CullAndDepth.html

    But if this doesn't solve it for you, you probably want to render to an intermediate buffer without transparency, then composite it into the scene with.

    Render textures.
     
  5. BrightBit

    BrightBit

    Joined:
    Jan 22, 2013
    Posts:
    243
    @hippocoder: Thank you very much! It helped a lot!

    I really didn't see this section in the manual before. Apart from that I also had to adjust the shader:

    Code (CSharp):
    1. Shader "Custom/Water"
    2. {
    3.     Properties
    4.     {
    5.         _Color ("Main Color", Color) = (1,1,1,1)
    6.         _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
    7.     }
    8.  
    9.     SubShader
    10.     {
    11.         Tags
    12.         {
    13.             // I HAD TO REMOVE THE LINE "Queue"="Transparent"
    14.             "IgnoreProjector" = "True"
    15.             "RenderType"      = "Opaque" // and change the rendertype to "Opaque"
    16.         }
    17.  
    18.         LOD 200
    19.  
    20.         // extra pass that renders to depth buffer only
    21.         Pass
    22.         {
    23.             ZWrite On
    24.             ColorMask 0
    25.         }
    26.  
    27.         UsePass "Transparent/Diffuse/FORWARD"
    28.     }
    29.     FallBack "Diffuse"
    30. }
    31.  
    Do you know why it only works with my changes? Anyway thanks in heaps for helping me!
     
  6. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Because transparent queue sorts differently otherwise polygons will clip each other so they have to be sorted back to front instead.

    But if this works fine for your situation then it will work fine on all devices - don't worry about it - if it's good, in this case, it's good! :)

    Generally that means you probably don't have transparent things behind transparent things that you still needed to see, ie meshes that are combined like X shaped grass billboards.
     
  7. HonoraryBob

    HonoraryBob

    Joined:
    May 26, 2011
    Posts:
    1,212
    I tried the "Transparent shader with depth writes" example code given on that page, but it doesn't work. I'm using 5.0.1.
     
  8. HonoraryBob

    HonoraryBob

    Joined:
    May 26, 2011
    Posts:
    1,212
    Isn't there some functional code that will do this, since it's a fairly common problem that needs to be solved?
     
  9. HonoraryBob

    HonoraryBob

    Joined:
    May 26, 2011
    Posts:
    1,212
    I got it to partially work using BrightBit's modified version that he posted farther above; but it only eliminates overlap for polys that are part of the same mesh. Multiple meshes will still have overlap. Is there any method to eliminate that?
     
  10. icefreedom

    icefreedom

    Joined:
    Jun 11, 2018
    Posts:
    9
    hi. i found solution for this problem. iam using URP
    upload_2023-6-27_17-1-26.png


    Shader "Custom/Water"
    {
    Properties
    {
    _Color("Main Color", Color) = (1,1,1,1)
    //_MainTex("Base (RGB) Trans (A)", 2D) = "white" {}
    }

    SubShader
    {
    Tags { "RenderType" = "Transparent" "Queue" = "Transparent" }
    LOD 200

    ZWrite Off
    Blend SrcAlpha OneMinusSrcAlpha



    Pass {
    Blend SrcAlpha OneMinusSrcAlpha
    Blend One OneMinusSrcAlpha
    ZWrite Off
    Cull Off
    Stencil {
    Ref 10
    ReadMask 10
    Comp NotEqual
    Pass Replace
    }
    CGPROGRAM
    #pragma vertex vert
    #pragma fragment frag
    #pragma target 3.5

    #include "UnityCG.cginc"

    struct appdata {
    float4 vertex : POSITION;
    float2 uv : TEXCOORD0;
    };

    struct v2f {
    float2 uv : TEXCOORD0;
    float4 vertex : SV_POSITION;
    };

    sampler2D _MainTex;
    float4 _Color;

    v2f vert(appdata v) {
    v2f o;
    o.vertex = UnityObjectToClipPos(v.vertex);
    o.uv = v.uv;
    return o;
    }

    fixed4 frag(v2f i) : SV_Target {
    fixed4 col = tex2D(_MainTex, i.uv) * _Color;
    col.a *= _Color.a;
    col.rgb *= col.a; // Preserve color intensity when transparent
    return col;
    }
    ENDCG

    //UsePass "Transparent/Diffuse/FORWARD"
    }
    //FallBack "Diffuse"
    }
    }
     
    plindsey likes this.