博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UnityShader之屏幕特效基础
阅读量:6999 次
发布时间:2019-06-27

本文共 5924 字,大约阅读时间需要 19 分钟。

1、什么是屏幕特效

我们这里讲的屏幕特效技术,指的是在渲染完整个场景后得到的屏幕图象的基础上,再对这个屏幕图像做一系列处理,实现出屏幕特效,使用这种技术可以为屏幕画面增添各种风格的艺术效果,比如泛光、景深、模糊等等。
 

2、unity实现屏幕特效的原理

如上所述,要实现屏幕特效,首先要抓取渲染完整个场景得到的屏幕图像,在unity中,提供了OnRenderImage函数,方便我们进行这样的操作。它的声明如下:MonoBehaviour.OnRenderImage(RenderTexture src,RenderTexture dest);unity会把当前渲染得到的图像存储在第一个参数对应的渲染纹理中,通过自定义的一系列操作后,得到目标渲染纹理(第二个参数中的渲染纹理),目标渲染纹理会最终显示在屏幕上。在OnRenderImage函数中,使用Graphics.Blit函数来对渲染纹理进行处理。这里我们做一个可以改变画面亮度、饱和度、以及对比度的简单屏幕特效。
 

3、C#脚本实现

//////                          _ooOoo_                               ////                         o8888888o                              ////                         88" . "88                              ////                         (| ^_^ |)                              ////                         O\  =  /O                              ////                      ____/`---'\____                           ////                    .'  \\|     |//  `.                         ////                   /  \\|||  :  |||//  \                        ////                  /  _||||| -:- |||||-  \                       ////                  |   | \\\  -  /// |   |                       ////                  | \_|  ''\---/''  |   |                       ////                  \  .-\__  `-`  ___/-. /                       ////                ___`. .'  /--.--\  `. . ___                     ////              ."" '<  `.___\_<|>_/___.'  >'"".                  ////            | | :  `- \`.;`\ _ /`;.`/ - ` : | |                 ////            \  \ `-.   \_ __\ /__ _/   .-` /  /                 ////      ========`-.____`-.___\_____/___.-`____.-'========         ////                           `=---='                              ////      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        ////                 佛祖保佑          永无BUG                      //////using System.Collections;using System.Collections.Generic;using UnityEngine;[ExecuteInEditMode][RequireComponent(typeof(Camera))]public class ScreenEffect : MonoBehaviour {    public Shader effectShader;      private Material effectMaterial;    public Material EffectMaterial    {        get        {            effectMaterial = CreateMaterial(effectShader, effectMaterial);            return effectMaterial;        }    }    [Range(0.0f, 3.0f)]    public float brightness = 1.0f;  //亮度    [Range(0.0f, 3.0f)]    public float saturation = 1.0f;  //饱和度    [Range(0.0f, 3.0f)]    public float contrast = 1.0f;    //对比度    void OnRenderImage(RenderTexture src, RenderTexture dest)    {        if (EffectMaterial != null)        {            EffectMaterial.SetFloat("_Brightness", brightness);            EffectMaterial.SetFloat("_Saturation", saturation);            EffectMaterial.SetFloat("_Contrast", contrast);            //对渲染纹理进行处理            Graphics.Blit(src, dest, EffectMaterial);        }        else        {            Graphics.Blit(src, dest);        }    }    private void Start()    {        bool isSupported = CheckSupport();        if (isSupported == false)        {            this.enabled = false;        }    }       // 检测当前平台是否支持屏幕特效    private bool CheckSupport()    {        if (SystemInfo.supportsImageEffects == false || SystemInfo.supportsRenderTextures == false)        {            Debug.LogWarning("当前平台不支持!");            return false;        }        return true;    }        // 创建材质    private Material CreateMaterial(Shader shader, Material material)    {        if (shader == null)        {            return null;        }        if (shader.isSupported && material && material.shader == shader)            return material;        if (!shader.isSupported)        {            return null;        }        else        {            material = new Material(shader);            material.hideFlags = HideFlags.DontSave;            if (material)                return material;            else                return null;        }    }}

4、Shader实现

Shader "yzpShader/ScreenEffect" {    Properties {        _MainTex ("Base (RGB)", 2D) = "white" {}  //需要处理的渲染纹理        _Brightness ("Brightness", Float) = 1     //亮度        _Saturation("Saturation", Float) = 1      //饱和度        _Contrast("Contrast", Float) = 1          //对比度    }    SubShader {        Pass {              ZTest Always Cull Off ZWrite Off                        CGPROGRAM              #pragma vertex vert              #pragma fragment frag                            #include "UnityCG.cginc"                            sampler2D _MainTex;              half _Brightness;            half _Saturation;            half _Contrast;                          struct v2f {                float4 pos : SV_POSITION;                half2 uv: TEXCOORD0;            };                          v2f vert(appdata_img v) {                v2f o;                                o.pos = UnityObjectToClipPos(v.vertex);                                o.uv = v.texcoord;                                         return o;            }                    fixed4 frag(v2f i) : SV_Target {                fixed4 renderTex = tex2D(_MainTex, i.uv);                                    // 计算亮度改变后的颜色                fixed3 finalColor = renderTex.rgb * _Brightness;                                // 计算饱和度改变后的颜色                fixed luminance = 0.2125 * renderTex.r + 0.7154 * renderTex.g + 0.0721 * renderTex.b;                fixed3 luminanceColor = fixed3(luminance, luminance, luminance);                finalColor = lerp(luminanceColor, finalColor, _Saturation);                                // 计算对比度改变后的颜色                fixed3 avgColor = fixed3(0.5, 0.5, 0.5);                finalColor = lerp(avgColor, finalColor, _Contrast);                                return fixed4(finalColor, renderTex.a);              }                            ENDCG        }      }        Fallback Off}

5、测试结果

首先将C#脚本挂在场景相机上,并将上面写好的shader拖拽到ScreenEffect脚本的effectShader上,修改该脚本的brightness、saturation、contrast值,可以得出下面这样的效果:

 

转载于:https://www.cnblogs.com/IAMTOM/p/10072794.html

你可能感兴趣的文章
easyui实现datagrid列标题拖动
查看>>
CentOS 6.5系统安装配置LAMP(Apache+PHP5+MySQL)服务器环境
查看>>
在Websphere上修改项目的web.xml中的配置后不起作用
查看>>
JAVA 数据计算、取整、+1、四舍五入
查看>>
wshell修改了upload功能,増加显示图片功能
查看>>
ERP中标准成本的差异分析控制
查看>>
linux 中断的上半部和下半部
查看>>
单例模式的七种写法
查看>>
好用到吐血!APP设计利器Sketch
查看>>
Android TensorFlow环境搭建
查看>>
【细品架构1/100】架构之缘起
查看>>
在js中获取后台传出的json数据
查看>>
Drools的JSR94实现形式
查看>>
oracle的nvl和nvl2
查看>>
hdfs 写orc
查看>>
1.9 xz压缩和解压缩
查看>>
IDEA如何自动提示并补全syso和main呢?
查看>>
9.数组和向量
查看>>
JXL读写Excel
查看>>
mysql自定义排序
查看>>