转载 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. Mybatis 拦截器报错org.apache.ibatis.executor.statement.StatementHandler.prepare(java.sql.Connection)

    出现此错误的原因是MyBatis 3.4.0 之后,StatementHandler的prepare方法做了修改,如下: 在args = { Connection.class }中添加第二个参数,即 ...

  2. C#多线程学习(二) 如何操纵一个线程

    在C#中,线程入口是通过ThreadStart代理(delegate)来提供的,你可以把ThreadStart理解为一个函数指针,指向线程要执行的函数,当调用Thread.Start()方法后,线程就 ...

  3. C# Pinvoke判断是UEFI模式还是BIOS模式

    [DllImport("kernel32.dll", SetLastError = true)] public static extern UInt32 GetFirmwareEn ...

  4. dataframe初始化

  5. Centos6和7的区别

    1.init系统 Linux 操作系统的启动首先从 BIOS 开始,接下来进入 boot loader,由 bootloader 载入内核,进行内核初始化.内核初始化的最后一步就是启动 pid 为 1 ...

  6. css3中的translate,transform,transition的区别

    translate:移动,transform的一个方法               通过 translate() 方法,元素从其当前位置移动,根据给定的 left(x 坐标) 和 top(y 坐标) ...

  7. java学习笔记_多态

    多态:父类的变量可以引用子类的对象 引用: Student s1 = stu; s1.setScore(200); 1.一个对象可以有多个引用,可以有多个变量操作同一个对象   2.当一个对象没有任何 ...

  8. SecureCRT上传下载文件

    这篇内容在哪看到的我也找不到了,不过就是做个记录. 步骤如下: 1.SecureCRT连接远程终端. 2.在连接窗口上方右击,弹出菜单后点击Connect SFTP Session, 3.点击后弹出窗 ...

  9. css样式之标签的查找

    css的组成部分:选择器和声明 css的注释: /*这是注释*/ <!DOCTYPE html> <html lang="zh-CN"> <head& ...

  10. 大象——Thinking in UML

    目录 大象--Thinking in UML 面向对象 普通民众的面向对象 大师眼中的面向对象 大象--Thinking in UML 大音希声,大象希形, 近来闲暇,随手翻起一些曾经看过的书籍,才发 ...