Unity3D Shader实现动态屏幕遮罩

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Unity shader实现遮罩效果

    本文实例为大家分享了Unity shader实现遮罩效果的具体代码,供大家参考,具体内容如下 效果: shader代码: Shader "Custom/Mask" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {}//目标图片,即需要被遮罩的图片 _MaskLayer("Culling Mask",2D) = "white"{}//混合的图片,设置

  • Unity3D Shader实现动态屏幕遮罩

    屏幕可视范围跟随目标物体移动,可修改可视范围大小,边缘渐变大小.以及遮罩颜色,支持最高物体数量可在Shader中修改,当前版本支持最多9个物体. 效果图如下: 控制面板如下: Shader代码如下: Shader "Peter/DarkEffect" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { // No culling or depth Cull Off

  • Unity3D Shader实现动态星空

    本文实例为大家分享了Unity3D Shader实现动态星空的具体代码,供大家参考,具体内容如下 Shader "Unlit/Test" { Properties { [Gamma][Header(CubeMap)]_MainColor("MainColor",COLOR)=(0.5,0.5,0.5,1) _Spec("Spec",Range(1,8))=1 [NoScaleOffset]_Tex("CubeMap",CUBE

  • Unity3D Shader实现流光效果

    本文实例为大家分享了Unity3D Shader实现流光效果的具体代码,供大家参考,具体内容如下 流光效果图: 演示工程:下载地址 //功能需求:模拟数据传送效果,高亮色块从模型上方移动到下方 //功能分析:这里采用UV动画的方式来实现,利用Alpha贴图控制流动的形状 // 利用Alpha遮罩贴图,控制模型中哪些地方需要进行流动 Shader "Custom/DataFlowEffect" { Properties { _MainColor("Main Color"

  • Unity3D Shader实现扫描显示效果

    本文实例为大家分享了Unity3D Shader实现扫描显示的具体代码,供大家参考,具体内容如下 通过Shader实现,从左向右的扫描显示,可自定义扫描颜色.宽度.速度. 效果图如下 编辑器界面如下 Shader源码如下 Shader "XM/ScanEffect" { Properties { _MainTex("Main Tex", 2D) = "white"{} _lineColor("Line Color", Colo

  • Unity3D Shader实现镜子效果

    本文实例为大家分享了Unity3D Shader实现镜子效果的具体代码,供大家参考,具体内容如下/p> Shader部分代码: Shader "Custom/FanShe" { Properties{ _MainTex("Albedo",2D) = "white"{} _MainTint("Diffuse Color",Color)=(1,1,1,1) _Cubemap("Cubemap",CUBE)

  • Unity Shader实现动态过场切换图片效果

    本文实例为大家分享了Unity Shader实现动态过场切换图片的具体代码,供大家参考,具体内容如下 一.简单介绍 Shader Language的发展方向是设计出在便携性方面可以和C++.Java等相比的高级语言,"赋予程序员灵活而方便的编程方式",并"尽可能的控制渲染过程"同时"利用图形硬件的并行性,提高算法效率". 本文介绍,如何使用 shader ,动态过场形式切换图片的一点简单效果. 二.实现原理 1.通过时间叠加判断,当 值小于 主图

  • Unity Shader实现动态雾效果

    Unity Shader学习:动态雾,供大家参考,具体内容如下 先将相机近裁面四个角向量传给shader,再通过观察空间下的深度值和相机位置算出像素在世界坐标系的位置,通过世界空间高度值来设定雾的范围和浓度,然后通过噪声和uv偏移实现扰动效果.得到了类似寂静岭或恶灵附身1的效果. C#部分: using System.Collections; using System.Collections.Generic; using UnityEngine; [ExecuteInEditMode] publ

  • Unity3D Shader实现扫描显示效果(2)

    上一篇使用的方式是对UV进行剪裁,如果用于模型的话,会出现一些问题.本篇使用的方式是对模型进行模型空间的剪裁,可设置剪裁方向.效果如下: 设置界面如下: mode用于设置剪裁方向. clip用于设置剪裁值. shader实现如下: Shader "XM/ScanEffect2" { Properties { _Color ("Color", Color) = (1,1,1,1) _MainTex ("Albedo (RGB)", 2D) = &q

  • Unity3D Shader实现贴图切换效果

    本文实例为大家分享了shader实现基于世界坐标的贴图置换效果. 效果如下: 设置面板如下: 可在面板上设置切换方向,与切换对象,及其切换速度. shader实现如下: Shader "XM/Effect/SwapTexture" { Properties { _Color ("Color", Color) = (1,1,1,1) _MainTex ("Albedo (RGB)", 2D) = "white" {} _Targ

  • Unity中的静态批处理和动态批处理操作

    前言 Unity在运行时可以将一些物体进行合并,从而用一个绘制调用来渲染他们.这一操作,我们称之为"批处理",能得到越好的渲染性能. Unity中内建的批处理机制所达到的效果要明显强于使用几何建模工具的批处理效果,因为,Unity引擎的批处理操作是在物体的可视裁剪操作之后进行的,处理的几何信息少很多. 材质 只有拥有相同材质的物体才可以进行批处理,因此,你需在程序中尽可能多地复用材质.如果你的两个材质仅仅是纹理不同,那么你可通过纹理拼合来将这两张纹理拼合成一张大的纹理,这样,你就可以使

随机推荐