Unity Shader-后处理:简单的颜色调整(亮度,饱和度,对比度)
好久没坚持写blog了,是时候开始撸一波新博文了!学习Unity有一段时间了,关于Shader的书也看了几本《Unity Shader入门精要》,《Unity 3D ShaderLab 开发实战详解》,开一个系列记录一下学习的心得笔记。原理就不多讲了,一篇一个实际Shader样例就好了。
貌似一开始关于shader的讲解都是diffuse,不过,我赶脚后处理貌似更简单,所以第一篇来一发简单后处理,屏幕的简单颜色校正--调整亮度,饱和度,对比度。
一.概念介绍
1.颜色模型的概念
1.1RGB颜色模型
1.2HSV颜色模型
1.3RGB颜色模型和HSV颜色模型的转化
2.亮度,饱和度,对比度,灰度的概念
2.1亮度
2.2饱和度
2.3对比度
2.4灰度
二.Unity屏幕后处理原理
1.OnRenderImage函数
- void OnRenderImage(RenderTexture sourceTexture,RenderTexture destTexture);
RenderTexture表示的是渲染纹理,我们渲染物体并不是仅仅渲染在屏幕空间,也可以将物体渲染到特定纹理上,也就是RenderTexture。sourceTexture就是我们渲染的场景图片,而destTexture是目标渲染纹理。我们可以在这个函数中进行相关的后处理效果,使用带有后处理效果shader的材质将场景内容重新渲染。
2.Graphics.Blit函数
- public static void Blit(Texture source,RenderTexture dest);
- public static void Blit(Texture source,RenderTexture dest, Material mat, int pass = -1);
- public static void Blit(Texture source,Material mat, int pass = -1);
source是源纹理,dest是目标纹理,当dest为null时,直接将源纹理拷贝到屏幕;mat是拷贝时使用的材质,也就是我们后处理时使用的材质,Unity会使用该材质将源纹理进行处理拷贝给目标纹理,pass是使用的材质shader所使用的pass,我们知道,一个shader中可能有多个pass,使用哪个pass进行处理就可以从该参数传入,当然,默认为-1时表示所有的pass都会执行。
三.后处理效果代码
1.脚本部分
- using UnityEngine;
- using System.Collections;
- //非运行时也触发效果
- [ExecuteInEditMode]
- //屏幕后处理特效一般都需要绑定在摄像机上
- [RequireComponent(typeof(Camera))]
- //提供一个后处理的基类,主要功能在于直接通过Inspector面板拖入shader,生成shader对应的材质
- public class PostEffectBase : MonoBehaviour {
- //Inspector面板上直接拖入
- public Shader shader = null;
- private Material _material = null;
- public Material _Material
- {
- get
- {
- if (_material == null)
- _material = GenerateMaterial(shader);
- return _material;
- }
- }
- //根据shader创建用于屏幕特效的材质
- protected Material GenerateMaterial(Shader shader)
- {
- if (shader == null)
- return null;
- //需要判断shader是否支持
- if (shader.isSupported == false)
- return null;
- Material material = new Material(shader);
- material.hideFlags = HideFlags.DontSave;
- if (material)
- return material;
- return null;
- }
- }
- using UnityEngine;
- using System.Collections;
- //继承自PostEffectBase
- public class ColorAdjustEffect : PostEffectBase {
- //通过Range控制可以输入的参数的范围
- [Range(0.0f, 3.0f)]
- public float brightness = 1.0f;//亮度
- [Range(0.0f, 3.0f)]
- public float contrast = 1.0f; //对比度
- [Range(0.0f, 3.0f)]
- public float saturation = 1.0f;//饱和度
- //覆写OnRenderImage函数
- void OnRenderImage(RenderTexture src, RenderTexture dest)
- {
- //仅仅当有材质的时候才进行后处理,如果_Material为空,不进行后处理
- if (_Material)
- {
- //通过Material.SetXXX("name",value)可以设置shader中的参数值
- _Material.SetFloat("_Brightness", brightness);
- _Material.SetFloat("_Saturation", saturation);
- _Material.SetFloat("_Contrast", contrast);
- //使用Material处理Texture,dest不一定是屏幕,后处理效果可以叠加的!
- Graphics.Blit(src, dest, _Material);
- }
- else
- {
- //直接绘制
- Graphics.Blit(src, dest);
- }
- }
- }
这样,我们的后处理脚本就完成了。涉及到以下几个知识点:
2.shader部分
- //shader的目录
- Shader "Custom/ColorAdjustEffect"
- {
- //属性块,shader用到的属性,可以直接在Inspector面板调整
- Properties
- {
- _MainTex ("Albedo (RGB)", 2D) = "white" {}
- _Brightness("Brightness", Float) = 1
- _Saturation("Saturation", Float) = 1
- _Contrast("Contrast", Float) = 1
- }
- //每个shader都有Subshaer,各个subshaer之间是平行关系,只可能运行一个subshader,主要针对不同硬件
- SubShader
- {
- //真正干活的就是Pass了,一个shader中可能有不同的pass,可以执行多个pass
- Pass
- {
- //设置一些渲染状态,此处先不详细解释
- ZTest Always Cull Off ZWrite Off
- CGPROGRAM
- //在Properties中的内容只是给Inspector面板使用,真正声明在此处,注意与上面一致性
- sampler2D _MainTex;
- half _Brightness;
- half _Saturation;
- half _Contrast;
- //vert和frag函数
- #pragma vertex vert
- #pragma fragment frag
- #include "Lighting.cginc"
- //从vertex shader传入pixel shader的参数
- struct v2f
- {
- float4 pos : SV_POSITION; //顶点位置
- half2 uv : TEXCOORD0; //UV坐标
- };
- //vertex shader
- //appdata_img:带有位置和一个纹理坐标的顶点着色器输入
- v2f vert(appdata_img v)
- {
- v2f o;
- //从自身空间转向投影空间
- o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
- //uv坐标赋值给output
- o.uv = v.texcoord;
- return o;
- }
- //fragment shader
- fixed4 frag(v2f i) : SV_Target
- {
- //从_MainTex中根据uv坐标进行采样
- fixed4 renderTex = tex2D(_MainTex, i.uv);
- //brigtness亮度直接乘以一个系数,也就是RGB整体缩放,调整亮度
- fixed3 finalColor = renderTex * _Brightness;
- //saturation饱和度:首先根据公式计算同等亮度情况下饱和度最低的值:
- fixed gray = 0.2125 * renderTex.r + 0.7154 * renderTex.g + 0.0721 * renderTex.b;
- fixed3 grayColor = fixed3(gray, gray, gray);
- //根据Saturation在饱和度最低的图像和原图之间差值
- finalColor = lerp(grayColor, finalColor, _Saturation);
- //contrast对比度:首先计算对比度最低的值
- fixed3 avgColor = fixed3(0.5, 0.5, 0.5);
- //根据Contrast在对比度最低的图像和原图之间差值
- finalColor = lerp(avgColor, finalColor, _Contrast);
- //返回结果,alpha通道不变
- return fixed4(finalColor, renderTex.a);
- }
- ENDCG
- }
- }
- //防止shader失效的保障措施
- FallBack Off
- }
四.效果展示
Unity Shader-后处理:简单的颜色调整(亮度,饱和度,对比度)的更多相关文章
- glsl计算sprite的亮度饱和度对比度
//glsl计算sprite的亮度饱和度对比度 #ifdef GL_ES precision mediump float; #endif uniform sampler2D u_texture; va ...
- Unity Shader后处理-搜索灰度效果
如U3D中Hierarchy面板下的搜索效果: 讲解分析: 1.这种PostEffect效果其实就是指Unity shader的后处理,即游戏中实现屏幕特效的常见方法.顾名思义屏幕后处理就是指在渲染完 ...
- unity shader 剔除指定的颜色
Shader "MyShader/PaintingBGTransparency" { Properties{ _MainTex("Base (RGB)", 2D ...
- Unity Shader入门精要学习笔记 - 第12章 屏幕后处理效果
建立一个基本的屏幕后处理脚本系统 屏幕后处理,顾名思义,通常指的是在渲染完整个场景得到屏幕图像后,再对这个图像进行一系列操作,实现各种屏幕特效.使用这种技术,可以为游戏画面添加更多艺术效果,例如景深. ...
- 【浅墨Unity3D Shader编程】之二 雪山飞狐篇:Unity的基本Shader框架写法&颜色、光照与材质
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/40955607 作者:毛星云(浅墨) ...
- 【转】《Unity Shader入门精要》冯乐乐著 书中彩图
为方便个人手机学习时候查阅,从网上转来这些彩图. 如属过当行为,联系本人删除. 勘错表 http://candycat1992.github.io/unity_shaders_book/unity_s ...
- Unity Shader入门精要学习笔记 - 第10章 高级纹理
转载自 冯乐乐的 <Unity Shader入门精要> 立方体纹理 在图形学中,立方体纹理是环境映射的一种实现方法.环境映射可以模拟物体周围的环境,而使用了环境映射的物体可以看起来像镀了层 ...
- Unity Shader入门精要之 screen post-processing effect
本篇记录了学习Unity Shader入门精要的屏幕后处理的一些知识点. OnRenderImage(RenderTexture src, RenderTexture dest) 以上函数是Unity ...
- 【Unity Shader】(十) ------ UV动画原理及简易实现
笔者使用的是 Unity 2018.2.0f2 + VS2017,建议读者使用与 Unity 2018 相近的版本,避免一些因为版本不一致而出现的问题. [Unity Shader](三) ----- ...
随机推荐
- 使用console进行 性能测试 和 计算代码运行时间
原文:http://www.tuicool.com/articles/JrARVjv 对于前端开发人员,在开发过程中经常需要监控某些表达式或变量的值,如果使用用 debugger 会显得过于笨重,最常 ...
- 洛谷 P4427 求和
传送门啦 思路: 开始不肿么容易想到用倍增,但是想到需要求 $ Lca $ ,倍增这种常数小而且快的方法就很方便了.求 $ Lca $ 就是一个最普通的板子.那现在考虑怎么求题目中的结果. 树上差分可 ...
- mysql 5.6 在线 DDL
原文链接地址:http://seanlook.com/2016/05/24/mysql-online-ddl-concept/ 做MySQL的都知道,数据库操作里面,DDL操作(比如CREATE,DR ...
- python 全栈开发,Day55(jQuery的位置信息,JS的事件流的概念(重点),事件对象,jQuery的事件绑定和解绑,事件委托(事件代理))
一.jQuery的位置信息 jQuery的位置信息跟JS的client系列.offset系列.scroll系列封装好的一些简便api. 一.宽度和高度 获取宽度 .width() 描述:为匹配的元素集 ...
- java远程工具类
package com.zdz.httpclient; import java.io.BufferedReader; import java.io.IOException; import java.i ...
- Ext.Js核心函数( 三)
ExtJs 核心函数简介 1.ExtJs提供的常用函数2.get.fly.getCmp.getDom.getBody.getDoc3.query函数和select函数4.encode函数和decode ...
- Asp.NetWebForm的控件属性
一:GridView: 1.绑定ID 的值:DataKeyNames="Id", 2.自动产生列的意思:AutoGenerateColumns 3.如何注册脚本:ClientScr ...
- 行为型模式之Command模式
命令模式将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化, 并且可以对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能. 概念描述 把命令的调用者与执行者分开,使双方不必关心对方是 ...
- KNN分类算法补充
KNN补充: 1.K值设定为多大? k太小,分类结果易受噪声点影响:k太大,近邻中又可能包含太多的其它类别的点. (对距离加权,可以降低k值设定的影响) k值通常是采用交叉检验来确定(以k=1为基准) ...
- 编译linux内核以及添加系统调用的全过程
参考链接: https://www.zybuluo.com/hakureisino/note/514321# 北京邮电大学操作系统实验: https://wenku.baidu.com/view/6d ...