【Unity3D】调整屏幕亮度、饱和度、对比度
1 屏幕后处理流程
调整屏幕亮度、饱和度、对比度,需要使用到屏幕后处理技术。因此,本文将先介绍屏幕后处理流程,再介绍调整屏幕亮度、饱和度、对比度的实现。
本文完整资源见→Unity3D调整屏幕亮度、饱和度、对比度。
屏幕后处理即:渲染完所有对象后,得到一张屏幕图像,对该屏幕图像进一步处理的过程称为屏幕后处理。屏幕后处理一般在 MonoBehaviour 生命周期 的 OnRenderImage 方法中进行,如下,src 是渲染完所有对象后的屏幕图像,dest 是经屏幕后处理得到的目标图像。如果用户想在不透明的 Pass 执行完毕后立即调用 OnRenderImage 方法,可以在 OnRenderImage 方法前面加上 [ImageEffectOpaque] 标签。
// [ImageEffectOpaque] // 在不透明的Pass执行完毕后立即调用OnRenderImage方法
void OnRenderImage(RenderTexture src, RenderTexture dest)
在 OnRenderImage 方法里,通常使用 Graphics.Blit 方法完成对纹理的处理,如下是常用的 Bilt 方法,source 是源纹理,dest 是目标纹理,mat 是进行屏幕后处理的材质,用户可以在该材质绑定的 Shader 中实现屏幕后处理特效。注意,屏幕后处理的 Shader 中必须包含名为 "_MainTex" 的纹理属性,用户在调用 Graphics.Blit 方法时会自动将 source 赋值给 Shader 中的 _MainTex 属性。
public static void Blit(Texture source, RenderTexture dest)
public static void Blit(Texture source, RenderTexture dest, Material mat, [Internal.DefaultValue("-1")] int pass)
public static void Blit(Texture source, Material mat, [Internal.DefaultValue("-1")] int pass)
另外,用户通过 CommandBuffer.DrawRenderer 和 Graphics.ExecuteCommandBuffer 也可以实现 Graphics.Blit 效果,详见案例:选中物体描边特效,主要流程如下:
CommandBuffer commandBuffer = new CommandBuffer();
RenderTexture tempTex = RenderTexture.GetTemporary(Screen.width, Screen.height, 0);
commandBuffer.SetRenderTarget(tempTex);
commandBuffer.ClearRenderTarget(true, true, Color.clear); // 设置模板清屏颜色为(0,0,0,0)
commandBuffer.DrawRenderer(renderer, effectMaterial); // renderer是物体的Render组件, effectMaterial是特效材质
Graphics.ExecuteCommandBuffer(commandBuffer);
// use tempTex
RenderTexture.ReleaseTemporary(tempTex); // 使用完tempTex后, 需要释放掉
在 Shader 中,用户也可以通过 GrabPass 抓取屏幕图像,详见案例:反射和折射。
2 亮度、饱和度、对比度
1)亮度
亮度表示颜色的明暗程度,亮度越高,颜色越亮,灰度值也越高。
2)饱和度
饱和度指色彩的鲜艳程度,也称色彩的纯度。饱和度取决于该色中含色成分和消色成分(灰色)的比例。含色成分越大,饱和度越大;消色成分越大,饱和度越小。纯的颜色都是高度饱和的,如鲜红,鲜绿。混杂上白色,灰色或其他色调的颜色,是不饱和的颜色,如绛紫,粉红,黄褐等。完全不饱和的颜色根本没有色调,如黑白之间的各种灰色。
3)对比度
对比度指一幅图像灰度反差的大小,即最大亮度与最小亮度之比。对比度越大,不同颜色之间的反差越大,黑白分明,对比度过大,图像会显得刺眼;对比度越小,不同颜色之间的反差越小,对比度过小,画面会显得灰蒙蒙。
3 代码实现
BrigSatuCont.cs
using UnityEngine;
[ExecuteInEditMode] // 编辑态可以查看脚本运行效果
[RequireComponent(typeof(Camera))] // 需要相机组件
public class BrigSatuCont : MonoBehaviour {
[Range(0.1f, 3.0f)]
public float brightness = 1.0f; // 亮度
[Range(0.1f, 3.0f)]
public float saturation = 1.0f; // 饱和度
[Range(0.1f, 3.0f)]
public float contrast = 1.0f; // 对比度
private Material material; // 材质
private void Start() {
material = new Material(Shader.Find("MyShader/BrightnessSaturationContrast"));
material.hideFlags = HideFlags.DontSave;
}
//[ImageEffectOpaque] // 在不透明的Pass执行完毕后立即调用OnRenderImage方法
void OnRenderImage(RenderTexture src, RenderTexture dest) {
if (material != null) {
material.SetFloat("_Brightness", brightness); // 设置亮度
material.SetFloat("_Saturation", saturation); // 设置饱和度
material.SetFloat("_Contrast", contrast); // 设置对比度
Graphics.Blit(src, dest, material);
} else {
Graphics.Blit(src, dest);
}
}
}
BrigSatuCont.Shader
Shader "MyShader/BrightnessSaturationContrast" { // 调整亮度、饱和度、对比度
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {} // 主纹理
_Brightness ("Brightness", Float) = 1 // 亮度
_Saturation("Saturation", Float) = 1 // 饱和度
_Contrast("Contrast", Float) = 1 // 对比度
}
SubShader {
Pass {
// 深度测试始终通过, 关闭深度写入
ZTest Always ZWrite Off
CGPROGRAM
#pragma vertex vert_img // 使用内置的vert_img顶点着色器
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex; // 主纹理
half _Brightness; // 亮度
half _Saturation; // 饱和度
half _Contrast; // 对比度
fixed4 frag(v2f_img i) : SV_Target { // v2f_img为内置结构体, 里面只包含pos和uv
fixed4 tex = tex2D(_MainTex, i.uv); // 纹理采样
fixed3 finalColor = tex.rgb * _Brightness; // 应用亮度_Brightness
fixed luminance = 0.2125 * tex.r + 0.7154 * tex.g + 0.0721 * tex.b; // 计算亮度
fixed3 luminanceColor = fixed3(luminance, luminance, luminance); // 饱和度为0、亮度为luminance的颜色
finalColor = lerp(luminanceColor, finalColor, _Saturation); // 应用饱和度_Saturation
fixed3 avgColor = fixed3(0.5, 0.5, 0.5); // 饱和度为0、亮度为0.5的颜色
finalColor = lerp(avgColor, finalColor, _Contrast); // 应用对比度_Contrast
return fixed4(finalColor, tex.a);
}
ENDCG
}
}
Fallback Off
}
说明: vert_img 是 Unity 内置的顶点着色器,v2f_img 是 Unity 内置的结构体变量,vert_img 和 v2f_img 的实现见→Shader常量、变量、结构体、函数。
运行效果:
1)调整亮度

2)调整饱和度

3)调整对比度

声明:本文转自【Unity3D】调整屏幕亮度、饱和度、对比度。
【Unity3D】调整屏幕亮度、饱和度、对比度的更多相关文章
- Android 播放电影时滑动屏幕调整屏幕亮度(转)
(转自:http://blog.csdn.net/piaozhiye/article/details/6544450) 发现有一些主流的播放器播放电影时可以通过滑动屏幕调整屏幕亮度,其实实现起来也很容 ...
- glsl计算sprite的亮度饱和度对比度
//glsl计算sprite的亮度饱和度对比度 #ifdef GL_ES precision mediump float; #endif uniform sampler2D u_texture; va ...
- 【转】Windows Phone 调整屏幕亮度的简单实现
之前看到以及其它应用都有调节屏幕亮度的功能,还以为MS有相关的API,就去MSDN找了下,但是怎么都找不到.今天突然想到做自定义MessageBox时,由于要突出弹出框部分,所以会改变LayoutRo ...
- Opencv学习笔记4:Opencv处理调整图片亮度和对比度
一.理论基础 在数学中我们学过线性理论,在图像亮度和对比度调节中同样适用,看下面这个公式: 在图像像素中其中: 参数f(x)表示源图像像素. 参数g(x) 表示输出图像像素. 参数a(需要满足a> ...
- Unity shader学习之屏幕后期效果之调整屏幕亮度,饱和度,对比度
Unity的屏幕后期处理效果,使用MonoBehaviour.OnRenderImage来实现. 转载请注明出处:http://www.cnblogs.com/jietian331/p/7228063 ...
- Mint linux中调整屏幕亮度的方法
/********************************************************************* * Author : Samson * Date ...
- c# 多种方法调整屏幕亮度
Github: https://github.com/CHNMaxGor/AjustScreenBrightness 方法一: 使用网上常说的 Gdi32.dll 下的 SetDeviceGammaR ...
- centos调整屏幕亮度
笔记本安装centos6.5后亮度无法通过键盘快捷键调节,可以通过安装软件来调节. 安装:yum install xgamma 设置亮度:xgamma -gamma n( 0.1 < n < ...
- C#调整图片亮度和对比度
BitmapSource bitmap = null; ; ; private void SetBrightness(int degree) { degree = degree * / ; Write ...
- 解决ubuntu无法调整和保存屏幕亮度的问题
整理自解决ubuntu无法调整和保存屏幕亮度的问题 ubuntu无法调整屏幕亮度,对笔记本来说很耗电,同时也很刺眼,因为它是默认以最大亮度来工作的. 所谓的调整,方法为下面的其中一种: 1.Fn+左右 ...
随机推荐
- 2023-04-17:设计一个包含一些单词的特殊词典,并能够通过前缀和后缀来检索单词。 实现 WordFilter 类: WordFilter(string[] words) 使用词典中的单词 wor
2023-04-17:设计一个包含一些单词的特殊词典,并能够通过前缀和后缀来检索单词. 实现 WordFilter 类: WordFilter(string[] words) 使用词典中的单词 wor ...
- 2023-02-19:请用go语言调用ffmepg,输出视频文件信息。
2023-02-19:请用go语言调用ffmepg,输出视频文件信息. 答案2023-02-19: 用 github.com/moonfdd/ffmpeg-go 这个库. 代码参考ffmpeg5入门教 ...
- 2022-02-13:k8s安装gitlab,yaml如何写?
2022-02-13:k8s安装gitlab,yaml如何写? 答案2022-02-13: yaml如下: apiVersion: apps/v1 kind: Deployment metadata: ...
- 2021-09-18:给定一个只包括 ‘(‘,‘)‘,‘{‘,‘}‘,‘[‘,‘]‘ 的字符串 s ,判断字符串是否有效。有效字符串需满足:左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合
2021-09-18:给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效.有效字符串需满足:左括号必须用相同类型的右括号闭合.左括号必须以正确的顺序闭合 ...
- Django4全栈进阶之路3 apps.py 文件
在 Django 4 中,每个应用(app)都需要定义一个 apps.py 文件,用于配置应用的基本信息,如应用的名称.显示名称.图标.默认路径.启动时需要执行的操作等.apps.py 文件是一个 P ...
- boot-admin 项目数据库缺省字段设计之最佳实践
数据库(Database)中的缺省字段(也称为默认字段),就是在一般情况下,每个数据表(Table)必须包含的字段(Field),这类字段用于满足特定的数据需求,字段值的填充或更改一般遵照一定的逻辑要 ...
- 在开发过程中使用git rebase还是git merge,优缺点分别是什么?
前言 在开发过程中,git rebase 和 git merge 都是常见的代码版本管理工具.它们都能够将分支合并到主分支,并且都有各自的优缺点. git merge git merge 是一种将两个 ...
- ES 数据没了?谁动了我的数据?
背景 我们在使用 Elasticsearch 的时候,可能会遇到数据"丢"了的情况.有可能是数据没成功写入 ES 集群,也可能是数据被误删了. 针对数据被误删,有没有好的解决办法呢 ...
- .NET周报 【5月第3期 2023-05-21】
国内文章 C# 实现 Linux 视频会议(源码,支持信创环境,银河麒麟,统信UOS) https://www.cnblogs.com/shawshank/p/17390248.html 信创是现阶段 ...
- ODOO升级可能遇到问题
a,找不到模块或视图不存在. 解决方案:查看是否将相应py文件加入到__init__文件中,或xml文件加入到manifest->data文件中. b, 找不到关联模块. 解决方案:这种一般要么 ...