利用脚本和Shader制作屏幕后处理效果
一、屏幕后处理的实现原理
该屏幕后处理的原理是将渲染完成后的屏幕纹理通过脚本和Shader完成一些操作,然后实现各种屏幕效果
而实现屏幕后处理效果的主要操作就是获得当下渲染完成后的屏幕图像,其中unity提供了一个函数用于获取此图像——OnRenderImage ( )
private void OnRenderImage(RenderTexture src,RenderTexture dest) { ... }
当在脚本中声明此函数后,Unity会把当前渲染完成后的图像存储在src源渲染纹理中,通过函数中的一系列操作后(该函数内操作是我们自定义的),再把目标渲染纹理存储在dest渲染纹理中,dest最终会被显示到屏幕上
然后在OnRenderImage函数中可以利用Graphics.Blit函数来完成对渲染后的屏幕图像的操作
Graphics.Blit(Texture src , RenderTexture dest , Material Mat);
Graphics.Blit(Texture src , RenderTexture dest , Material Mat , int pass=-1);
Graphics.Blit(src, dest, Mat);
src为源纹理,dest为处理后的纹理最后会显示到屏幕上
mat是所使用的材质,该材质会利用相应的Sahder代码对源纹理进行屏幕后处理效果的实现
其中src源纹理会被传入到Shader的_MainTex属性中,所以我们就可以利用Sahder对_MainTex属性进行修改来实现屏幕后处理的效果
同时参数Pass的默认值为-1,表示将会依次调用Shader内的所有Pass
二、关于黑白阈值的屏幕后处理效果实现
首先创建一个脚本,挂载到摄像机上
在脚本中添加OnRenderImage函数
private void OnRenderImage(RenderTexture src , RenderTexture dest)
{
Graphics.Blit(src,dest,Mat)
}
其中Mat代表的材质还未指定,可以在脚本中添加一个公共的Sahder用于存放所需要的Shader,然后通过该Shader创建对应的材质球(Material _newmat = new Material( PostProcessingShader );)
public Shader PostProcessingShader;
Material _newmat = new Material( PostProcessingShader ); //通过Shader创建材质球
然后添加一个关于Mat的Get/Set属性访问器(public Material Mat),然后在public Material Mat中设置 private Material mat 的值
当在OnRenderImage函数中使用到Mat时,此时就会进入到public Material Mat的Get方法中读取到mat的值,从而返回给OnRenderImage函数该值。具体如下方所示:
private Material mat;
public Material Mat
{
get
{
//当mat为空时
if(mat==null)
{
//为指定的Shader新建一个材质球
Material _newmat = new Material( PostProcessingShader );//材质球隐藏并且不保存
_newmat.hideFlags = HideFlags.HideAndDontSave;
mat = _newmat;
//将新建的材质球返回给Mat
return mat; //读取并返回值
}
//mat不为空
else
{
return mat; //读取并返回值
}
}
}
关于Get/Set属性访问器的具体用法和原理参考:
Unity-Get/Set属性访问器详解_unity get set-CSDN博客
C#的属性:get、set_c# get =>-CSDN博客
Get/Set属性访问器中使用get方法中读取值,set方法设置值。在set方法中可以对值的设置进行限制,起到一定的安全作用

接着在 "PostProcessingShader" 的Shader代码中来完成屏幕后处理效果,例如黑白阈值
接上文,src源纹理会通过Graphics.Blit函数传入到Shader的_MainTex属性中,所以在Shader可以通过uv坐标采样_MainTex得到源纹理的fixed4 类型的颜色值
对于黑白阈值的实现,可以根据采样后的 col.r 与一个滑杆值进行step函数的计算
step(a,b) 当a<=b时 , return 1; else return 0
滑杆值:_BW("BW",Range(0,1))=0
采样贴图后的值:fixed4 col = tex2D(_MainTex, i.uv);
step(col.r , _BW); //step(a,b) 当a<=b时,return 1; else return 0
但是此时Shader创建的材质球不会被暴漏出来,所以材质球中_BW的滑杆属性不能被调节
所以此时只能在脚本代码中对_BW参数进行调节
- 先在脚本中设置一个变量,用于控制黑白阈值 [Range(0,1)] public float bw;
- 然后通过SetFloat在脚本中更改Shader中_BW属性的值
- Mat.SetFloat("_BW",bw);

C#脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static System.Net.WebRequestMethods;
using UnityEngine.UI;//在编辑器模式下也可运行此脚本
[ExecuteInEditMode]public class Postprocessing : MonoBehaviour
{public Shader PostProcessingShader;//在脚本中设置一个变量,用于控制黑白阈值[Range(0,1)]public float bw;private Material mat;public Material Mat{get{ //当mat为空时if(mat==null){//为指定的Shader新建一个材质球Material _newmat = new Material(PostProcessingShader);//材质球隐藏并且不保存_newmat.hideFlags = HideFlags.HideAndDontSave;mat = _newmat;//将新建的材质球返回给Matreturn mat;}//mat不为空else{return mat;}}}//Unity在图像渲染完成后对图像进行修改,需要对OnRenderImage() 进行重写//OnRenderImage在图像渲染完成之后被调用,因此可以用来添加屏幕的后处理效果。//输入的图片 RenderTextrure source, 输出的图片是 RenderTexture destination.//如果要对这个方法进行重写,必须要要加上 Graphic.Blit方法。//src为原始图像,dest为修改后的图像private void OnRenderImage(RenderTexture src,RenderTexture dest){Mat.SetFloat("_BW",bw);//src图像须传入到Mat材质Shader中,然后Shader使用MainTex来获取此图像Graphics.Blit(src, dest, mat);}
}
Shader代码:
Shader "Hidden/PostProcessing"
{Properties{_MainTex ("Texture", 2D) = "white" {}_BW("BW",Range(0,1))=0}SubShader{// No culling or depthCull Off//深度写入关闭,因为深度写入会导致画面出错ZWrite Off//使每一帧的图像都被渲染到屏幕上ZTest AlwaysPass{CGPROGRAM#pragma vertex vert_img#pragma fragment frag#include "UnityCG.cginc"float _BW;sampler2D _MainTex;fixed4 frag (v2f_img i) : SV_Target{fixed4 col = tex2D(_MainTex, i.uv);// just invert the colors 反向颜色值然后输出// return step(col,0.5); fixed4(step(col.r,0.5),step(col.g,0.5),step(col.b,0.5),step(col.a,0.5))// step(a,b) 当a<=b时,return 1; else return 0;//在脚本代码中修改_BW值return step(col.r,_BW);}ENDCG}}
}
【太妃糖耶】新作上线,快来看看!
相关文章:
利用脚本和Shader制作屏幕后处理效果
一、屏幕后处理的实现原理 该屏幕后处理的原理是将渲染完成后的屏幕纹理通过脚本和Shader完成一些操作,然后实现各种屏幕效果 而实现屏幕后处理效果的主要操作就是获得当下渲染完成后的屏幕图像,其中unity提供了一个函数用于获取此图像——OnRenderIma…...
【银河麒麟系统常识】命令:uname -m(查看系统架构)
命令: uname -m 功能 常用的 Linux/Unix 终端命令,用于显示当前系统的硬件架构; 返回 返回系统的CPU架构类型,用于判断软件兼容性; 输出结果架构说明常见设备x86_64Intel/AMD 64位 CPU主流 PC、服务器aarch64ARM 64位 …...
3.1.2 内存池
文章目录 3.1.2 内存池1. 什么是内存池2. 内存管理1. 定长2. 不定长3. jemalloc4. tcmalloc 3.1.2 内存池 1. 什么是内存池 内存池(Memory Pool) 是一种 预先分配 一块大内存,然后按需分配和回收 其中小块内存的技术。它的本质是管理一块连续…...
基于SpringBoot + Vue 的餐厅点餐管理系统
SpringBootVue餐厅点餐管理系统 技术框架 后端:springboot mybatisPlus前端:Vue2 elementUI数据库:mysql项目构建工具:maven 数据库表 14张 角色及功能 管理员:登录、用户管理、餐桌信息管理、菜品类型管理、菜…...
Android开发BasePagerAdapter
Android开发BasePagerAdapter 有个基类的PagerAdapter 方便很多 public class BasePagerAdapter extends FragmentPagerAdapter {private static final String TAG "FragmentPagerAdapter";private static final boolean DEBUG false;private final FragmentMana…...
70. Linux驱动开发与裸机开发区别,字符设备驱动开发
一、裸机驱动开发回顾 1、底层,跟寄存器打交道,有些MCU提供了库。 二、Linux驱动开发思维 1、Linux下驱动开发直接操作寄存器不现实。 2、根据Linux下的各种驱动框架进行开发。一定要满足框架,也就是Linux下各种驱动框架的掌握。 3、驱动最…...
【博客节选】再谈Unity 的 root motion
节选自 【Unity实战笔记】第二十三 root motion变更方向攻击 (OnStateMove rootmotion rigidbody 使用的一些问题) 小伙伴们应该对root motion非常困惑,包括那个bake into pose。 当xz bake into pose后,角色攻击动画与父节点产…...
26考研——栈、队列和数组_栈(3)
408答疑 文章目录 一、栈1、栈(Stack)的概念和特点定义术语操作特性示例直观理解栈的基本操作初始化栈判断栈是否为空入栈操作出栈操作读取栈顶元素销毁栈 栈的数学性质 2、栈的顺序存储结构顺序栈的定义栈顶指针初始化注意事项 共享栈共享栈的操作共享栈…...
“十五五”时期航空弹药发展环境分析
1.“十五五”时期航空弹药发展环境分析 (标题:小二号宋体居中) 一、建言背景介绍 (一级标题:黑体三号,首行空两格) 航空弹药作为现代战争的核心装备,其发展水平直接关乎…...
桥接模式的优点和典型实现
桥接模式的优点 桥接模式通过将抽象部分与实现部分分离,使得它们可以独立变化,从而提高系统的灵活性和可扩展性。以下是桥接模式的主要优点: 分离抽象和实现: 桥接模式将抽象部分和实现部分分离,使得两者可以独立变化…...
Kotlin 协程官方文档知识汇总(一)
1、协程基础 Kotlin 是一门仅在标准库中提供最基本底层 API 以便其他库能够利用协程的语言。与许多其他具有类似功能的语言不同,async 与 await 在 Kotlin 中并不是关键字,甚至都不是标准库的一部分。此外,Kotlin 的挂起函数概念为异步操作提…...
删除字符串邻近的重复项
1047. 删除字符串中的所有相邻重复项 - 力扣(LeetCode) 对于字符串中字符的匹配或者删除等问题,通常会用到栈这个数据结构,要保持这样一个思路。 对于这道题,可以遍历字符串,用栈存储,一旦遇到…...
基于 mxgraph 实现流程图
mxgraph 可以实现复杂的流程图绘制。mxGraph里的Graph指的是图论(Graph Theory)里的图而不是柱状图、饼图和甘特图等图(chart),因此想找这些图的读者可以结束阅读了。 作为图论的图,它包含点和边,如下图所示。 交通图 横道图 架构图 mxGrap…...
动态路由机制MoE专家库架构在多医疗AI专家协同会诊中的应用探析
随着医疗人工智能技术的飞速进步,AI在医学领域的应用日益增多,尤其是在复杂疾病的诊断和治疗中,AI技术的应用带来了巨大的潜力。特别是动态路由机制混合专家(Mixture of Experts,MoE)架构,因其灵活、高效的特点,正逐渐成为实现多AI专家协同会诊的关键技术。通过将多个不…...
双工通信:WebSocket服务
(一)WebSocket概述 WebSocket 是基于 TCP 的一种新的网络协议。它实现了浏览器与服务器全双工通信——浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接, 并进行双向数据传输 注意;Websocket也只能由客户端先握…...
洪水灌溉算法 + 总结
文章目录 floodfill算法图像渲染题解代码 岛屿数量题解代码 岛屿的最大面积题解代码 被围绕的区域题解代码 太平洋大西洋水流问题题解代码 扫雷游戏题解代码 衣橱整理题解代码 总结 floodfill算法 1. 寻找相同性质的联通块,可以使用dfs或者bfs解决,比如…...
docker中间件部署
1.docker安装 # 1.卸载旧版本 yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine# 2.需要的安装包 yum install -y yum-utils# 3.设置镜像的仓库 # 3.1.默认是国外的&#x…...
LangChain4j(1):初识LangChain4j
1 什么是LangChain和LangChain4j LangChain是一个大模型的开发框架,使用LangChain框架,程序员可以更好的利用大模型的能力,大大提高编程效率。如果你是一个lava程序员,那么对LangChain最简单直观的理解就是,LangChain…...
基于 Swoole 的高性能 RPC 解决方案
文章精选推荐 1 JetBrains Ai assistant 编程工具让你的工作效率翻倍 2 Extra Icons:JetBrains IDE的图标增强神器 3 IDEA插件推荐-SequenceDiagram,自动生成时序图 4 BashSupport Pro 这个ides插件主要是用来干嘛的 ? 5 IDEA必装的插件&…...
Photoshop 2025安装包下载及Photoshop 2025详细图文安装教程
文章目录 前言一、Photoshop 2025安装包下载二、Photoshop 2025安装教程1.解压安装包2.运行程序3.修改安装路径4.设安装目录5.开始安装6.等安装完成7.关闭安装向导8.启动软件9.安装完成 前言 无论你是专业设计师,还是初涉图像处理的小白,Photoshop 2025…...
CPU跑大模型怎么加速?
一、概念 近几年,大模型的规模越做越大。普通码农没几张显卡几乎都跑不动动辄几百B的模型了。当然,随着SLM进一步发展,移动端、PC端部署SLM变得轻松了起来。即便只有CPU也能带得起3B以内的SLM,只不过推理速度比较感人。因此&#…...
PostgreSQL详解
第一章:环境部署与基础操作 1.1 多平台安装详解 Windows环境 图形化安装 下载EnterpriseDB安装包(含pgAdmin) 关键配置项说明: # postgresql.conf优化项 max_connections 200 shared_buffers 4GB work_mem 32MB 服务管理命…...
SQL Server安装程序无法启动:系统兼容性检查失败
问题现象: 运行 SQL Server 2022 安装程序时,提示 “硬件或软件不满足最低要求”,安装向导直接退出或无法继续。 快速诊断 操作系统版本检查: # 查看 Windows 版本(需 20H2 或更高) winver 支持的系统&…...
期权合约作废的话,权利金和保证金会退还么?
在期权交易中,权利金是否可以退回,主要取决于期权的交易情况和合约条款。 期权作废的三种情形 一般来说期权作废一共有三种情况,分别是到期没有行权、主动放弃或者是标的退市了。 第一种是到期未行权,一般来说值得都是虚值期权&…...
MIPI计算ECC和CRC工具介绍
一、MIPI简介 MIPI联盟,即移动产业处理器接口(Mobile Industry Processor Interface 简称MIPI)联盟。MIPI(移动产业处理器接口)是MIPI联盟发起的为移动应用处理器制定的开放标准和一个规范。MIPI官网https://mipi.org/…...
医院管理系统(源码)分享
「医院管理系统(源码) 源码: https://pan.quark.cn/s/b6e21488fce3 第1章 绪论 1.1 项目背景 随着计算机科学的迅猛发展和互联网技术的不断推进,人们的生活方式发生了巨大的变化,同时也推动了整个软件产业的发展。把…...
使用Geotools从DEM数据中读取指定位置的高程实战
目录 前言 一、GridCoverage2D对象介绍 1、GridCoverage2D的属性 2、GridCoverage2D核心方法 3、GridCoverage2D中的高级操作 二、指定位置的高程获取 1、存储原理 2、相关属性的获取 3、获取高程的方法 三、总结 前言 在地理信息科学领域,高程数据是至关重…...
uniapp 在app上 字体如何不跟着系统字体大小变
在UniApp开发中,默认情况下App的字体可能会跟随系统字体设置而变化。如果你希望保持固定的字体样式,不随系统字体设置改变,可以采用以下几种方法: 方法一:全局CSS设置 在App.vue的样式中添加以下CSS: /*…...
RAG优化:python从零实现GraphRag 一场文档与知识的“恋爱”之旅
嘿,亲爱的算法工程师们,准备好迎接一场文档与知识的“恋爱”之旅了吗?今天我们要介绍的 Graph RAG,就像是一位“红娘”,帮助文档和知识在图的世界里找到彼此,擦出智慧的火花! 文章目录 为什么需要 Graph RAG?Graph RAG 的“恋爱秘籍”准备好了吗?让我们开始吧!环境设…...
STM32F103_LL库+寄存器学习笔记05 - GPIO输入模式,捕获上升沿进入中断回调
导言 GPIO设置输入模式后,一般会用轮询的方式去查看GPIO的电平状态。比如,最常用的案例是用于检测按钮的当前状态(是按下还是没按下)。中断的使用一般用于计算脉冲的频率与计算脉冲的数量。 项目地址:https://github.…...
