一、需要提前了解的

其实关于屏幕后处理(Screen Post-processing Effects)相关的知识,前面已经提过了不少:

这些是 OpenGL 渲染部分:

  • OpenGL基础35:帧缓冲(下)之简单图像处理:图像处理更多的是思维和算法,和你的平台/语言都无关
  • OpenGL基础33:帧缓冲(上)之离屏渲染
  • OpenGL基础34:帧缓冲(中)之附件

搞懂了上面这些后,就可以进入 Unity3D 了:

  • UnityShader19:渲染纹理(上)之截屏功能实现:里面有关 RenderImage 函数和 Bilt 函数的讲解,这里会用到
  • UnityShader20:CommandBuffer初见(上)
  • UnityShader20.1:CommandBuffer初见(下)

了解了这些内容之后,这一章的内容就非常好理解

二、屏幕后处理 C# 部分逻辑

  • 屏幕后处理的时机:完成整个场景、得到屏幕图像后
  • 屏幕后处理的目的:对整个游戏画面添加各种艺术效果和屏幕特技

对于上面的时机和目的,单纯的一个或多个 Shader 就可能难以去实现完整的屏幕后处理逻辑,还需要脚本的帮助

先解决第一个问题:抓取屏幕,这就依赖于 OnRenderImage 函数和 Graphics.Bilt 函数

using UnityEngine;
using System.Collections;[ExecuteInEditMode]
//当在物体上添加该脚本时,Camera组件也会被自动被添加上去(如果没有的话)
[RequireComponent(typeof(Camera))]
public class PostEffectsBase: MonoBehaviour
{protected void Start(){//如果显卡支持图像后期处理效果if (!SystemInfo.supportsImageEffects){//设置当前组件为关闭状态enabled = false;}}protected Material CheckShaderAndCreateMaterial(Shader shader, Material material){//判断当前着色器是否可在当前显卡设备上使用,如果对应的着色器的所有Fallback都不可支持或者传入的着色器就不存在,返回nullif (shader == null || !shader.isSupported)return null;if (material && material.shader == shader)return material;else{material = new Material(shader);//设置当前材质不会被保存在场景中material.hideFlags = HideFlags.HideAndDontSave;if (material)return material;elsereturn null;}}
}

上面这个是基类,主要用于检查条件和资源是否支持我们进行图像后处理,以及组合 Shader 和 Meterial

  • SystemInfo.supportsImageEffects:如果显卡支持图像后期处理效果,返回 true
  • [RequireComponent(typeof(cName))]:添加依赖项:当你设置一个用了 RequireComponent 的脚本为组件,与此同时组件 cName 也会被自动被添加上去(如果没有的话)且不可被移除
  • shader.isSupported:当前着色器是否可在当前显卡设备上使用,如果对应的着色器的所有 Fallback 都不可支持,返回 false
  • object.hideFlags:设置的值应为 Unity 内置的枚举 HideFlags,用于控制对象的销毁、保存和在检查器中的可见性
using UnityEngine;
using System.Collections;public class PostEffectExample: PostEffectsBase
{public Shader shader;private Material _material;public Material material{get{_material = CheckShaderAndCreateMaterial(shader, _material);return _material;}}[Range(0.0f, 3.0f)]public float brightness = 1.0f;[Range(0.0f, 3.0f)]public float saturation = 1.0f;[Range(0.0f, 3.0f)]public float contrast = 1.0f;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);}}
}

这是屏幕后处理的核心脚本:通过 OnRenderTexture 拿到当前屏幕 RT,之后再通过 Blit 将它作为绑定了指定 Shader Meterial 的主纹理,进行一次或多次渲染,得到的最终结果会显示到屏幕上

  • MonoBehaviour.OnRenderImage(srcRT, targetRT):中文简单介绍参见这里,它在所有不透明和透明的 Pass 执行完毕后被调用,以便对场景中所有的游戏对象都产生影响
  • Graphics.Blit(…):中文简单介绍参见这里

三、亮度、对比度与饱和度

和这一章一样,亮度、对比度与饱和度的计算当然是在着色器中:

Shader "Jaihk662/PPEExample1"
{Properties{_MainTex("Base(RGB)", 2D) = "white" {}_Brightness("Brightness", Float) = 1            //亮度_Saturation("Saturation", Float) = 1            //饱和度_Contrast("Contrast", Float) = 1                //对比度}CGINCLUDE       //和之前常用的CGPROGRAM不同,在CGINCLUDE和ENDCG范围内插入的shader代码会被插入到所有Pass中#include "UnityCG.cginc"sampler2D _MainTex;  half _Brightness;half _Saturation;half _Contrast;struct vert2frag {float4 pos: SV_POSITION;float2 uv: TEXCOORD0;};vert2frag vert(appdata_img v){vert2frag o;o.pos = UnityObjectToClipPos(v.vertex);o.uv = v.texcoord;return o;}half4 frag(vert2frag i): SV_Target{fixed4 renderTex = tex2D(_MainTex, i.uv);//计算亮度fixed3 finalColor = renderTex.rgb * _Brightness;//计算饱和度fixed luminance = 0.2125 * renderTex.r + 0.7154 * renderTex.g + 0.0721 * renderTex.b;       //图像转黑白的专业算法fixed3 luminanceColor = fixed3(luminance, luminance, luminance);finalColor = lerp(luminanceColor, finalColor, _Saturation);//计算对比度fixed3 avgColor = fixed3(0.5, 0.5, 0.5);finalColor = lerp(avgColor, finalColor, _Contrast);return fixed4(finalColor, renderTex.a);  }ENDCGSubshader{Pass{ZTest Always Cull Off ZWrite OffFog { Mode off }        //设置雾模式:关闭CGPROGRAM//使用低精度(FP16)以提升fragment着色器的运行速度,减少时间#pragma fragmentoption ARB_precision_hint_fastest#pragma vertex vert#pragma fragment fragENDCG}}
}

然后只需要将这个 Shader 给到对应的后处理脚本就 OK,这个 Shader 就是 Bilt 操作时 Meterial 对应的 Shader

上面的参数对应的亮度为 2.74,饱和度为 0.83,对比度为 0.2,效果和原图如下:

UnityShader24:最简单的屏幕后处理例子相关推荐

  1. 屏幕后处理故障艺术效果

    最近在做故障艺术中的RGB Split效果.RGB分离的效果可以做很多变化,本篇文章的重点部分是在SelectiveRGB效果上,也就是单独的对屏幕中的某个东西做RGB效果. 因为之前也没写过屏幕后处 ...

  2. [OpenGL] 屏幕后处理:景深效果

    开发环境:Qt, OpenGL 立方体纹理是Qt官方教程Cube里自带的纹理. 概念引入 景深是摄像中的术语.相机聚焦后,镜头前远近平面之间的物体能够清晰成像,这一段清晰成像的距离也就是景深,我们可以 ...

  3. unity屏幕后处理全家桶之color grading

    color grading color grading指的是对最终的游戏界面进行颜色和亮度的改变或矫正.你可以理解为增加滤镜. 屏幕后处理全家桶里的color grading是完全实时hdr工具,内部 ...

  4. Unity中基于屏幕后处理的彩色与黑白渐变效果

    本文将介绍Unity屏幕后处理的基本方法与游戏角色死亡后的屏幕渐变到黑白效果的实现方法. 屏幕后处理是指整个场景每一帧渲染完毕后,再对得到的屏幕图像进行一系列处理并显示到屏幕上的过程.Unity中我们 ...

  5. 屏幕后处理——Bloom

    来自于<Unity Shader 入门精要>书本的学习 先上图 代码分3部分 1.PostEffectsBase.cs using System.Collections; using Sy ...

  6. 一个简单的epoll测试例子

    一个简单的epoll测试例子 一段简单的epoll测试例子,编译运行后可以直接用浏览器访问localhost来测试. 1 #include <unistd.h> 2 #include &l ...

  7. 一个简单的三层架构例子(.NET入门)

    最近开始学习.NET 用的是c# 目前要用三层架构的模式开发一个简单的图书管理系统,不过以为刚接触这门技术.做起来分外吃力,甚至连究竟要写些什么都不清楚. 于是乎上网到处找寻三层架构的基础入门知识,终 ...

  8. 一个简单的规则引擎例子

    本例使用的规则引擎包是RulesEngine,关于RulesEngine的介绍,请自行补充,这里只是一个极简单使用场景. 例子大体就是用户有一些优惠券,系统会根据用户订单情况,筛选可以使用的优惠券供用 ...

  9. 一个简单的iBatis入门例子

    一个简单的iBatis入门例子,用ORACLE和Java测试 目录结构: 1.导入iBatis和oracle驱动. ibatis-2.3.4.726.jar ojdbc14.jar 2.创建类com/ ...

最新文章

  1. 基数估算HyperLogLog
  2. web项目_学生证管理系统
  3. android webview拍照,在android 2.2/2.3中使用webview从camera中照相并且上传的实现
  4. Django框架(23.Django中的模板的标签、变量、过滤器和注释)
  5. 博古通今的孩子是怎么养成的?答案就在这本影响了无数中国人思想的奇书里……
  6. 物理拓扑和逻辑拓扑——现实和应用的比较
  7. 如何建立队列c语言_什么是优先队列
  8. adprw指令通讯案例_实例 | 三菱FX3U485无协议通讯程序详解(含程序)
  9. 关于5G你所需要知道的一切
  10. linux netcat命令实例
  11. 指示灯亮着,但是右边的数字小键盘不可用
  12. 你可以做一个更好的Coder为了自己的将来
  13. 每日面试】阿里巴巴 Java后端 57min
  14. 蔡颖-《APS走向实践》书解读之一:APS优化供应链从绩效指标开始
  15. 一阶的RC高低通电路和微积分电路有什么区别
  16. 用协议软件分析ping大包丢包故障
  17. php 搜索字符串ctrl f_js搜索关键字(Ctrl + F)
  18. Cypress系列(50)- wrap() 命令详解
  19. ios传智播客_如何在iOS中创建播客播放列表
  20. 韩顺平JAVA-D5

热门文章

  1. python基础教程是什么-python基础教程之python是什么?
  2. python是什么类型的编程语言-2.python是什么编程语言。
  3. python常用代码大全-Python常用库大全,看看有没有你需要的
  4. python能做什么-学会Python后都能做什么?网友们的回答简直不要太厉害
  5. python从入门到精通-python从入门到精通视频(大全60集)
  6. python在线编辑器手机-‎App Store 上的quot;Python AI - 代码编辑器”
  7. h5 语音识别_h5 在线语音识别接口_html5 语音识别 - 云+社区 - 腾讯云
  8. 嵌入式linux调试dsi,做嵌入式开发时,你是怎么实现LCD显示的?
  9. Vue中条件判断 v-if 、v-show
  10. [Vue warn]: Error in render: TypeError: _self.$scopedSlots.default is not a function 错误解决