Search Unity

Glow around point in ScreenSpace

Discussion in 'Shaders' started by VLukianenko, Feb 19, 2018.

  1. VLukianenko

    VLukianenko

    Joined:
    Mar 27, 2017
    Posts:
    30
    Hello, everyone!

    I'm trying to write a shader for UI elements that would highlight them around given point (global shader variable) - the closer the pixel is to the screen point, the more _GlowColor is added to it.

    However, I can't get it working. This is my shader code:

    Code (CSharp):
    1.  
    2. Shader "Custom/UI/UI - Glow around point"
    3. {
    4.     Properties
    5.     {
    6.         [PerRendererData]_MainTex("Static texture (can be empty)", 2D) = "white" {}
    7.         _Color("Main color", Color) = (0,0,0,0)
    8.         _GlowColor("Glow color", Color) = (0,0,0,0)
    9.         _GlowDistance("Glow distance", float) = 5
    10.  
    11.         [Space(30)]
    12.  
    13.         _StencilComp("Stencil Comparison", Float) = 8
    14.         _Stencil("Stencil ID", Float) = 0
    15.         _StencilOp("Stencil Operation", Float) = 0
    16.         _StencilWriteMask("Stencil Write Mask", Float) = 255
    17.         _StencilReadMask("Stencil Read Mask", Float) = 255
    18.         _ColorMask("Color Mask", Float) = 15
    19.     }
    20.  
    21.         SubShader
    22.     {
    23.             Tags
    24.         {
    25.             "Queue" = "Transparent"
    26.             "IgnoreProjector" = "True"
    27.             "RenderType" = "Transparent"
    28.             "PreviewType" = "Plane"
    29.         }
    30.  
    31.             Stencil
    32.         {
    33.             Ref[_Stencil]
    34.             Comp[_StencilComp]
    35.             Pass[_StencilOp]
    36.             ReadMask[_StencilReadMask]
    37.             WriteMask[_StencilWriteMask]
    38.         }
    39.  
    40.             ColorMask[_ColorMask]
    41.             Cull Off
    42.             ZWrite Off
    43.             ZTest[unity_GUIZTestMode]
    44.             Blend SrcAlpha One
    45.  
    46.             Pass
    47.         {
    48.             CGPROGRAM
    49.             #pragma vertex vert
    50.             #pragma fragment frag
    51.  
    52.             #include "UnityCG.cginc"
    53.  
    54.             uniform sampler2D _MainTex;
    55.          
    56.             uniform Vector _PointPosition;
    57.  
    58.             uniform float4 _MainTex_ST;
    59.             uniform float4 _Color;
    60.             uniform float4 _GlowColor;
    61.  
    62.             uniform float _GlowDistance;
    63.  
    64.             uniform float _GlowIntensity;
    65.  
    66.             struct appdata
    67.             {
    68.                 float4 vertex : POSITION;
    69.                 float2 texcoord : TEXCOORD0;
    70.                 float4 color : COLOR;
    71.             };
    72.  
    73.             struct v2f
    74.             {
    75.                 float2 uv : TEXCOORD0;
    76.                 float4 vertex : SV_POSITION;
    77.                 float4 color : COLOR;
    78.             };
    79.  
    80.             v2f vert(appdata v)
    81.             {
    82.                 v2f o;
    83.                 o.vertex = UnityObjectToClipPos(v.vertex);
    84.                 o.color = v.color;
    85.                 o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
    86.  
    87.                 return o;
    88.             }
    89.  
    90.             fixed4 frag(v2f i) : SV_Target
    91.             {
    92.  
    93.                 fixed4 color = _Color * tex2D(_MainTex, i.uv*_MainTex_ST)*i.color;
    94.  
    95.                 float dist = distance(_PointPosition, i.vertex) / _GlowDistance;
    96.  
    97.                 color.rgb += (_GlowColor*_GlowIntensity) / dist;
    98.  
    99.                 return color;
    100.             }
    101.             ENDCG
    102.         }
    103.     }
    104.         Fallback "Mobile/VertexLit"
    105. }
    106.  


    And in a test script that is attached to a point I do this, to get the coordinates of the point game object:

    Code (CSharp):
    1.  
    2.     void Update () {
    3.         Vector4 screenPos = Camera.main.WorldToScreenPoint((gameObject.transform.position));
    4.         Shader.SetGlobalVector("_PointPosition", screenPos);
    5.         Shader.SetGlobalFloat("_GlowIntensity", (Mathf.Sin((Mathf.PI*Time.time))+1)*0.5f);
    6.  
    7.         Debug.Log("target is " + screenPos.x + " pixels from the left");
    8.         Debug.Log("target is " + screenPos.y + " pixels from the bottom");
    9.     }
    10.    
    Everything seems to work, but for some reason the y coordinate of screen gets mirrored around the screen center... I can't figure out why for few hours already, so I'm asking for help: what am I missing? Here's a video of what's happening: http://take.ms/ECHpw
     
    Last edited: Feb 21, 2018
  2. customphase

    customphase

    Joined:
    Aug 19, 2012
    Posts:
    246
    https://docs.unity3d.com/Manual/SL-PlatformDifferences.html
     
    VLukianenko likes this.
  3. VLukianenko

    VLukianenko

    Joined:
    Mar 27, 2017
    Posts:
    30
    This looks totally like the case, but for some reason, flipping y-uv-coordinate doesn't change anything as well as y-vertex coordinate. What fixed my issue was flipping points Y coordinate:

    Code (CSharp):
    1.  var pos = gameObject.transform.position;
    2.         pos.y *= -1;
    3.         Vector4 screenPos = Camera.main. WorldToScreenPoint((pos));
    4.         Shader.SetGlobalVector("_PointPosition", screenPos);
    Is it a platform-specific dependency? Doesn't look like that...
    And it wasn't working if I flipped that coordinate inside shader...
     
    Last edited: Feb 22, 2018