Unity3d Ugui图片上制作点光 、棱形光效果shader,并具有裁切
Unity3d Ugui圖片上制作點(diǎn)光 、棱形光效果
實(shí)現(xiàn)的效果可以參考如下圖所示
通過shader來實(shí)現(xiàn)上述的效果,為了大家的適應(yīng)性,推薦在unity官方的默認(rèn)ui shader上更改,我用的是2019.2.17版本。以下是鏈接
unity官方下載
查找對(duì)應(yīng)版本選擇built in shaders 下載
可以在路徑builtin_shaders-2019.2.21f1\DefaultResourcesExtra\UI 下找到UI-Default.shader
在以此的基礎(chǔ)上修改代碼
類似點(diǎn)光的實(shí)現(xiàn)
點(diǎn)光本質(zhì)來說形狀就是一個(gè)圓,首先在Properties中需要定義圓心,和其半徑
_CircleParameter("Circle Parameter",Vector)=(0.5,0.5,0.2,1) //xy 為圓心所在位置, z為半徑 ,w為光線強(qiáng)度接下來我們需要得到uv坐標(biāo)下,每個(gè)點(diǎn)距離我們定義的圓的距離
float2 centrePoint=_CircleParameter.xy; //圓心 float dis=distance(IN.uv,centrePoint); //uv與圓心的距離很明顯,我們只需要 距離dis在圓半徑_CircleParameter.z范圍內(nèi)的點(diǎn),可以通過如下代碼獲得
float factor= step(dis,_CircleParameter.z);factor 的值為 圓半徑小于兩點(diǎn)距離(_CircleParameter.z<dis)則為0,否則為1。step函數(shù)可以搜索CG 標(biāo)準(zhǔn)函數(shù)庫查看相關(guān)概念。
接下里我們可以通過得到的factor為點(diǎn)光顏色去做裁剪,去掉圓以外的光顏色。很明顯在圓以外的factor值都為0,只要將光顏色(_PointColor)的alpha值乘以factor。
_PointColor.a*=factor; //裁剪掉超出圓范圍的光有些圖片上有透明元素,比如我在上面中使用的圖片,顯然這些透明的地方不應(yīng)該顯示光顏色,當(dāng)然如果你想的話也可以。通過采樣獲取(color)的顏色 判斷當(dāng)前像素上是否透明,不需要顯示。
_PointColor.a*=step(0.01,color.a); //裁剪掉透明處的光光是有衰減的,我們可以通過如下一個(gè)簡單的計(jì)算得到。
_PointColor.a*=1.0-(dis/_CircleParameter.z); //光的衰減點(diǎn)距離圓心越近dis/_CircleParameter.z越小,但是很明顯衰減是從圓心往外的,可以用去1去減使其相反。
最后只需要混合光的顏色和采樣得到的顏色
color.rgb= color.rgb+_PointColor.rgb*_PointColor.a*_CircleParameter.w; //混合顏色 ,_CircleParameter.w為顏色強(qiáng)度有時(shí)候我們會(huì)希望圖片做一些裁剪,比如讓它只顯示圓的形狀。那么我們只需要以上代碼的基礎(chǔ)上,通過采樣顏色的alpha乘以factor就可以去掉范圍以外的顏色。代碼十分簡單
color.a*=factor;棱形光
基本思想與上面的圓類似,簡單的來說,就是我們需要判斷哪些點(diǎn)在這個(gè)棱形范圍內(nèi)。
上圖中使用的是四邊相等的棱形,并且頂點(diǎn)距離坐標(biāo)中心為1,很明顯此棱形在四邊上的點(diǎn)有如下關(guān)系式 x+y=1(x和y分布都是x上距離坐標(biāo)中心的距離,和y上距離坐標(biāo)中心的距離)。那么在此棱形中的點(diǎn)顯然 小于 x+y。只需要將uv坐標(biāo)轉(zhuǎn)換為上圖以棱形為坐標(biāo)系,可以很容易計(jì)算點(diǎn)是否在棱形內(nèi)。代碼如下
最后把所有完整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) //點(diǎn)光的顏色_CircleParameter("Circle Parameter",Vector)=(0.5,0.5,0.2,1) //xy 為圓心所在位置, z為半徑 ,w為光線強(qiáng)度[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 相關(guān)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為顏色強(qiáng)度//color.rgb= (color.rgb*color.a+_PointColor.rgb*_PointColor.a*_CircleParameter.w)*step(0.001,_PointColor.a); //混合顏色 ,_CircleParameter.w為顏色強(qiáng)度return color;}ENDCG}} }謝謝。
總結(jié)
以上是生活随笔為你收集整理的Unity3d Ugui图片上制作点光 、棱形光效果shader,并具有裁切的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hive优化笔记
- 下一篇: 计算机与软件学院辅导员陈伯亨,十年桃李满