Unity Shader 屏幕后效果——颜色校正
屏幕后效果指的是,当前整个场景图已经渲染完成输出到屏幕后,再对输出的屏幕图像进行的操作。
在Unity中,一般过程通常是:
1.建立用于处理效果的shader和临时材质,给shader脚本传递需要控制的参数和变量
2.利用OnRenderImage函数抓取当前屏幕渲染纹理
OnRenderImage(RenderTexture source, RenderTexture destination){ }
第一个参数为处理前纹理,第二个为最终显示纹理
3.在OnRenderImage函数中调用Graphics.Blit方法对抓取的纹理进行具体的后期操作
Graphics.Blit(source, destination, material,-1);
material为需要处理的材质,-1为参数pass的默认值,表示对shader中所有的pass依次调用,这里也可以省略
为此,首先可以提前建立一个基类ScreenEffectBase,主要用于检查Shader并创建临时材质:
脚本如下:
using UnityEngine; [ExecuteInEditMode]
//屏幕后处理效果主要是针对摄像机进行操作,需要绑定摄像机
[RequireComponent(typeof(Camera))]
public class ScreenEffectBase : MonoBehaviour
{
public Shader shader;
private Material material;
protected Material Material
{
get
{
material = CheckShaderAndCreatMat(shader, material);
return material;
}
} //用于检查并创建临时材质
private Material CheckShaderAndCreatMat(Shader shader, Material material)
{
Material nullMat = null;
if (shader != null)
{
if (shader.isSupported)
{
if (material && material.shader == shader){ }
else
{
material = new Material(shader){ hideFlags = HideFlags.DontSave };
}
return material;
}
}
return nullMat;
}
}
之后创建的屏幕后处理效果的控制脚本都可以继承自该基类,例如我们创建关于基本颜色校正的控制脚本:
using UnityEngine; public class ColorCorrectionCtrl : ScreenEffectBase
{
private const string _Brightness = "_Brightness";
private const string _Saturation = "_Saturation";
private const string _Contrast = "_Contrast"; [Range(, )]
public float brightness = 1.0f;
[Range(, )]
public float saturation = 1.0f;
[Range(, )]
public float contrast = 1.0f; private void OnRenderImage(RenderTexture source, RenderTexture destination)
{
if (Material!=null)
{
Material.SetFloat(_Brightness, brightness);
Material.SetFloat(_Saturation, saturation);
Material.SetFloat(_Contrast, contrast); Graphics.Blit(source, destination, Material);
}
else
Graphics.Blit(source, destination);
}
}
其中,brightness,saturation,contrast分别为调整参数——亮度,饱和度和对比度,_Brightness,_Saturation,_Contrast为之后对应的shader中需要相应定义的属性参数。
这里利用构建的材质Material对shader的属性赋值并调用Graphics.Blit进行屏幕后效果的处理。
具体实现颜色校正的shader如下:
Shader "MyUnlit/ColorCorrection"
{
Properties
{
//这里的参数主要用于展示在材质面板中进行调节,但因为这次是临时创建的材质,参数都已经放在了C#脚本中调整,因此相对应的参数都可以省略
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" } Pass
{
//OnRenderImage的调用可能会发生在渲染透明物体之前,为了不影响之后透明物体的渲染,需要:开启深度测试+双面渲染+关闭深度写入
ZTest always
Cull off
ZWrite off CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fog #include "UnityCG.cginc" struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
}; struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS()
float4 vertex : SV_POSITION;
}; sampler2D _MainTex;
half _Brightness;
half _Saturation;
half _Contrast; v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
//因为是临时创建的材质,这里不需要对纹理进行任何变换操作(无可操作的材质面板),直接传递即可,_MainTex_ST也不需要定义
o.uv = v.uv;
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
} fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv); //亮度计算直接叠加
fixed3 color = col.rgb*_Brightness; //饱和度和灰度有关,先计算最低灰度系数下的图像,随后对原始的图像进行插值操作
fixed3 gray = fixed3(0.2125, 0.7154, 0.0721);
//点积得到最低灰度值,构成最低灰度图像
fixed minGray = dot(gray, col.rgb);
fixed3 grayColor = fixed3(minGray, minGray, minGray);
//对灰度图像和原始图像插值操作以得到最终系数的显示图像
color = lerp(grayColor, color, _Saturation); //对比度效果类似,先计算最低对比度图像,即(0.5,0.5,0.5),随后插值操作
fixed3 minContrast = fixed3(0.5, 0.5, 0.5);
color = lerp(minContrast, color, _Contrast); //得到所有处理完成后的图像颜色,但alpha保持不变
fixed4 finColor = fixed4(color, col.a); UNITY_APPLY_FOG(i.fogCoord, finColor);
return finColor;
}
ENDCG
}
}
//关闭回调
fallback off
}
效果如下(随便调的不用在意~):



Unity Shader 屏幕后效果——颜色校正的更多相关文章
- Unity Shader 屏幕后效果——边缘检测
关于屏幕后效果的控制类详细见之前写的另一篇博客: https://www.cnblogs.com/koshio0219/p/11131619.html 这篇主要是基于之前的控制类,实现另一种常见的屏幕 ...
- Unity Shader 屏幕后效果——全局雾
Unity内置的雾效需要在每个shader中分别编写,造成了极大的不便.这里利用屏幕后处理产生可单独控制且自由度更高的雾效. 屏幕后雾效的本质在于,通过深度纹理重构出每个像素在世界空间中的位置,根据得 ...
- Unity Shader 屏幕后效果——高斯模糊
高斯模糊是图像模糊处理中非常经典和常见的一种算法,也是Bloom屏幕效果的基础. 实现高斯模糊同样用到了卷积的概念,关于卷积的概念和原理详见我的另一篇博客: https://www.cnblogs.c ...
- Unity Shader 屏幕后效果——景深
景深效果的原理是,在摄像机的近裁剪平面和远裁剪平面之间可以设置一个焦距,在这个距离所在的平面上的物体最为清晰,而这个距离之前或之后的物体成像是一种模糊状态(根据距离逐渐模糊,最终达到最为模糊的状态). ...
- Unity Shader 屏幕后效果——Bloom外发光
Bloom的原理很简单,主要是提取渲染图像中的亮部区域,并对亮部区域进行模糊处理,再与原始图像混合而成. 一般对亮部进行模糊处理的部分采用高斯模糊,关于高斯模糊,详见之前的另一篇博客: https:/ ...
- Unity Shader 屏幕后效果——摄像机运动模糊(速度映射图实现)
速度映射图主要是为了得到每个像素相对于前一帧的运动矢量,其中一种方法是使用摄像机的深度纹理来推导. 推导过程如下: 先由深度纹理逆推出NDC(归一化的设备坐标)下的顶点坐标,利用VP矩阵(视角*投影矩 ...
- Unity Shader实现描边效果
http://gad.qq.com/article/detail/28346 描边效果是游戏里面非常常用的一种效果,一般是为了凸显游戏中的某个对象,会给对象增加一个描边效果.本篇文章和大家介绍下利用S ...
- Unity Shader 之 透明效果
透明效果 透明效果一般有两种实现方法: 第一种,使用透明度测试(Alpha Test) 第二种,使用透明度混合(Alpha Blending) 透明度测试和透明度混合机制: 透明度测试(Alpha T ...
- Unity实现屏幕抖动效果(通过Camera Viewpoint实现)
由于游戏死亡时一般都需要屏幕抖一下下. 所以百度了下相关写法,发现方法很多~~~ 找来找去,找到个简单粗暴地,啥都不需要,一个脚本拖动到Camera上就可以了 略微修改了一点点,share一下 usi ...
随机推荐
- C Shell中的变量数组
今天刚刚在看一点C Shell的内容,发现一个挺好玩的东西!就是环境变量可以像数组那样来设置!具体设置语法如下: set variable=(element1 element2 ...) //注意元素 ...
- UVa 11400 Lighting System Design(DP 照明设计)
意甲冠军 地方照明系统设计 总共需要n不同类型的灯泡 然后进入 每个灯电压v 相应电压电源的价格k 每一个灯泡的价格c 须要这样的灯泡的数量l 电压低的灯泡能够用电压高的灯泡替换 ...
- Robot Framework 快速入门_中文版
目录 介绍 概述 安装 运行demo 介绍样例应用程序 测试用例 第一个测试用例 高级别测试用例 数据驱动测试用例 关键词keywords 内置关键词 库关键词 用户定义关键词 变量 定义变量 使用变 ...
- c# 守护进程,WPF程序自守护
原文:c# 守护进程,WPF程序自守护 版权声明:本文为博主原创文章,转载请注明出处. https://blog.csdn.net/lwwl12/article/details/79035246 如何 ...
- 如何完全备份android在系统system分区和data分
安德鲁斯系统备份是非常的情况下,可以使用.下面的这个python脚本.它可以用来备份整个data分:所有data分区的文件和文件夹打包data.zip.并产生recovery专用edify脚本upda ...
- Converter
public class ImgPathConvert : IValueConverter { public object Convert(object value, Type targetType, ...
- Rust这种新型的语言注定火不起来,功能太强大(特性太多),还不如用成熟稳定强大的C/C++,而且生态不行、所以恶性循环
这种新型的语言注定火不起来,功能太强大(特性太多),还不如用成熟稳定强大的C/C++,,而Golang足够简单,入门快,编译快,性能也强悍,解决了服务端开发人员的痛点,,注定被大多数人接受... go ...
- 【Linux】查看物理CPU个数、核数、逻辑CPU个数
①物理cpu数:主板上实际插入的cpu数量,可以数不重复的 physical id 有几个(physical id) cat /proc/cpuinfo| grep "physical id ...
- 《芒果TV》UWP版利用Windows10通用平台特性,率先支持Xbox One平台
在Windows开发者中心开放提交Xbox平台应用之后,<芒果TV>UWP版迅速更新v3.1.2版,通过升级兼容目标,利用Windows10通用平台特性,率先覆盖Xbox平台用户. 芒果T ...
- php 如何利用 soap调用.Net的WebService asmx文件
原文:php 如何利用 soap调用.Net的WebService asmx文件 最近,帮一个同行测试用.net写的WebService接口,C#调用通过,现在需要测试一下php版本对它的调用,经过各 ...