雷火电竞-中国电竞赛事及体育赛事平台

歡迎來到入門教程網(wǎng)!

C#教程

當(dāng)前位置:主頁 > 軟件編程 > C#教程 >

Unity3D Shader實(shí)現(xiàn)動(dòng)態(tài)屏幕遮罩

來源:本站原創(chuàng)|時(shí)間:2020-01-10|欄目:C#教程|點(diǎn)擊:

屏幕可視范圍跟隨目標(biāo)物體移動(dòng),可修改可視范圍大小,邊緣漸變大小、以及遮罩顏色,支持最高物體數(shù)量可在Shader中修改,當(dāng)前版本支持最多9個(gè)物體。

效果圖如下:

控制面板如下:

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"

      //追蹤物體最多個(gè)數(shù)
      #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#調(diào)用代碼如下:

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);
    }
  }

  //漸變像素?cái)?shù)量
  public int _smoothLength = 20;
  //遮罩混合顏色
  public Color _darkColor = Color.black;
  //目標(biāo)物體
  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);
  }
}

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持我們。

上一篇:Unity通過UGUI的Slider調(diào)整物體顏色

欄    目:C#教程

下一篇:c#開發(fā)cad預(yù)覽圖塊步驟詳解

本文標(biāo)題:Unity3D Shader實(shí)現(xiàn)動(dòng)態(tài)屏幕遮罩

本文地址:http://www.jygsgssxh.com/a1/C_jiaocheng/4854.html

網(wǎng)頁制作CMS教程網(wǎng)絡(luò)編程軟件編程腳本語言數(shù)據(jù)庫服務(wù)器

如果侵犯了您的權(quán)利,請(qǐng)與我們聯(lián)系,我們將在24小時(shí)內(nèi)進(jìn)行處理、任何非本站因素導(dǎo)致的法律后果,本站均不負(fù)任何責(zé)任。

聯(lián)系QQ:835971066 | 郵箱:835971066#qq.com(#換成@)

Copyright © 2002-2020 腳本教程網(wǎng) 版權(quán)所有