Search Unity

Question Fill mesh gaps with certain color

Discussion in 'Shaders' started by hainkiwanki, Oct 9, 2020.

  1. hainkiwanki

    hainkiwanki

    Joined:
    Oct 23, 2017
    Posts:
    20
    Hello,

    I have a simple mesh of 2 planes next to eachother but not connected or touching eachother. I want to fill the gaps between the vertices with a simple single color. I am not sure where to begin on this one. Or what terminology I could use to google some more information. If anyone could point me in the right direction that'd be great.

    Im using URP and Unity 2019.4.11f1.

    Here are some pictures of what I mean:
    https://imgur.com/a/oSSWkLL


     
  2. domjon

    domjon

    Joined:
    Oct 14, 2012
    Posts:
    12
    The easiest way really would be to add separate geometry to the top that lines up, and set it to an unlit single color shader. I did this for a game of mine recently.

    Although, an ice cream sandwich shader like that does sound really interesting!
     

    Attached Files:

  3. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,550
    If you can't modify the geometry like domjon mentions, or you want it filled incase the camera clips with the surface, then it's mainly just a shader that has
    Cull off
    set in it so that backfaces are rendered, and you can use the
    VFACE
    semantic in the shader to know if the triangle is facing towards you or not, and if not you simply output your solid color.
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,350
    If you want to fill the gap like the example you have above and in the link, the only option is to actually fill that space with geometry. Likely manually. The GPU does not have enough information to fill in that space via a shader, as even if it's the same mesh, shaders only know at most about a single triangle at a time.

    Removing culling & using
    VFACE
    or
    SV_IsFrontFace
    to detect the back face to color it black will only make backs of existing geometry be drawn black. The gaps in the geometry will remain and are unsolvable without actually having more geometry in the mesh.
     
  5. hainkiwanki

    hainkiwanki

    Joined:
    Oct 23, 2017
    Posts:
    20
    Yea, I can't change the geometry in the mesh sadly. So ice cream sandwich shader is the option! Haha


    VFACE sounds very useful here in this situation, I will have a look into it. Thank you.


    I think having the color set to 0,0,0 or black will suffice I hope. I will test it with VFACE and/or SV_IsFrontFront. Thank you for the pointers :D
     
  6. hainkiwanki

    hainkiwanki

    Joined:
    Oct 23, 2017
    Posts:
    20
    Update:

    So I tried it with 2 options for now.

    First option uses 2 shaders which both make use of the stencil buffer. I added a simple plane between the gap of the mesh inside Unity as followed:

    The shader for this one has ZWrite Off and uses the following stencil
    Code (CSharp):
    1.        
    2. Stencil {
    3.             Ref 1
    4.             Comp Always
    5.             Pass Replace
    6.         }
    7.  
    Up next I added a bigger plane to the whole house area like this:

    This one is even simpler than the previous one, simply added the following stencil to a new shader:
    Code (CSharp):
    1.  
    2.        Stencil{
    3.             Ref[_MaskValue]
    4.             Comp Equal
    5.         }
    6.  
    And then you can see the nice result shown in the picture above.

    Second option uses the backface culling mentioned in above comments.
    The full shader for this one is the following:

    Code (CSharp):
    1. Shader "Custom/Vface"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex("Texture", 2D) = "white" {}
    6.         _BumpMap("Bumpmap", 2D) = "bump" {}
    7.     }
    8.  
    9.     SubShader
    10.     {
    11.         Cull Off
    12.         CGPROGRAM
    13.         #pragma target 5.0
    14.         #pragma surface surf Lambert addshadow
    15.  
    16.         struct Input {
    17.             float IsFacing : VFACE;
    18.             float2 uv_MainTex;
    19.             float2 uv_BumpMap;
    20.         };
    21.  
    22.         sampler2D _MainTex;
    23.         sampler2D _BumpMap;
    24.  
    25.         void surf(Input i , inout SurfaceOutput o)
    26.         {
    27.             float4 textColor = tex2D(_MainTex, i.uv_MainTex).rgba;
    28.             float4 color = (i.IsFacing > 0) ? textColor : float4(0,0,0,1);
    29.             o.Albedo = color.rgb;
    30.             //o.Emission = color.rgb;
    31.             o.Normal = UnpackNormal(tex2D(_BumpMap, i.uv_BumpMap));
    32.         }
    33.  
    34.         ENDCG
    35.     }
    36. }
    This gives the following result when seen from an angle (on the right of the pic, dont mind the color differences):

    Looking very good, the only problem here are my meshes in this case. The meshes don't have a polygon on the bottom and thus when the house is looked at from above, you can see the missing polygons if the background color is not the same as the color used for the backfaces.


    In the picture above the camera clear flag is set to skybox, hence we get this ugly grey-brown-ish color. However, if I set the camera clear flag to solid color and pitch black (like the backfaces), it solves this issue.


    Also here there are a few issues with the right one (backface one), like you can still see the door through the gap which you can't in the other method.

    Anyways, I think all this can be avoided by simply adding more polygons to the meshes. But I thought it would be interesting to try something like this.

    Thank you all for your help :)
     
    Invertex likes this.