Unity3d Ugui图片上制作点光 、棱形光效果shader,并具有裁切
Unity3d Ugui圖片上制作點光 、棱形光效果
實現的效果可以參考如下圖所示
通過shader來實現上述的效果,為了大家的適應性,推薦在unity官方的默認ui shader上更改,我用的是2019.2.17版本。以下是鏈接
unity官方下載
查找對應版本選擇built in shaders 下載
可以在路徑builtin_shaders-2019.2.21f1\DefaultResourcesExtra\UI 下找到UI-Default.shader
在以此的基礎上修改代碼
類似點光的實現
點光本質來說形狀就是一個圓,首先在Properties中需要定義圓心,和其半徑
_CircleParameter("Circle Parameter",Vector)=(0.5,0.5,0.2,1) //xy 為圓心所在位置, z為半徑 ,w為光線強度接下來我們需要得到uv坐標下,每個點距離我們定義的圓的距離
float2 centrePoint=_CircleParameter.xy; //圓心 float dis=distance(IN.uv,centrePoint); //uv與圓心的距離很明顯,我們只需要 距離dis在圓半徑_CircleParameter.z范圍內的點,可以通過如下代碼獲得
float factor= step(dis,_CircleParameter.z);factor 的值為 圓半徑小于兩點距離(_CircleParameter.z<dis)則為0,否則為1。step函數可以搜索CG 標準函數庫查看相關概念。
接下里我們可以通過得到的factor為點光顏色去做裁剪,去掉圓以外的光顏色。很明顯在圓以外的factor值都為0,只要將光顏色(_PointColor)的alpha值乘以factor。
_PointColor.a*=factor; //裁剪掉超出圓范圍的光有些圖片上有透明元素,比如我在上面中使用的圖片,顯然這些透明的地方不應該顯示光顏色,當然如果你想的話也可以。通過采樣獲取(color)的顏色 判斷當前像素上是否透明,不需要顯示。
_PointColor.a*=step(0.01,color.a); //裁剪掉透明處的光光是有衰減的,我們可以通過如下一個簡單的計算得到。
_PointColor.a*=1.0-(dis/_CircleParameter.z); //光的衰減點距離圓心越近dis/_CircleParameter.z越小,但是很明顯衰減是從圓心往外的,可以用去1去減使其相反。
最后只需要混合光的顏色和采樣得到的顏色
color.rgb= color.rgb+_PointColor.rgb*_PointColor.a*_CircleParameter.w; //混合顏色 ,_CircleParameter.w為顏色強度有時候我們會希望圖片做一些裁剪,比如讓它只顯示圓的形狀。那么我們只需要以上代碼的基礎上,通過采樣顏色的alpha乘以factor就可以去掉范圍以外的顏色。代碼十分簡單
color.a*=factor;棱形光
基本思想與上面的圓類似,簡單的來說,就是我們需要判斷哪些點在這個棱形范圍內。
上圖中使用的是四邊相等的棱形,并且頂點距離坐標中心為1,很明顯此棱形在四邊上的點有如下關系式 x+y=1(x和y分布都是x上距離坐標中心的距離,和y上距離坐標中心的距離)。那么在此棱形中的點顯然 小于 x+y。只需要將uv坐標轉換為上圖以棱形為坐標系,可以很容易計算點是否在棱形內。代碼如下
最后把所有完整shader附上
Shader "Wjh/2DPoint" {Properties{[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}_Color ("Tint", Color) = (1,1,1,1)_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[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0_PointColor("Point Color",Color)=(1,1,0,1) //點光的顏色_CircleParameter("Circle Parameter",Vector)=(0.5,0.5,0.2,1) //xy 為圓心所在位置, z為半徑 ,w為光線強度[Toggle(USE_CLIP_SHAPE)] _UseClipShape("Use Clip Shape",Float)=0.0 //是否開啟裁剪-圓[Toggle(USE_DIAMOND)] _UseDiamond("Use Clip Shape",Float)=0.0 //是否開啟裁剪-圓}SubShader{Tags{"Queue"="Transparent""IgnoreProjector"="True""RenderType"="Transparent""PreviewType"="Plane""CanUseSpriteAtlas"="True"}Stencil{Ref [_Stencil]Comp [_StencilComp]Pass [_StencilOp]ReadMask [_StencilReadMask]WriteMask [_StencilWriteMask]}Cull OffLighting OffZWrite OffZTest [unity_GUIZTestMode] Blend SrcAlpha OneMinusSrcAlphaColorMask [_ColorMask]Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#pragma target 2.0#include "UnityCG.cginc"#include "UnityUI.cginc"#pragma multi_compile_local _ UNITY_UI_CLIP_RECT#pragma multi_compile_local _ UNITY_UI_ALPHACLIP//自定義裁剪宏#pragma shader_feature_local USE_CLIP_SHAPE //自定義棱形宏#pragma shader_feature_local USE_DIAMOND struct appdata_t{float4 vertex : POSITION;float4 color : COLOR;float2 texcoord : TEXCOORD0;UNITY_VERTEX_INPUT_INSTANCE_ID};struct v2f{float4 vertex : SV_POSITION;fixed4 color : COLOR;float2 uv : TEXCOORD0;float4 objPosition : TEXCOORD1;UNITY_VERTEX_OUTPUT_STEREO };sampler2D _MainTex;fixed4 _Color;fixed4 _TextureSampleAdd;float4 _ClipRect;float4 _MainTex_ST;fixed4 _PointColor;fixed4 _CircleParameter;float _UseClipCircle;float _UseClipDiamond;v2f vert(appdata_t v){v2f OUT;//Gpu Instancing 相關UNITY_SETUP_INSTANCE_ID(v);UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);OUT.objPosition = v.vertex;OUT.vertex = UnityObjectToClipPos(OUT.objPosition);OUT.uv = TRANSFORM_TEX(v.texcoord, _MainTex);OUT.color = v.color * _Color;return OUT;}float ClipDiamond(float2 uv)//裁剪棱形{float x=abs( uv.x-_CircleParameter.x);float y=abs( uv.y-_CircleParameter.y);return step(x+y,_CircleParameter.z);}fixed4 frag(v2f IN) : SV_Target{fixed4 color = (tex2D(_MainTex, IN.uv) + _TextureSampleAdd) * IN.color;//圖片裁剪#ifdef UNITY_UI_CLIP_RECTcolor.a *= UnityGet2DClipping(IN.objPosition.xy, _ClipRect);#endif#ifdef UNITY_UI_ALPHACLIPclip (color.a - 0.001);#endiffloat2 centrePoint=_CircleParameter.xy; //圓心float dis=distance(IN.uv,centrePoint); //uv與圓心的距離//是否開啟裁剪棱形,否則圓#ifdef USE_DIAMOND float factor=ClipDiamond(IN.uv);#elsefloat factor= step(dis,_CircleParameter.z); //超出圓范圍的因子為0,其余為1#endif_PointColor.a*=step(0.01,color.a); //裁剪掉透明處的光_PointColor.a*=factor; //裁剪掉超出圓范圍的光//是否開啟裁剪形狀#ifdef USE_CLIP_SHAPEcolor.a*=factor; #endif_PointColor.a*=1.0-(dis/_CircleParameter.z); //光的衰減color.rgb= color.rgb+_PointColor.rgb*_PointColor.a*_CircleParameter.w; //混合顏色 ,_CircleParameter.w為顏色強度//color.rgb= (color.rgb*color.a+_PointColor.rgb*_PointColor.a*_CircleParameter.w)*step(0.001,_PointColor.a); //混合顏色 ,_CircleParameter.w為顏色強度return color;}ENDCG}} }謝謝。
總結
以上是生活随笔為你收集整理的Unity3d Ugui图片上制作点光 、棱形光效果shader,并具有裁切的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hive优化笔记
- 下一篇: xp 无法关闭计算机,xp系统不能关机解