转载 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. GCT感受

    GCT考试已经结束了,但是复习GCT的时候一直没来得及总结点什么,GCT考的比较基础,所以复习起来并不是特别费力,但是还是有一些东西值得我们去学习的. 对于GCT考试,一开始在报名的时候其实心里是挺抵 ...

  2. Java == 和 equals 比较

    在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str2 = new String(&qu ...

  3. 《html5 从入门到精通》读书笔记(一)

    今天看了<html5 从入门到精通>这本书,感觉阅读下来很舒心,不像阅读其他书籍很揪心.html增加的知识点,我觉得非常有价值,看完几章记录了一些内容,不但能巩固,也为下次遗忘知识点做好准 ...

  4. vmware获取主机、数据中心等对象ManagedObjectReference

    在vmware的api中提供以下列表中的对象,称作ManagedObjectReference,包括虚拟机信息.主机.数据中心等等一些信息,我们可以通过vcenter的web api得到. 下面我们来 ...

  5. nowcoder(牛客网)OI测试赛2 解题报告

    qwq听说是一场普及组难度的比赛,所以我就兴高采烈地过来了qwq 然后发现题目确实不难qwq.....但是因为蒟蒻我太蒻了,考的还是很差啦qwq orz那些AK的dalao们qwq 赛后闲来无事,弄一 ...

  6. 爬虫开发13.UA池和代理池在scrapy中的应用

      今日概要 scrapy下载中间件 UA池 代理池 今日详情 一.下载中间件 下载中间件(Downloader Middlewares) 位于scrapy引擎和下载器之间的一层组件. - 作用: ( ...

  7. “全栈2019”Java第三十二章:增强for循环Foreach语法

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  8. [AIR] 利用File获取应用程序根目录

    import flash.filesystem.File; var file1:File = new File(File.applicationDirectory.resolvePath(" ...

  9. [Swift]扩展String类:extension String

    请参考本博客另一篇技术博文: <[Swift]字符串(String类.NSString类)常用操作> extension String { //获取字符串首字符 var first: St ...

  10. 【python】10分钟教你用python如何正确把妹

    前言 今天没妹子约,刚好研究一下.如何用神奇的python打造一个把妹神器吧.看完这个,你们就能走向人生巅峰,迎娶白富美啦. 我知道你们想看看效果 image 当然啦,这只是测试版的效果,真正的版本可 ...