Unity 屏幕特效 之 基础知识简介,屏幕灰度特效实现
程序员文章站
2022-05-24 23:45:52
...
Unity 屏幕特效 之 基础知识简介,屏幕灰度特效实现
目录
四、MonoBehaviour.OnRenderImage(RenderTexture,RenderTexture) 函数
一、前言:
unity shader中的pass是会顺序执行的,但是由于在图像处理中我们常常需要使用一个pass的处理结果作为另一个pass的输入,这个时候就需要用到OnRenderImage()函数了。
二、函数介绍
MonoBehaviour.OnRenderImage(RenderTexture source,RenderTexture destination)
官方描述Description
OnRenderImage is called after all rendering is complete to render image.,该函数在所有的渲染完成后由monobehavior自动调用。
官方解释:该函数允许我们使用着色器滤波操作来修改最终的图像,输入原图像source,输出的图像放在desitination里。
三、Graphics.Blit()函数
该函数的作用就是通过一个shader将原图的像素放置到destionation中。
四、MonoBehaviour.OnRenderImage(RenderTexture,RenderTexture) 函数
五、Shader 脚本模板(仅供参考)
Shader "xxxx/xxxxxx"
{
Properties
{
_MainTex("Base (RGB)", 2D) = "white" {}
......
......
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
......
fixed4 frag(v2f_img i) : COLOR
{
fixed4 finalColor;
.......
.......
return finalColor;
}
ENDCG
}
}
FallBack off
}
六、屏幕特效示例
屏幕特效案例测试,如下:
1、写一个让图片变为灰度图的屏幕特效;
2、新建一个shader,进行屏幕特效原图转为灰度图;
3、然后新建一个脚本,把脚本拖动到主相机下,然后将 shader 赋予相应变量即可;
(注意在示例中,我们用到了Material::SetTexture()函数,这是给材质赋值的,我们这里把原图的值赋值给_MainTex,然后shader处理的时候采样的图片就是相机得到的场景图片了,这里可以设置所有类型的值,你也可以尝试自己写一个滑动条,然后动态设置图片的灰度级别)
4、工程效果测试图
七、示例特效 shader 和 脚本代码
Shader "Unlit/ZTestImageEffect"
{
Properties
{
_MainTex("Base (RGB)", 2D) = "white" {}
_LuminosityAmount("Brightness Amount", Range(0.0, 1)) = 1.0
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
fixed _LuminosityAmount;
fixed4 frag(v2f_img i) : COLOR
{
//Get the colors from the RenderTexture and the uv's
//from the v2f_img struct
fixed4 renderTex = tex2D(_MainTex, i.uv);
//Apply the Luminosity values to our render texture
float luminosity = 0.299 * renderTex.r + 0.587 * renderTex.g + 0.114 * renderTex.b;
fixed4 finalColor = lerp(renderTex, luminosity, _LuminosityAmount);
return finalColor;
}
ENDCG
}
}
FallBack off
}
using UnityEngine;
using System.Collections;
/// <summary>
/// 1、表示在编辑器模式下运行
/// 2、实时变化灰度参数。这个就是脚本里设置Shader中的参数值
/// 3、Shader中根据这个参数值把灰度效果渲染到RenderTexture上
/// </summary>
[ExecuteInEditMode]
public class TestImageEffectGrey : MonoBehaviour
{
#region Variables
public Shader curShader; // 进行屏幕变化的 shader
public float grayScaleAmount = 1.0f; // 灰度与原色的插值比例
private Material curMaterial; // shader 对应的材质
#endregion
#region Properties
// curMaterial的属性
Material material
{
get
{
if (curMaterial == null)
{
curMaterial = new Material(curShader);
curMaterial.hideFlags = HideFlags.HideAndDontSave;
}
return curMaterial;
}
}
#endregion
void Start()
{
// 判断但钱是否支持图片特效
if (!SystemInfo.supportsImageEffects)
{
enabled = false;
return;
}
// 判断材质是否为空,并且当前材质是否支持
if (!curShader && !curShader.isSupported)
{
enabled = false;
}
}
// 屏幕特效处理
void OnRenderImage(RenderTexture sourceTexture, RenderTexture destTexture)
{
if (curShader != null)
{
material.SetFloat("_LuminosityAmount", grayScaleAmount);
Graphics.Blit(sourceTexture, destTexture, material);
}
else
{
Graphics.Blit(sourceTexture, destTexture);
}
}
void Update()
{
// 保持 值在 0,1 之间
grayScaleAmount = Mathf.Clamp(grayScaleAmount, 0.0f, 1.0f);
}
void OnDisable()
{
// 销毁当前材质
if (curMaterial)
{
DestroyImmediate(curMaterial);
}
}
}