第十二章 屏幕后处理效果

屏幕后处理效果是实现屏幕特效的常见方法。

建立一个基本的屏幕后处理的脚本

屏幕后处理指的是在渲染完整个场景得到屏幕图像后,再对这个图像进行一系列操作,实现各种屏幕特效。

想要实现屏幕后处理的基础在于抓取屏幕。Unity为我们提供了一个接口-OnRenderImage函数。

声明如下:MonoBehaviour.OnRenderImage(RenderTexture src,RenderTexture dest)

当我们在屏幕上运行此函数后,Unity会把当前渲染得到的图像存储在第一个参数对应的源渲染纹理中,通过函数中的一系列操作后,再把目标渲染纹理,即第二个参数对应的渲染纹理显示到屏幕上。在OnRenderImage中,我们通常是通过Graphics.Blit函数来完成对渲染纹理的处理。

public static void Blit(Texture src, RenderTexture dest);

public static void Blit(Texture src, RenderTexture dest, Material mat, int pass = -1);

public static void Blit(Texture src, Material mat, int pass = -1);

参数src对应了源纹理,在屏幕后处理技术中,这个参数通常就是当前屏幕的渲染纹理或是上一步处理后得到的渲染纹理。参数dest是目标渲染纹理,如果它的值为null就会直接将结果显示在屏幕上。参数mat是我们使用的材质,这个材质使用的Unity Shader将会进行各种屏幕后处理操作,而src纹理将会被传递给Shader中名为_MainTex的纹理属性。参数pass的默认值为-1,表示将会一次调用Shader内的所有Pass。否则,只会调用给定索引的Pass。

默认情况下,OnRenderImage函数会在所有不透明和透明的Pass执行完毕后被调用,以便对场景中所有游戏对象都产生影响。但有时我们希望在不透明的Pass执行完毕后立即调用OnRenderImage函数,从而不对透明物体产生任何影响。此时,我们可以在OnRenderImage函数前添加ImageEffectOpaque属性来实现这样的目的。

要实现屏幕后处理过程如下:

using UnityEngine;
using System.Collections;

//所有屏幕后处理效果都需要绑定在某个摄像机上,我们希望在编辑器状态下也可以查看该脚本
[ExecuteInEditMode]
[RequireComponent(typeof(Camera))]
public class PostEffectsBase : MonoBehaviour
{

//提前检查资源是否满足
protected void CheckResources()
{
bool isSupported = CheckSupport();

if (isSupported == false)
{
NotSupported();
}
}
protected bool CheckSupport()
{
//if (SystemInfo.supportsImageEffects == false || SystemInfo.supportsRenderTextures == false)
//{
//	Debug.LogWarning("This platform does not support image effects or render textures.");
//	return false;
//}

return true;
}
protected void NotSupported()
{
enabled = false;
}

protected void Start()
{
CheckResources();
}

//指定一个Shader来创建一个用于处理渲染纹理的材质
//CheckShaderAndCreateMaterial接受两个参数,第一个参数指定了该特效需要使用的Shader,第二个参数则是用于后期处理的材质。该函数首先检查Shader可用性,检查通过后就返回一个使用了该Shader的材质,否则返回null
protected Material CheckShaderAndCreateMaterial(Shader shader, Material material)
{
if (shader == null)
{
return null;
}

if (shader.isSupported && material && material.shader == shader)
return material;

if (!shader.isSupported)
{
return null;
}
else
{
material = new Material(shader);
material.hideFlags = HideFlags.DontSave;
if (material)
return material;
else
return null;
}
}
}

调整屏幕的亮度、饱和度和对比度

Shader "Unity Shaders Book/Chapter 12/Brightness Saturation And Contrast" {
	Properties {
		//Graphics.Blit(src, dest, material)将第一个参数传递给Shader中名为_MainTex的属性
		_MainTex ("Base (RGB)", 2D) = "white" {}
		//调整亮度
		_Brightness ("Brightness", Float) = 1
		//调整饱和度
		_Saturation("Saturation", Float) = 1
		//调整对比度
		_Contrast("Contrast", Float) = 1
	}
	SubShader {
		Pass {  
			//屏幕后处理实际上是在场景中绘制了一个与屏幕同宽同高的四边形面片。
			//关闭深度写入
			ZTest Always Cull Off ZWrite Off
			
			CGPROGRAM  
			#pragma vertex vert  
			#pragma fragment frag  
			  
			#include "UnityCG.cginc"  
			  
			sampler2D _MainTex;  
			half _Brightness;
			half _Saturation;
			half _Contrast;
			  
			//屏幕特效只需要进行必须的顶点变换,把正确的纹理坐标传递给片元着色器
			struct v2f {
				float4 pos : SV_POSITION;
				half2 uv: TEXCOORD0;
			};
			
			//使用Unity内置结构体appdata_img作为顶点着色器的输入,它只包含了图像处理时必须的顶点坐标和纹理坐标等
			v2f vert(appdata_img v) {
				v2f o;
				
				o.pos = UnityObjectToClipPos(v.vertex);
				
				o.uv = v.texcoord;
						 
				return o;
			}
		
			fixed4 frag(v2f i) : SV_Target {
				//得到对原屏幕图像采样结果renderTex
				fixed4 renderTex = tex2D(_MainTex, i.uv);  
				  
				//调整亮度
				fixed3 finalColor = renderTex.rgb * _Brightness;
				
				//计算该像素对应的亮度值luminance
				//对每个颜色分量乘以一个特定的系数再相加
				fixed luminance = 0.2125 * renderTex.r + 0.7154 * renderTex.g + 0.0721 * renderTex.b;
				//创建一个饱和度为0的颜色值
				fixed3 luminanceColor = fixed3(luminance, luminance, luminance);
				//使用_Saturation属性和颜色之间进行插值,得到希望的饱和度颜色
				finalColor = lerp(luminanceColor, finalColor, _Saturation);
				
				//创建一个对比度为0的颜色值
				fixed3 avgColor = fixed3(0.5, 0.5, 0.5);
				//使用_Contrast属性在其和颜色值之间进行插值
				finalColor = lerp(avgColor, finalColor, _Contrast);
				
				return fixed4(finalColor, renderTex.a);  
			}  
			  
			ENDCG
		}  
	}
	
	Fallback Off
}

边缘检测

描边效果的一种实现方法。

边缘检测的原理是利用一些边缘检测算子对图像进行卷积操作。

什么是卷积

图像处理中,卷积操作指的是使用一个卷积核对一张图像中的每个像

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/553353.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【C语言回顾】函数

前言1. 函数的概念和分类2.库函数3. 自定义函数3.1 自定义函数的简单介绍3.2 自定义函数举例 4. 形参和实参4.1 形参4.2 实参4.3 形参和实参的关系4.3.1 理解4.3.2 举例代码和调试 5. 嵌套函数和链式访问5.1 嵌套函数5.2 链式访问 6. 函数的声明和定义6.1 单个文件6.2 多个文件…

Java PDF文件流传输过程中速度很慢,如何解决?

专栏集锦,大佬们可以收藏以备不时之需: Spring Cloud 专栏:http://t.csdnimg.cn/WDmJ9 Python 专栏:http://t.csdnimg.cn/hMwPR Redis 专栏:http://t.csdnimg.cn/Qq0Xc TensorFlow 专栏:http://t.csdni…

Https网站接口被黑被恶意调取

背景: 维护的一个网站最近短信接口被黑,发送大量短信。起初以为是在网站内部操作,优化了发送短信前的操作,如添加图形验证码,屏蔽国外IP等。但后续还存在被调取情况,定位排查到是该接口在外部被恶意调取。 …

牛客Linux高并发服务器开发学习第二天

Gcc编译 利用gcc 生成应用时如果不加-o 和应用名,默认生成a.out 可以用./ a.out打开 Gcc工作流程 可执行程序Windows系统中为.exe Linux系统中为.out g也可以编辑c程序 gcc也可以编译cpp代码,只是在编译阶段gcc不能自动共和C程序使用的库进行联接&…

论文笔记:Are Human-generated Demonstrations Necessary for In-context Learning?

iclr 2024 reviewer 评分 6668 1 intro 大型语言模型(LLMs)已显示出在上下文中学习的能力 给定几个带注释的示例作为演示,LLMs 能够为新的测试输入生成输出然而,现行的上下文学习(ICL)范式仍存在以下明显…

海信发布《黑神话:悟空》定制电视E8N新品,重塑大屏游戏体验

4月17日,在“AI美好生活”2024海信电视E8系列新品发布会上,海信电视官宣成为《黑神话:悟空》全球官方合作伙伴。同时,海信电视还为广大游戏玩家带来了《黑神话:悟空》的显示CP,推出了官方定制电视——旗舰新…

夸克AI PPT初体验:一键生成大纲,一键生成PPT,一键更换模板!

大家好,我是木易,一个持续关注AI领域的互联网技术产品经理,国内Top2本科,美国Top10 CS研究生,MBA。我坚信AI是普通人变强的“外挂”,所以创建了“AI信息Gap”这个公众号,专注于分享AI全维度知识…

FineBI 6.0 Linux 部署、ClickHouse 源配置

文章目录 FineBI 概述FineBI 部署安装环境说明1.下载安装包2.安装3.初始化设置4.登录5.快速入门 启动与关闭启动关闭 ClickHouse 源配置开启驱动上传功能驱动上传数据库连接配置基础表属性设置数据导入 FineBI 概述 FineBI 是一款国产的商业智能(BI)软件…

基于Ultrascale+系列GTY收发器64b/66b编码方式的数据传输(一)——Async Gearbox使用及上板测试

于20世纪80年代左右由IBM提出的传统8B/10B编码方式在编码效率上较低(仅为80%),为了提升编码效率,Dgilent Techologies公司于2000年左右提出了64b/66b编码并应用于10G以太网中。Xilinx GT手册中没有过多64b/66b编码介绍&#xff0c…

生活中的洪特规则

不知道你还记不记得高中物理所学的一个奇特的物理规则:洪特规则。 洪特规则是德国人弗里德里希洪特(F.Hund)根据大量光谱实验数据总结出的一个规律,它指出电子分布到能量简并的原子轨道时,优先以自旋相同的方式分别占…

【算法一则】矩阵置零 【矩阵】【空间复用】

题目 给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1: 输入:matrix [[1,1,1],[1,0,1],[1,1,1]] 输出:[[1,0,1],[0,0,0],[1,0,1]]示例 2: …

深度学习 Lecture 9 信息增益、One-hot、回归树、集成树、随机森林、XGBoost模型

一、信息增益(Information Gain) 决定使用什么特征来划分一个节点取决于什么样的特征选择最能减少熵(也就是使纯度最大化) 在决策树中,熵的减少被称为信息增益。 所以如何选择呢? 假设现在有三个特征可以选择&#…

CUDA 以及MPI并行矩阵乘连接服务器运算vscode配置

一、CUDA Vscode配置 (一)扩展安装 本地安装 服务器端安装 (二) CUDA 配置 .vscode c_cpp_properties.json {"configurations": [{"name": "Linux","includePath": ["${workspa…

【NUCLEO-G071RB】004——GPIO-按键EXTI外部中断控制LED闪烁

NUCLEO-G071RB:004——GPIO-按键EXTI外部中断控制LED闪烁 设计目标电路原理图芯片配置程序修改 设计目标 电路原理图 与NUCLEO-G071RB:003——GPIO-按键控制LED灯相同 芯片配置 1、PC13(B1):EXTI外部中断模式&…

STM32 USB虚拟串口

电路原理图 usb部分 晶振部分 usb与单片机连接 配置信息 sys配置信息 rcc配置信息 usb配置信息 虚拟串口配置信息 时钟配置信息 项目配置信息 代码 包含文件 主函数代码 实验效果 修改接收波特率依然可以正常接收,也就是说单片机可以自动适应上位机的波特率设置。…

【Day 1】HTML 与 CSS

1 前端 网站的工作流程: 首先我们需要通过浏览器访问发布到前端服务器中的前端程序,这时候前端程序会将前端代码返回给浏览器浏览器得到前端代码,此时浏览器会将前端代码进行解析,然后展示到浏览器的窗口中,这时候我…

EVI增强型植被指数

​随着遥感技术的发展,我们对地球上的植被状况有了更深入的了解,而其中一种重要的工具就是EVI(Enhanced Vegetation Index,增强型植被指数)。EVI不仅是一种植被指数,更是一种对植被生态系统健康和生产力评估…

统一SQL-支持unpivot列转行

统一SQL介绍 https://www.light-pg.com/docs/LTSQL/current/index.html 源和目标 源数据库:Oracle 目标数据库:TDSQL-MySQL 操作目标 在Oracle中,可以使用unpivot将列转换成行,在TDSQL-MySQL中没有对应的功能,由…

设计模式学习(六)——《大话设计模式》

设计模式学习(六)——《大话设计模式》 简单工厂模式(Simple Factory Pattern),也称为静态工厂方法模式,它属于类创建型模式。 在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂…

C++算法题 - 矩阵

目录 36. 有效的数独54. 螺旋矩阵48. 旋转图像73. 矩阵置零289. 生命游戏 36. 有效的数独 LeetCode_link 请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。 数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现…
最新文章