Unity3D Shader实现动态屏幕遮罩
程序员文章站
2023-08-17 20:45:13
屏幕可视范围跟随目标物体移动,可修改可视范围大小,边缘渐变大小、以及遮罩颜色,支持最高物体数量可在shader中修改,当前版本支持最多9个物体。
效果图如下:
控制...
屏幕可视范围跟随目标物体移动,可修改可视范围大小,边缘渐变大小、以及遮罩颜色,支持最高物体数量可在shader中修改,当前版本支持最多9个物体。
效果图如下:
控制面板如下:
shader代码如下:
shader "peter/darkeffect" { properties { _maintex ("texture", 2d) = "white" {} } subshader { // no culling or depth cull off zwrite off ztest always pass { cgprogram #pragma vertex vert #pragma fragment frag #include "unitycg.cginc" //追踪物体最多个数 #define itemsize 9 struct appdata { float4 vertex : position; float2 uv : texcoord0; }; struct v2f { float2 uv : texcoord0; float4 vertex : sv_position; }; sampler2d _maintex; fixed4 _darkcolor; float _smoothlength; fixed _itemcnt; float4 _item[itemsize]; v2f vert (appdata v) { v2f o; o.vertex = unityobjecttoclippos(v.vertex); o.uv = v.uv; return o; } fixed calcalpha(float4 vt, float4 pt) { if(pt.z < 0) { return 1; } float distpow2 = pow(vt.x - pt.x, 2) + pow(vt.y - pt.y, 2); float dist = (distpow2 > 0) ? sqrt(distpow2) : 0; float smoothlength = _smoothlength; if(smoothlength < 0) { smoothlength = 0; } float maxvalue = pt.z; float minvalue = pt.z - smoothlength; if(minvalue < 0) { minvalue = 0; smoothlength = pt.z; } if(dist <= minvalue) { return 0; } else if (dist > maxvalue) { return 1; } fixed retval = (dist - minvalue) / smoothlength; return retval; } fixed4 frag (v2f i) : sv_target { fixed alphaval = 1; fixed tmpval = 1; for(fixed index = 0; index < _itemcnt; ++index) { tmpval = calcalpha(i.vertex, _item[index]); if(tmpval < alphaval) { alphaval = tmpval; } } alphaval *= _darkcolor.a; return tex2d(_maintex, i.uv) * ( 1 - alphaval) + _darkcolor * alphaval; } endcg } } }
c#调用代码如下:
using system.collections; using system.collections.generic; using unityengine; [executeineditmode] [requirecomponent(typeof(camera))] public class darkeffect : monobehaviour { [system.serializable] public class item { [serializefield] public transform target; [serializefield] public int radius; public vector3 getscreenposition(camera cam) { return cam.worldtoscreenpoint(target.position); } } //渐变像素数量 public int _smoothlength = 20; //遮罩混合颜色 public color _darkcolor = color.black; //目标物体 public list<item> _items = new list<item>(); protected material _mainmaterial; protected camera _maincamera; vector4[] _itemdatas; item _tmpitem; vector4 _tmpvt; vector3 _tmppos; int _tmpscreenheight; private void onenable() { _mainmaterial = new material(shader.find("peter/darkeffect")); _maincamera = getcomponent<camera>(); } private void onrenderimage(rendertexture source, rendertexture destination) { if (_itemdatas == null || _itemdatas.length != _items.count) { _itemdatas = new vector4[_items.count]; } _tmpscreenheight = screen.height; for (int i = 0; i < _items.count; i++) { _tmpitem = _items[i]; _tmppos = _tmpitem.getscreenposition(_maincamera); _tmpvt.x = _tmppos.x; _tmpvt.y = _tmpscreenheight - _tmppos.y; _tmpvt.z = _tmpitem.radius; _tmpvt.w = 0; _itemdatas[i] = _tmpvt; } _mainmaterial.setint("_smoothlength", _smoothlength); _mainmaterial.setcolor("_darkcolor", _darkcolor); _mainmaterial.setint("_itemcnt", _itemdatas.length); _mainmaterial.setvectorarray("_item", _itemdatas); graphics.blit(source, destination, _mainmaterial); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: C#.NET获取拨号连接的宽带连接方法
下一篇: Unity5.6大规模地形资源创建方法