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

温湿度传感器联网方案选型避坑指南:有线/WiFi/蜂窝/LoRa实战对比 温湿度监测是工业物联网的基础场景,其联网方案选择本质是通信可靠性、部署环境适配性与全生命周期成本的综合权衡。从物理层原理看,有线依赖电气特性抗干扰,WiFi受限于2.4GHz信道拥塞与信号衰减,蜂窝依托授权频段但受基站覆盖与SIM管理制约,LoRa则以扩频技术换取超低功耗和远距离,却需自建网络与精细信道规划。技术价值体现在数据连续性(如冷链审计)、免维护周期(如农业大棚)和电磁鲁棒性(如食品产线)。典型应用场景包括地下停车场(有线唯一可行)、老式楼宇(WiFi需破解DHCP与WPA3兼容陷阱)、广域分散点位 阅读详情

本系列主要参考《Unity Shaders and Effects Cookbook》一书(感谢原书作者),同时会加上一点个人理解或拓展。

这里是本书所有的插图。这里是本书所需的代码和资源(当然你也可以从官网下载)。

========================================== 分割线 ==========================================



写在前面


通过上一篇我们建立了一个简化的屏幕特效系统,在这一篇,我们开始学习创建更复杂的像素操作来实现一些在当代游戏中常见的屏幕特效。


使用屏幕特效来调整游戏的整体色彩是非常重要的,这给了设计师控制游戏最后全貌的能力。比如,通过颜色调整条来调整游戏最终画面的红蓝绿三色的密度,或者通过添加一定的色调使整个屏幕看起来像是老电影那样的效果。


这篇文章里,我们将会更多地学习关于调整图像颜色方面的内容。也就是,亮度、饱和度和对比度。学习这些调整颜色的方法可以让我们对屏幕特效有一个很好的理解。



实现


这一篇很多代码是建立在上一篇的基础上,所以很多代码不用写啦~

  1. 创建一个新的脚本,命名为BSC_ImageEffect;
  2. 创建一个新的Shader,命名为BSC_Effect;
  3. 把上一篇中的C#代码复制到第一步中创建的脚本中,我们只需要关注亮度、饱和度和对比度效果的运算;
  4. 把上一篇中的Shader代码复制到第二步中创建的Shader中;
  5. 把新的脚本添加到Camera上,并使用新的Shader给脚本中的Cur Shader赋值;
  6. 创建一个新的场景,命名为BSC_Effect。添加一个平行光,三个球体,以及一个平面。创建4个新材质,使用自带的Specular Shader即可,任意选择四种颜色为它们赋值,这可以使我们更好地检验我们的画面特效。最后,把4个材质赋给球体和平面。

最后,你会得到类似于下面的效果:




实现


由于我们之前的代码已经完成了建立一个基本的画面特效所需的核心操作,现在我们只要完成亮度、饱和度和对比度计算的代码即可。

首先,我们来完成Shader代码。
  1. 添加亮度、饱和度和对比度对应的新的Properties,我们要保留_MainTex属性,这是因为在创建画面特效时,该属性就是脚本传递给我们的render texture。
    [plain]  view plain  copy
     print ?
    1. Properties {  
    2.     _MainTex ("Base (RGB)", 2D) = "white" {}  
    3.     _BrightnessAmount ("Brightness Amount", Range(0.0, 2.0)) = 1.0  
    4.     _SaturationAmount ("Saturation Amount", Range(0.0, 1.0)) = 1.0  
    5.     _ContrastAmount ("Contrast Amount", Range(0.0, 1.0)) = 1.0  
    6. }  

  2. 和以前一样,在CGPROGRAM中建立和上述Properties之间的联系,创建对应的变量:
    [plain]  view plain  copy
     print ?
    1. SubShader {  
    2.     Pass {  
    3.         CGPROGRAM  
    4.         #pragma vertex vert_img  
    5.         #pragma fragment frag  
    6.           
    7.         #include "UnityCG.cginc"  
    8.           
    9.         uniform sampler2D _MainTex;  
    10.         fixed _BrightnessAmount;  
    11.         fixed _SaturationAmount;  
    12.         fixed _ContrastAmoun  

  3. 现在,我们需要创建操作来进行真正的亮度、饱和度和对比度的计算。在frag函数上面创建下面的函数:
    [plain]  view plain  copy
     print ?
    1. float3 ContrastSaturationBrightness (float3 color, float brt, float sat, float con) {  
    2.     // Increase or decrease these values to  
    3.     // adjust r, g and b color channels separately  
    4.     float avgLumR = 0.5;  
    5.     float avgLumG = 0.5;  
    6.     float avgLumB = 0.5;  
    7.       
    8.     // Luminance coefficients for getting luminance from the image  
    9.     float3 LuminanceCoeff = float3 (0.2125, 0.7154, 0.0721);  
    10.       
    11.     // Operation for brightmess  
    12.     float3 avgLumin = float3 (avgLumR, avgLumG, avgLumB);  
    13.     float3 brtColor = color * brt;  
    14.     float intensityf = dot (brtColor, LuminanceCoeff);  
    15.     float3 intensity = float3 (intensityf, intensityf, intensityf);  
    16.       
    17.     // Operation for saturation  
    18.     float3 satColor = lerp (intensity, brtColor, sat);  
    19.       
    20.     // Operation for contrast  
    21.     float3 conColor = lerp (avgLumin, satColor, con);  
    22.       
    23.     return conColor;  
    24. }  

    解释:这个函数的第一个参数是当前的render texture的某个像素;其他参数则是用于整体调整颜色,这些变量会通过后面的脚本传递给Shader。函数一开始,声明了一些常量,它们被用于定义一个最基本的颜色值,以便和修改后的进行比较。

    书上讲这个函数的实现的地方比较含糊不清,看不懂。我按自己的理解解释一下。这其实是一个叠加的过程:先计算当前亮度值下的像素,再在此基础上计算当前饱和度值下的像素,最后再在此基础上计算当前对比度下的像素,并输出:
    —— 当前亮度值下的像素是通过使用render texture上原始的像素乘以亮度值实现的,这很好理解,brt越大(可以大于1),图像越偏向白色,也就越亮。
    —— 计算当前饱和度值下的像素,需要使用lerp函数。其中,lerp的右边界值就是上一步得到的像素值,而左边界值是当前亮度下饱和度最低的像素值。计算方法是在当前亮度的基础上,点乘LuminanceCoeff常量系数。这些系数是基于CIE颜色匹配函数的,也是业界公认的标准。最后,sat参数在两者之间进行线性插值。sat越大(可以大于1),brtColor的份重越大。
    —— 计算当前对比度下的像素是类似的过程,同样使用lerp函数。其中,lerp的右边界是上一步得到的像素值,左边界值是对比度最低的像素值,这里使用了常量avgLumin。最后,con参数在两者之间进行线性插值。con越大(可以大于1),satColor的份重越大。

  4. 最后,我们需要稍微修改下frag函数,使得它可以逐像素处理render texture中的每个像素,然后再重新输出,返回给脚本:
    [plain]  view plain  copy
     print ?
    1. fixed4 frag(v2f_img i) : COLOR {  
    2.     //Get the colors from the RenderTexture and the uv's  
    3.     //from the v2f_img struct  
    4.     fixed4 renderTex = tex2D(_MainTex, i.uv);  
    5.       
    6.     //Apply the brightness, saturation, contrast operations  
    7.     renderTex.rgb = ContrastSaturationBrightness (renderTex.rgb, _BrightnessAmount, _SaturationAmount, _ContrastAmount);  
    8.       
    9.     return renderTex;  
    10. }  


下面是编写脚本。我们需要在脚本中添加新的代码,以便可以向Shader发送合适的数据信息:
  1. 首先添加合适的变量来控制亮度、饱和度和对比度:
    [plain]  view plain  copy
     print ?
    1. #region Variables  
    2. public Shader curShader;  
    3. public float brightnessAmount = 1.0f;  
    4. public float saturationAmount = 1.0f;  
    5. public float contrastAmount = 1.0f;  
    6.   
    7. private Material curMaterial;  
    8. #endregion  

  2. 然后,在OnRenderImage函数中,将新的值传递给Shader:
    [plain]  view plain  copy
     print ?
    1. void OnRenderImage (RenderTexture sourceTexture, RenderTexture destTexture){  
    2.     if (curShader != null) {  
    3.         material.SetFloat("_BrightnessAmount", brightnessAmount);  
    4.         material.SetFloat("_SaturationAmount", saturationAmount);  
    5.         material.SetFloat("_ContrastAmount", contrastAmount);  
    6.           
    7.         Graphics.Blit(sourceTexture, destTexture, material);  
    8.     } else {  
    9.         Graphics.Blit(sourceTexture, destTexture);  
    10.     }  
    11. }  

  3. 最后,我们只需要在函数中,确保各变量的范围即可。这些范围可以根据需要任意设置:
    [plain]  view plain  copy
     print ?
    1. // Update is called once per frame  
    2. void Update () {  
    3.     brightnessAmount = Mathf.Clamp(brightnessAmount, 0.0f, 2.0f);  
    4.     saturationAmount = Mathf.Clamp(saturationAmount, 0.0f, 2.0f);  
    5.     contrastAmount = Mathf.Clamp(contrastAmount, 0.0f, 3.0f);  
    6. }  

完成后,返回Unity。我们这时可以在面板中更改亮度、饱和度和对比度了。下面的图显示了它的结果:
  



解释


类似这样的屏幕特效对于得到高质量的游戏画面是非常重要的,它们允许你调整游戏的最终画面而不需要去编辑场景中所有的材质。
c#处理图片rgb、伽马、饱和度、黑白 传入为图像流,输出为image /// /// 图像调整(色彩、亮度、对比度、伽马) /// /// 原始图 /// r增量(-255至255) /// g增量(-255至255) /// b增量(-255至255) /// 亮度(-255至255) /// 对 阅读详情

相关推荐

【Unity Shaders】使用Unity Render Textures实现画面特效——画面特效中的类似Photoshop的基本混合模式

本系列主要参考《Unity Shaders and Effects Cookbook》一书(感谢原书作者),同时会加上一点个人理解或拓展。这里是本书所有的插图。这里是本书所需的代码和资源(当然你也可以从官网下载)。========================================== 分割线 ==========================================写在前面

candycat 1万+

【Unity3D】调整屏幕亮度、饱和度、对比度

在 OnRenderImage 方法里,通常使用 Graphics.Blit 方法完成对纹理的处理,如下是常用的 Bilt 方法,source 是源纹理,dest 是目标纹理,mat 是进行屏幕后处理的材质,用户可以在该材质绑定的 Shader 中实现屏幕后处理特效。用户通过 CommandBuffer.DrawRenderer和Graphics.ExecuteCommandBuffer也可以实现Graphics.Blit效果。在Shader中,用户也可以通过 GrabPass抓取屏幕图像。

little_fat_sheep 4213

Unity URP 7.7.1实战:5分钟实现自定义扭曲特效

屏幕后处理是游戏开发中实现视觉特效的核心技术,它通过对渲染完成的图像进行二次处理来增强画面表现力。其原理是在渲染管线的最后阶段,通过着色器对屏幕空间中的每个像素进行采样和计算,从而改变最终输出。这项技术的价值在于能以较低的性能开销,实现诸如热浪、冲击波、能量护盾等极具表现力的视觉效果,广泛应用于各类游戏和交互式应用中。在Unity的Universal Render Pipeline中,实现自定义后处理需要遵循其模块化设计,通过创建Renderer Feature和Render Pass来插入自定义渲染逻辑。

weixin_34008933的博客 696

C# Graphics中有关绘图质量的几个Mode

  一、CompositingMode 获取一个值,该值指定如何将合成图像绘制到此 Graphics。复合模式确定从源映像的像素是覆盖(SourceCopy)还是组合(SourceOver, 需要使用半透明、混合叠加效果时使用)使用背景像素。默认值为 SourceOver。 该属性适用于 适用于.NET Framework 4.7.2, 4.7.1, 4.7, 4.6.2, 4.6.1, 4...

weixin_34416649的博客 1375

Unity游戏开发:Wizard Spells Pack魔法特效资源包深度使用与优化指南

在Unity游戏开发中,粒子系统是实现技能特效、环境交互等视觉反馈的核心技术组件。其原理是通过程序化生成和控制大量微小图像(粒子),模拟火焰、烟雾、魔法等动态效果。这项技术的价值在于能以较低的性能开销创造出丰富的视觉表现,是提升游戏沉浸感和打击感的关键。在ARPG、MMO、卡牌对战等各类游戏中,华丽的技能特效直接影响玩家的操作体验与游戏品质。对于独立开发者或中小团队而言,从零制作一套风格统一、性能优良的特效体系挑战巨大。因此,集成高质量的第三方特效资源包(Asset Pack)成为高效开发的常见实践。本文将

dht91597的博客 333

Unity特效性能优化实战:从设计到渲染的全流程指南

在实时渲染领域,性能优化是保障应用流畅运行的核心技术。其原理在于平衡CPU、GPU与内存资源,通过减少绘制调用、控制顶点数量与优化填充率来提升帧率。这项技术的价值在于,它能让复杂的视觉特效在各种硬件平台上稳定呈现,是游戏与交互应用开发的关键。在Unity引擎中,特效系统是性能消耗的主要来源之一,尤其涉及粒子系统、复杂着色器与高分辨率纹理时。本文聚焦于Unity特效资源包的全生命周期优化,系统阐述了如何通过分层设计、纹理压缩、着色器简化与对象池等工程实践,在移动端等性能受限场景下,实现视觉震撼与运行效率的平衡

weixin_33910385的博客 407

【Unity Shaders】使用Unity Render Textures实现画面特效——画面.

本系列主要参考《Unity Shaders and Effects Cookbook》一书(感谢原书作者),同时会加上一点个人理解或拓展。 这里是本书所有的插图。这里是本书所需的代码和资源(当然你也可以从官网下载)。 ========================================== 分割线 ==============================

feixiangdixiaoniao的专栏 710

C# 无损修改图像色相、饱和度、亮度

由于一个项目需要,调节图片的亮度,开始使用遍历图片每一个像素,并修改图像的RGB值,发现修改后无法恢复到原来图像。在网上查了一些资料,发现了强大的MagickImage,给大家分享一下,希望对大家有所帮助。

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

本系列主要參考《Unity Shaders and Effects Cookbook》一书(感谢原书作者),同一时候会加上一点个人理解或拓展。这里是本书全部的插图。这里是本书所需的代码和资源(当然你也能够从官网下载)。========================================== 切割线 ==========================================...

weixin_33692284的博客 245

Unity锐化效果功能

这是一个测试场景。其中的有一些粒子效果展示。也有相机锐化效果的。效果图在博客:https://blog.youkuaiyun.com/KiTok/article/details/80418981

Unity Shader - 后处理:简单的颜色调整(亮度,饱和度,对比度)

我们在做游戏的时候,虽然现在有了Unity等引擎,不用我们自己处理一些繁琐的东西,但是不管怎么样,最后显示在屏幕上的还是一些RGB的像素信息,了解这些基本的概念,肯定对我们做游戏有更大的帮助。

【Unity Shaders】使用Unity Render Textures实现画面特效——画面特效中的类似Photoshop的基本混合模式...

本系列主要参考《Unity Shaders and Effects Cookbook》一书(感谢原书作者),同时会加上一点个人理解或拓展。这里是本书所有的插图。这里是本书所需的代码和资源(当然你也可以从官网下载)。========================================== 分割线==========================================写在...

weixin_33786077的博客 649

Nvidia Isaac Sim安装与配置 入门教程 2024(2)

Isaac Sim 安装和配置教程将指导用户完成从下载软件到设置和运行仿真的全过程。教程内容包括安装必要的依赖项、配置系统环境、配置Omniverse环境以及调试和优化仿真环境的步骤。通过详细的操作步骤和图文并茂的说明,用户可以快速上手 Isaac Sim,构建出高质量的机器人仿真环境,实现其研究和应用目标。

m0_56661101的博客 2万+

【Unity Shaders】使用Unity Render Textures实现画面特效——画面特效中的相似Photoshop的基本混合模式...

本系列主要參考《Unity Shaders and Effects Cookbook》一书(感谢原书作者),同一时候会加上一点个人理解或拓展。这里是本书全部的插图。这里是本书所需的代码和资源(当然你也能够从官网下载)。========================================== 切割线 ==========================================...

weixin_34390996的博客 213

PCIe Gen4眼图测试实战:如何用示波器快速定位信号完整性问题(附避坑指南)

本文详细解析了PCIe Gen4眼图测试中的信号完整性诊断方法,通过示波器操作技巧和实战案例,帮助工程师快速定位抖动、反射等信号问题。特别针对眼图闭合、阻抗失配等常见问题提供了避坑指南和解决方案,提升高速信号调试效率。

weixin_29230773的博客 372

用matlab编程求矩阵的极大无关组,向量组极大无关组表示问题

已知向量组T:Eqn11.gif (3.16 KB, 下载次数: 1)2013-10-21 19:19 上传.(1) 求向量组T的秩,并判断向量组T的相关性;(2) 求T的极大线性无关组;(3) 将其余的向量用所求的极大线性无关组线性表示。程序:>> A=[1 1 3 2;-1 1 -1 3;5-2 8 9;-1 3 1 7]>> r=rank(A)>> A1=...

weixin_35094083的博客 7386

Crest Ocean Render 终极指南:Unity 高性能水体渲染深度解析

Crest Ocean Render 是 Unity 引擎中领先的实时海洋渲染解决方案,专为游戏开发者和视觉艺术家设计。这个高级水体系统通过创新的几何位移技术和多层级渲染管线,实现了电影级的海面视觉效果。不同于传统的水体着色器,Crest 采用基于 GPU 的波浪模拟和动态 LOD 系统,能够在保持高性能的同时渲染出真实感极强的海洋场景。 ## 技术架构深度剖析 ### 波浪模拟引擎的核心原理

gitblog_00307的博客 405

5-DOF机械臂课程设计(一)之正逆运动学

文章目录基本要求基本概念关节坐标系的建立正运动学求解DH参数表的建立逆运动学求解多解下解的选取源码下载后续 基本要求 ​ 开发上位机程序,要求有良好的界面,能提供关节空间下和笛卡尔坐 标下表示的目标位姿点和中间若干经过点的输入功能,进行轨迹规划, 并控制机械臂沿轨迹运动,最终完成目标抓取的任务。 基本概念 连杆长度 :2个相邻关节轴线之间的距离 连杆扭角 :2个相邻关节轴线之间的角度 连杆偏距 :2个关节坐标系的X轴之间的距离 关节角度 :关节变量 计算时需要加初始角度偏移 关节坐标系的建立 ​ 根据《机

Rosen的博客 5857

Unity科幻特效插件Sci-Fi Effects:模块化设计与性能优化实战

在游戏开发中,视觉特效是提升沉浸感的关键技术,其核心在于通过粒子系统、着色器编程和渲染管线实现动态视觉效果。从原理上看,特效系统通过模拟物理现象(如能量流动、爆炸冲击)和光学特性(如透明度、发光边缘)来创造逼真体验,其技术价值在于显著降低美术与程序开发门槛,提升内容生产效率。在应用场景上,科幻类游戏、虚拟现实项目以及影视动画预演等领域对高质量特效需求尤为迫切。本文以Unity资产商店中的Sci-Fi Effects插件为例,深入解析其模块化架构与多管线支持特性,并重点探讨了如何通过对象池、LOD和着色器优化

weixin_34025051的博客 406

C#实战:如何用HslCommunication快速搞定三菱FX5U PLC通讯(附完整代码)

本文详细介绍了如何利用HslCommunication库在C#环境中快速实现与三菱FX5U PLC的通讯。通过实战代码演示,从环境搭建、建立连接、核心数据读写到构建健壮的监控服务,系统讲解了如何高效完成数据采集与交互,大幅提升工业自动化项目的开发效率。

s4t5u6v的博客 1202

手把手教你用mitmproxy抓包抖音数据流(附Python脚本模板)

本文详细介绍了如何使用mitmproxy抓包抖音数据流,包括环境搭建、证书安装和Python脚本模板。从mitmproxy配置到抖音API解析,提供完整的移动端数据流分析方案,帮助开发者快速掌握数据抓取技术,适用于应用优化、竞品分析和安全审计等场景。

weixin_33670786的博客 307
上一篇: 【Unity Shaders】使用Unity Render Textures实现画面特效——建立画面特效脚本系统
下一篇: 最新基于高德地图的android进阶开发 GPS地图定位
wkkingsam
博客等级 码龄10年 10粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值