Unity全局置灰白(辅助标签:OnRenderImage,shader)

文章目录

      • 一. 前言
      • 二. 接口
        • MonoBehaviour的OnRenderImage函数
        • Graphics.Blit函数
      • 三. RGB转灰色算法
      • 四. 使用例子
        • C#脚本
        • Shader

注意:此方法在iOS上会有问题,导致摄像机无法渲染,黑屏。

一. 前言

在一些特殊的日子需要表示哀悼,游戏可能需要灰白色显示。

Unity提供了一些接口给我们。

二. 接口

MonoBehaviour的OnRenderImage函数

MonoBehaviour.OnRenderImage(RenderTexture source, RenderTexture destination)

官方描述
OnRenderImage is called after all rendering is complete to render image.,该函数在所有的渲染完成后由monobehavior自动调用。
该函数允许我们使用着色器滤波操作来修改最终的图像,输入原图像source,输出的图像放在desitination里。

Graphics.Blit函数

public static void Blit(Texture source, RenderTexture dest, Vector2 scale, Vector2 offset);
public static void Blit(Texture source, RenderTexture dest, Vector2 scale, Vector2 offset, int sourceDepthSlice, int destDepthSlice);
public static void Blit(Texture source, RenderTexture dest, Material mat, [Internal.DefaultValue("-1")] int pass);
public static void Blit(Texture source, RenderTexture dest, Material mat, int pass, int destDepthSlice);
public static void Blit(Texture source, RenderTexture dest, Material mat);
public static void Blit(Texture source, RenderTexture dest);
public static void Blit(Texture source, Material mat, int pass, int destDepthSlice);
public static void Blit(Texture source, Material mat);
public static void Blit(Texture source, RenderTexture dest, int sourceDepthSlice, int destDepthSlice);
public static void Blit(Texture source, Material mat, [Internal.DefaultValue("-1")] int pass);

该函数的作用就是通过一个shader将原图的像素放置到destionation中。

三. RGB转灰色算法

Gray = R*0.299 + G*0.587 + B*0.114

四. 使用例子

如下,把下面的C#脚本挂到摄像机上,并赋值curShader对象,Shader代码见下文。
Unity全局置灰白(辅助标签:OnRenderImage,shader)_第1张图片

C#脚本

using UnityEngine;
using System.Collections;

[ExecuteInEditMode]
public class GrayCamera : MonoBehaviour
{
    public Shader curShader;
    public float grayScaleAmount = 1.0f;
    private Material curMaterial;

    Material material
    {
        get
        { 
            if (curMaterial == null)
            {
                curMaterial = new Material(curShader);
                curMaterial.hideFlags = HideFlags.HideAndDontSave;
            }
            return curMaterial;
        }
    }
     
    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("_LumionsityAmount", grayScaleAmount);
            Graphics.Blit(sourceTexture, destTexture, material);
        }
        else
        {
            Graphics.Blit(sourceTexture, destTexture);
        }
    }

    void Update()
    {
        grayScaleAmount = Mathf.Clamp(grayScaleAmount, 0, 1.0f);
    }

    void OnDisable()
    {
        if (curMaterial)
        {
            DestroyImmediate(curMaterial);
        }
    }
}

Shader

Shader "Custom/GrayCameraEffect" 
{
    Properties
    {
        _MainTex("Base (RGB)",2D) = "white"{ }
        _LuminosityAmount("GrayScale Amount",Range(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
            {
                fixed4 renderTex = tex2D(_MainTex,i.uv);
                float luminosity = 0.299 * renderTex.r + 0.587 * renderTex.g + 0.114 * renderTex.b;
                fixed4 finalColor = lerp(renderTex,luminosity,_LuminosityAmount);
                return finalColor;
            }
            ENDCG
        }
    }

    FallBack "Diffuse"
}

你可能感兴趣的:(Unity3D)