Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Cutting holes through UI images in Unity using stencil buffers and shaders

Discussion in 'Shaders' started by sanyasn, Nov 12, 2020.

  1. sanyasn

    sanyasn

    Joined:
    Jun 22, 2020
    Posts:
    1
    I am quite new to shaders in unity and have a very basic understanding.
    I have a foreground image on the UI Layer that covers the whole scene. How can I cut through this foreground image and show a small part of the 3D worldspace behind? I need to make multiple holes dynamically and not just a simple static hole.

    I have read that I need two shaders, one for a mask (x-ray) and one for the mask target. I thought it would be a good idea to take a lightweight shader for a base, so I took an Unlit Transparent shader.

    Code (CSharp):
    1.  
    2. Shader "Custom/HoleShader"
    3. {
    4.     Properties
    5.     {
    6.         _MainTex ("Base (RGB), Alpha (A)", 2D) = "white" {}
    7.         _Color ("Tint", Color) = (1,1,1,1)
    8.  
    9.         _StencilComp ("Stencil Comparison", Float) = 8
    10.         _Stencil ("Stencil ID", Float) = 0
    11.         _StencilOp ("Stencil Operation", Float) = 0
    12.         _StencilWriteMask ("Stencil Write Mask", Float) = 255
    13.         _StencilReadMask ("Stencil Read Mask", Float) = 255
    14.  
    15.         _ColorMask ("Color Mask", Float) = 15
    16.  
    17.         [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
    18.     }
    19.     SubShader
    20.     {
    21.         Tags { "Queue"="Geometry-1" }
    22.  
    23.         ColorMask 0
    24.         ZWrite Off
    25.  
    26.         Stencil {
    27.              Ref 1
    28.              Comp always
    29.              Pass replace
    30.         }
    31.     }
    32.     FallBack "UI/Default"
    33. }
    Then I created another shader for the mask target (in my case for the UI image on the UI Layer and for 3D elements in the worldspace space that are not supposed to be seen through the hole/window).


    Code (CSharp):
    1.  
    2. Shader "Custom/HoleTargetShader"
    3. {
    4.     Properties
    5.     {
    6.         _MainTex ("Base (RGB), Alpha (A)", 2D) = "white" {}
    7.         _Color ("Tint", Color) = (1,1,1,1)
    8.  
    9.         _StencilComp ("Stencil Comparison", Float) = 8
    10.         _Stencil ("Stencil ID", Float) = 0
    11.         _StencilOp ("Stencil Operation", Float) = 0
    12.         _StencilWriteMask ("Stencil Write Mask", Float) = 255
    13.         _StencilReadMask ("Stencil Read Mask", Float) = 255
    14.  
    15.         _ColorMask ("Color Mask", Float) = 15
    16.  
    17.         [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
    18.     }
    19.     SubShader
    20.     {
    21.         Tags { "Queue"="Geometry" }
    22.  
    23.         Stencil {
    24.              Ref 1
    25.              Comp notequal
    26.              Pass keep
    27.         }
    28.     }
    29.     FallBack "UI/Default"
    30. }
    Would be very thankful for any help!
     
    Last edited: Nov 14, 2020
  2. unityuserunity85496

    unityuserunity85496

    Joined:
    Jan 9, 2019
    Posts:
    89