zoukankan      html  css  js  c++  java
  • [Unity3D]Shader编程之动态屏幕遮罩

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

  • 相关阅读:
    CF633C Spy Syndrome 2 trie树
    luogu 3998 [SHOI2013]发微博 map
    阿里云ECS新增端口
    阿里云运行docker容器报错
    no matches for kind "ReplicaSet" in version "extensions/v1beta1"
    k8s中flannel:镜像下载不了
    k8s删除节点后再重新添加进去(踩坑)
    如何在IntelliJ Idea中同时启动不同端口
    SpringBoot整合Elastic-job(详细)
    K8S容器探针
  • 原文地址:https://www.cnblogs.com/sanyejun/p/9848167.html
Copyright © 2011-2022 走看看