转载 https://blog.csdn.net/u012741077/article/details/78425834

屏幕可视范围跟随目标物体移动,可修改可视范围大小,边缘渐变大小、以及遮罩颜色,支持最高物体数量可在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);
}
}

[Unity3D]Shader编程之动态屏幕遮罩的更多相关文章

  1. 【浅墨Unity3D Shader编程】之二 雪山飞狐篇:Unity的基本Shader框架写法&amp;颜色、光照与材质

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/40955607 作者:毛星云(浅墨)  ...

  2. 【浅墨Unity3D Shader编程】之三 光之城堡篇:子着色器、通道与标签的写法 &amp; 纹理混合

    本系列文章由@浅墨_毛星云 出品,转载请注明出处.   文章链接:http://hpw123.net/a/C__/kongzhitaichengxu/2014/1117/120.html 作者:毛星云 ...

  3. 【浅墨Unity3D Shader编程】之一 夏威夷篇:游戏场景的创建 & 第一个Shader的书写

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/40723789 作者:毛星云(浅墨)  ...

  4. 【浅墨Unity3D Shader编程】之中的一个 夏威夷篇:游戏场景的创建 &amp; 第一个Shader的书写

    本系列文章由@浅墨_毛星云 出品.转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/40723789 作者:毛星云(浅墨)  ...

  5. 【Aladdin Unity3D Shader编程】之一 基本入门

    OpenGL.DirectX以及GLSL.HLSL.CG OpenGL和DirectX是图像应用编程接口,用于渲染二维或者三维图形. GLSL着色语言是用来在OpenGL中着色编程的语言,有点在于跨平 ...

  6. 【Aladdin Unity3D Shader编程】之三 光照模型(二)

    高光反射模型 Specular=直射光*pow(cosθ,高光的参数) θ:是反射光和视野方向的夹角 编写高光反射Shader Shader "AladdinShader/07 Specul ...

  7. 【Aladdin Unity3D Shader编程】之四 贴图纹理

    关于纹理贴图介绍 纹理坐标也叫UV坐标,UV坐标都是0~1,并不是我们所理解的像素坐标,相当于是一个百分比. 编写shader映射纹理 将纹理的颜色取代漫反射的颜色 Shader "Alad ...

  8. 【Aladdin Unity3D Shader编程】之二 光照模型(一)

    光照模型 光照模型就是一个公式,使用这个公式来计算在某个点的光照效果. 在标准光照模型里面,我们把进入摄像机的光分为下面四个部分: 自发光 类似生活中的萤火虫等自己能够发光 高光反射 类似生活中的镜子 ...

  9. 【译】Unity3D Shader 新手教程(1/6)

    本文为翻译,附上原文链接. 转载请注明出处--polobymulberry-博客园. 刚开始接触Unity3D Shader编程时,你会发现有关shader的文档相当散,这也造成初学者对Unity3D ...

随机推荐

  1. vim command

    问题:对多行缩进 简述:向左缩是<,向右缩是> 详述:在命令状态,按v进入visual状态,选中多行,再按>,相当于一个TAB键:再选中多行,按<试试 ------------ ...

  2. 'System.ValueTuple, Version=0.0.0.0 required for Add-Migration on .NET 4.6.1 Class Library

    https://stackoverflow.com/questions/45978173/system-valuetuple-version-0-0-0-0-required-for-add-migr ...

  3. Update语句到底是如何操作记录的?

    经常会听到一些开发的朋友说,Update语句的操作原理是:先删后加!今天偶然想起这句话,索性验证一下.参考下面示例: USE CSDN go --新添加一个文件组和文件 ALTER DATABASE ...

  4. Linux下配置Apache为多端口

    1.打开Apache的配置文件httpd.conf,在Listen 80处另起一行输入Listen 8080(监听8080端口),要想再添加端口可依次添加 2.在httpd.conf文件最后一行添加: ...

  5. 973. K Closest Points to Origin

    We have a list of points on the plane.  Find the K closest points to the origin (0, 0). (Here, the d ...

  6. while 小项目练习

    # (1) 用双层while 写十行十列小星星 j = 0 while j < 10: #打印一行十个小星星 i = 0 while i <10: print("*", ...

  7. 一个简单的HTML病毒分析

    一直就想写这篇东西了,仅仅是上班时说要上班,不写.回家后又忙着玩游戏,丢一边去了.如今仅仅好不务正业的开写了.希望头儿不会知道我的blog.哈哈 在非常久之前就对HTML的病毒非常感兴趣了,非常好奇怎 ...

  8. TCP的超时与重传

    一.引言 对于每个TCP连接,TCP管理4个不同的定时器 重传定时器用于当希望收到另一端的确认. 坚持 (persist) 定时器使窗口大小信息保持不断流动,即使另一端关闭了其接收窗口. 保活 (ke ...

  9. P5038 [SCOI2012]奇怪的游戏 二分+网络流

    $ \color{#0066ff}{ 题目描述 }$ Blinker最近喜欢上一个奇怪的游戏. 这个游戏在一个 \(N \times M\) 的棋盘上玩,每个格子有一个数.每次\(Blinker\)会 ...

  10. ubuntu->桌面版-常用设置

    1.目前使用unity桌面 ,使用Gnome,未来将会采用 Qt/QML 语言写的桌面 2.汉化 系统: 在 设置(setting)->语言支持(language support)->选择 ...