Unity中基于屏幕后处理的彩色与黑白渐变效果

xiaoxiao2021-02-28  83

本文将介绍Unity屏幕后处理的基本方法与游戏角色死亡后的屏幕渐变到黑白效果的实现方法。

屏幕后处理是指整个场景每一帧渲染完毕后,再对得到的屏幕图像进行一系列处理并显示到屏幕上的过程。Unity中我们一般使用C#脚本与Shader搭配的方法来实现屏幕后处理。我们首先需要将C#脚本添加到摄像头中,再在脚本中通过OnRenderImage()函数来获取屏幕图像,最后在OnRenderImage()函数中使用Graphics.Blit()函数来根据指定的Shader处理屏幕图像。

C#脚本部分需要两个重要函数:MonoBehaviour.OnRenderImage()函数与Graphics.Blit()函数。OnRenderImage()有两个参数:

MonoBehaviour.OnRenderImage(RenderTexture src,RenderTexture dest)

Unity会将每一帧得到的原始图像存储在src中,再根据函数中我们编写的算法进行处理,只要我们将处理结果存储到dest中,Unity便会将它显示到屏幕上,这就是整个屏幕后处理的基本流程。OnRnederImage中会用到另一个重要函数Graphics.Blit()。它有三种重载方式:

public static void Blit(Texture source, RenderTexture dest); public static void Blit(Texture source, RenderTexture dest, Material mat, int pass = -1); public static void Blit(Texture source, Material mat, int pass = -1)

参数source会赋值给shader中的_MainTex属性,参数dest是目标渲染纹理,参数mat是我们指定的材质,pass是我们指定的shader中的pass索引,当它等于-1时,会依次调用shader中所有的pass,否则仅调用索引位置的pass。当使用第三种重载方式时,没有dest参数,渲染结果会直接显示在屏幕上。以下是本例中的C#脚本,我们可以通过调整GrayFactor的黑白程度。

using System.Collections; using System.Collections.Generic; using UnityEngine; public class BlackAndWhite : MonoBehaviour { Material material; public Shader shader; [Range(0,1.0f)] public float GrayFactor; // Use this for initialization void Start () { material = new Material(shader); } // Update is called once per frame void Update () { if(GrayFactor<1) GrayFactor += Time.deltaTime*0.5f; } void OnRenderImage(RenderTexture src,RenderTexture dest) { if (material != null) { //设置shader中的_GrayFactor参数 material.SetFloat("_GrayFactor", GrayFactor); Graphics.Blit(src, dest, material); } else { Graphics.Blit(src, dest); } }

Shader代码的思路也比较简单,先取出每个像素的亮度值,使用它就可以建立一个饱和度为0的颜色(纯黑白)。我们再使用lerp函数与_GrayFactor对画面的彩色与新建的黑白颜色进行插值,最终返回插值颜色即可。

Shader "PostEffect/NewUnlitShader" { Properties{ _MainTex("MainTex",2D)="white"{} } SubShader{ Pass{ ZTest Always Cull Off ZWrite Off CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" sampler2D _MainTex; fixed _GrayFactor; struct v2f{ float4 pos:SV_POSITION; half2 uv:TEXCOORD0; }; v2f vert(appdata_img v){ v2f o; o.pos=mul(UNITY_MATRIX_MVP,v.vertex); o.uv=v.texcoord; return o; } fixed4 frag(v2f i):SV_Target { fixed4 renderTex=tex2D(_MainTex,i.uv); //提取亮度 fixed luminance=0.2125*renderTex.r+0.7154*renderTex.g+0.0721*renderTex.b; //建立0饱和度颜色 fixed3 luminanceColor=fixed3(luminance,luminance,luminance); //对颜色进行插值 fixed3 finalColor=lerp(renderTex.rgb,luminanceColor,_GrayFactor); return fixed4(finalColor,1.0); } ENDCG } } }

实现效果:

转载请注明原文地址: https://www.6miu.com/read-27197.html

最新回复(0)