先看效果:
天空盒和角色都慢慢灰度化了,人物死亡的时候将屏幕置灰,很实用。
首先创建一个置灰的shader,如下:
Shader "MyShader/die"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Speed("Speed",float)=0
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _Speed;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
fixed4 grayCol = col.r*0.299 + col.g*0.587 + col.b*0.114;//得到灰度
col = lerp(col, grayCol, _Speed);
return col;
}
ENDCG
}
}
}
上面的rgb分别乘上0.299,0.587,0.114让原本的图变成灰度图,那是每个rgb通道所占的权重,因为我们人眼对每种颜色的敏感度不一样,所以权重也不一样。
接下来就是创建一个c#代码,挂载在Camera上。代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraGray : MonoBehaviour
{
private Shader grayShader;
private Material mat;
private float speed = 0;
void Start()
{
grayShader = Shader.Find("MyShader/die");
mat = new Material(grayShader);
}
void Update()
{
speed = Mathf.Lerp(speed, 1, Time.deltaTime*0.5f);
}
/// <summary>
/// 在所有渲染完成后被调用,对图片进行额外渲染
/// </summary>
private void OnRenderImage(RenderTexture source, RenderTexture destination)
{
if(mat!=null)
{
mat.SetFloat("_Speed", speed);
Graphics.Blit(source, destination, mat);
}
else
{
Graphics.Blit(source, destination);
}
}
}
运行之后,屏幕就慢慢置灰了。