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) = //亮度
_Saturation("Saturation", Float) = //饱和度
_Contrast("Contrast", Float) = //对比度
}
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值,可以得出下面这样的效果:

UnityShader之屏幕特效基础的更多相关文章

  1. UnityShader实例15:屏幕特效之Bloom

    http://blog.csdn.net/u011047171/article/details/48522073 Bloom特效       概述        Bloom,又称“全屏泛光”,是游戏中 ...

  2. UnityShader实例13:屏幕特效之均值模糊(Box Blur)

    均值模糊(Box Blur) 概述 因为公司手游项目需求.须要一个适合手机平台的模糊效果,同一时候须要开放一个參数便于调节模糊值.我首先想到的就是ps里面的均值模糊. 查资料能够知道均值模糊是一种高速 ...

  3. Unity shader(CG) 写一个 散色、折射、反射、菲涅尔、gamma、简单后期屏幕特效

    http://www.lai18.com/content/506918.html 1.自生要求是很重要的,当然不是什么强迫工作之类的,而是自己有限的能力上不断的扩展兴趣上的内容. 2.用生活的眼光去发 ...

  4. 屏幕适配基础——了解:ppi、dpi、px、sp、dp

    做android开发绕不开的几个名词:ppi.dpi.px.sp.dp.那么它们的定义.区别和联系都是什么呢?这篇博客系统的做一个概述和总结. 1.基本概念 px:pixel,像素,电子屏幕上组成一幅 ...

  5. android 屏幕适配基础(1)

    1. 概念定义 寸/英寸:   1寸=3.333333厘米:1英寸=2.54厘米(屏幕尺寸以英寸为单位) 像素 :    像素是组成图象的最基本单元要素:点. 一个像素有多大呢?主要取决于显示器的分辨 ...

  6. 【Unity Shaders】使用Unity Render Textures实现画面特效——画面特效中的亮度、饱和度和对照度

    本系列主要參考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同一时候会加上一点个人理解或拓展. 这里是本书全部的插图. 这里是本书所需的代码 ...

  7. Unity Shader入门精要学习笔记 - 第12章 屏幕后处理效果

    建立一个基本的屏幕后处理脚本系统 屏幕后处理,顾名思义,通常指的是在渲染完整个场景得到屏幕图像后,再对这个图像进行一系列操作,实现各种屏幕特效.使用这种技术,可以为游戏画面添加更多艺术效果,例如景深. ...

  8. 开始VS 2012中LightSwitch系列的第3部分:我该选择哪一个屏幕模板

    [原文发表地址]  Beginning LightSwitch in VS 2012 Part 3: Screen Templates, Which One Do I Choose? [原文发表时间] ...

  9. 关于如何写UI及屏幕适配的一些技巧

    因为公司开启了一个新的iOS项目, 所以近期比较忙, 没有更新博客,今天打算总结一下关于UI布局及屏幕适配的一些实战技巧,尤其使用纯代码,会对提升效率及代码易于维护等方面有明显帮助,这里提到的没有使用 ...

随机推荐

  1. [ACM_数据结构] HDU 1166 敌兵布阵 线段树 或 树状数组

    #include<iostream> #include<cstdio> #include<memory.h> using namespace std; ]; //- ...

  2. Python3------装饰器详解

    装饰器 定义:本质是函数.(装饰其他函数)就是为其他函数添加附加功能 原则:1.不能修改被装饰的函数的源代码 2.不能修改被装饰的函数的调用方式 理解装饰器前提条件: 1.函数即"变量&qu ...

  3. C#使用MongoDb来存储文件

    近期在写一个小玩意,需要保存一些图片,以前我采用的是FTP或者直接数据库保存文件,用FTP来保存文件感觉比较麻烦,用数据库吧,还要改字段类型,修改代码,修改查询语句,懒得改. 以前看过mongonDb ...

  4. c#字典怎么获取第一个键值 List<对象>获取重复项,转成Dictionary<key,List<对象>>

    c#字典怎么获取第一个键值 Dictionary<string, int> dictionary = new Dictionary<string, int>(); dictio ...

  5. ProtoBuf序列化和反序列化方法

    最近公司需要将以前的协议全都改成ProtoBuf生成的协议,再将结构体打包和解包过程终于到一些问题 ,无法使用Marshal.SizeOf计算结构体大小,最后找了一下ProtoBuf的文档,可以用它自 ...

  6. WPF点滴(2) 创建单实例应用程序

    最近有同事问道在应用程序启动之后,再次双击应用程序,如何保证不再启动新的应用程序,而是弹出之前已经启动的进程,本质上这就是创建一个单实例的WPF应用程序.在VS的工程树中有一个App.xaml和App ...

  7. RabbitMQ - Start Up

    开始之前 rabbitmq是一个被广泛使用的消息队列,它是由erlang编写的,根据AMQP协议设计实现的. AMQP的主要特征是面向消息.队列.路由(包括点对点和发布/订阅).可靠性.安全. Rab ...

  8. Java_使用日志

    日志有什么用? 在实际开发中,不可能使用控制台输出所有数据,可以用日志把程序运行的过程记录下来,包括运行中出现的异常和BUG 当出现问题的时候,程序员可以去查看日志,从而能快速的找到问题所在. 一般来 ...

  9. 剑指offer四十九之把字符串转换成整数

    一.题目 将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数. 数值为0或者字符串不是一个合法的数值则返回0 二.思路 详见代码. 三.代码 public class Solution { ...

  10. (转)MySQL优化笔记(八)--锁机制超详细解析(锁分类、事务并发、引擎并发控制)

    当一个系统访问量上来的时候,不只是数据库性能瓶颈问题了,数据库数据安全也会浮现,这时候合理使用数据库锁机制就显得异常重要了. 原文:http://www.jianshu.com/p/163c96983 ...