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:
ShaderCode
Shader "Custom/UI/UI - Glow around point"
{
Properties
{
[PerRendererData]_MainTex("Static texture (can be empty)", 2D) = "white" {}
_Color("Main color", Color) = (0,0,0,0)
_GlowColor("Glow color", Color) = (0,0,0,0)
_GlowDistance("Glow distance", float) = 5
[Space(30)]
_StencilComp("Stencil Comparison", Float) = 8
_Stencil("Stencil ID", Float) = 0
_StencilOp("Stencil Operation", Float) = 0
_StencilWriteMask("Stencil Write Mask", Float) = 255
_StencilReadMask("Stencil Read Mask", Float) = 255
_ColorMask("Color Mask", Float) = 15
}
SubShader
{
Tags
{
"Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "Transparent"
"PreviewType" = "Plane"
}
Stencil
{
Ref[_Stencil]
Comp[_StencilComp]
Pass[_StencilOp]
ReadMask[_StencilReadMask]
WriteMask[_StencilWriteMask]
}
ColorMask[_ColorMask]
Cull Off
ZWrite Off
ZTest[unity_GUIZTestMode]
Blend SrcAlpha One
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform Vector _PointPosition;
uniform float4 _MainTex_ST;
uniform float4 _Color;
uniform float4 _GlowColor;
uniform float _GlowDistance;
uniform float _GlowIntensity;
struct appdata
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
float4 color : COLOR;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
float4 color : COLOR;
};
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.color = v.color;
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
fixed4 color = _Color * tex2D(_MainTex, i.uv*_MainTex_ST)*i.color;
float dist = distance(_PointPosition, i.vertex) / _GlowDistance;
color.rgb += (_GlowColor*_GlowIntensity) / dist;
return color;
}
ENDCG
}
}
Fallback "Mobile/VertexLit"
}
And in a test script that is attached to a point I do this, to get the coordinates of the point game object:
void Update () {
Vector4 screenPos = Camera.main.WorldToScreenPoint((gameObject.transform.position));
Shader.SetGlobalVector("_PointPosition", screenPos);
Shader.SetGlobalFloat("_GlowIntensity", (Mathf.Sin((Mathf.PI*Time.time))+1)*0.5f);
Debug.Log("target is " + screenPos.x + " pixels from the left");
Debug.Log("target is " + screenPos.y + " pixels from the bottom");
}
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: Monosnap