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](三) ----- ...
随机推荐
- XPATH语法(一)
Xpath简介 XPath即为XML路径语言,它是一种用来确定XML(标准通用标记语言的子集)文档中某部分位置的语言.XPath基于XML的树状结构,有不同类型的节点,包括元素节点,属性节点和文本节点 ...
- LeetCode(51):N皇后
Hard! 题目描述: n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击. 上图为 8 皇后问题的一种解法. 给定一个整数 n,返回所有不同的 n 皇后问 ...
- 深度学习Bible学习笔记:第一章 前言
写在前面:请务必踏踏实实看书,结合笔记或视频来理解学习,任何技术,啃砖头是最扎实最系统的,为避免知识碎片化,切忌抛却书本的学习!!! 一 什么是深度学习 1 关于AI: AI系统必须具备从原始数据提取 ...
- java 动态代理(类型信息)
代理是基本的设计模式之一它为你提供额外的或不同的操作,而插入的用来代替"实际"对象的对象. package typeinfo; //: typeinfo/SimpleProxyDe ...
- bzoj2243树链剖分+区间合并
树链上区间合并的问题比区间修改要复杂,因为每一条重链在线段树上分布一般都是不连续的,所以在进行链上操作时要手动将其合并起来,维护两个端点值 处理时的方向问题:lca->u是一个方向,lca-&g ...
- 2018-2019-2 20165333 《网络对抗技术》 Exp5:MSF基础应用
2018-2019-2 20165333 <网络对抗技术> Exp5:MSF基础应用 实践内容(3.5分) 本实践目标是掌握metasploit的基本应用方式,重点常用的三种攻击方式的思路 ...
- jQuery插件实践之轮播练习(二)
所有文章搬运自我的个人主页:sheilasun.me 上一篇中学习了jQuery插件的写法,这篇该着手实现啦.首先明确一下轮播要具备哪些功能: 可以点击"向后"按钮向后翻页 可以点 ...
- [转] css自定义字体font-face的兼容和使用
@Font-face目前浏览器的兼容性: Webkit/Safari(3.2+) TrueType/OpenType TT (.ttf) .OpenType PS (.otf): Opera (10+ ...
- Eclipse-debug时提示absent line number information的解决办法
unable to install breakpoint in ...(file name) due to miss line number attributes. midify compliter ...
- HDU5730
cdq分治+FFT 转移:dp[i]=Σdp[i-j]*a[j](1<=j<=i)