Bloom 效果
1、Bloom 效果是什么
Bloom效果(中文也可以叫做高光溢出效果),是一种使画面中亮度较高的区域产生一种光晕或发光效果的图像处理技术,Bloom效果的主要目的是模拟现实世界中强光源在相机镜头或人眼中造成的散射和反射现象,使得画面中较亮的区域“扩散”到周围的区域,造成一种朦胧的效果

2、基本原理
三步骤概括Unity Shader中实现Bloom效果的基本原理:
- 提取:提取原图像中的亮度区域存储到一张新纹理中
- 模糊:将提取出来的纹理进行模糊处理(一般采用高斯模糊)
- 合成:将模糊处理后的亮度纹理和源纹理进行颜色叠加
可以在屏幕后处理时,单独调用某个Pass对渲染纹理进行处理,只需要利用Unity中的三个函数即可
- RenderTexture.GetTemporary(纹理宽,纹理高,0)
- Graphics.Blit(源纹理,目标纹理,材质,passID)
- RenderTexture.ReleaseTemporary(渲染纹理对象)
处理Bloom效果时将使用4个Pass,他们分别是:
- 用于 提取亮度区域 存储到新纹理中的 1 个 Pass
- 用于 模糊处理提取出来的纹理 的 高斯模糊的 2 个 Pass(可以复用高斯模糊Shader中写好的Pass)
- 用于 与原图像进行合成 的 1 个 Pass
如何提取
需要在Shader中声明一个亮度阈值变量,亮度低于该值的区域不会被提取,主要用于“提取”Pass的片元着色器函数当中,
用当前像素的灰度值 L = 0.2125*R + 0.7154*G + 0.0721*B 与 亮度阈值变量 进行计算
灰度值 – 亮度阈值变量:是为了仅保留超过阈值的部分,可以提取出图像中亮度较高的地方。
Clamp函数:如果结果小于0则为0,大于1则为1。得到的val表示像素的亮度贡献
颜色*亮度贡献:基于亮度阈值调节颜色的亮度,若val为0则为黑色,越接近1越接近原始颜色
这样做的目的是保留高亮区域的颜色信息,同时衰减低亮区域的颜色。

如果“提取”Pass是Shader中的第一个Pass,可以利用RenderTexture.GetTemporary 和 Graphics.Blit 函数将源纹理提取亮度信息后存储到缓存区中
如何模糊
利用 UsePass 指令使用高斯模糊中的 Pass,需要在Bloom效果的Shader中声明一个纹理属性 _Bloom用于存储模糊处理完毕后的纹理,在C#代码中完成高斯模糊处理后,只需要将缓存区内容,写入材质球中的纹理属性即可
如何合成
在“合成”的Pass 中只需要用主纹理 _MainTex (其中使用的纹理是屏幕原图像)和纹理属性 _Bloom (其中使用的纹理是模糊处理后的亮度纹理信息)进行颜色叠加即可,我们对两张纹理进行采样,将获取到的颜色信息进行加法运算
因为颜色相加带来的效果就是增加亮度,使得原本高亮的部分变得更加显眼从而达到Bloom效果(高光溢出效果)
Shader "ShaderProj/11//Bloom"
{Properties{_MainTex ("Texture", 2D) = "white" {}_Bloom ("Bloom", 2D) = "white" {}_LuminanmceThreshold ("LuminanmceThreshold", Float) = 0.5//_BlurSize("BlurSize", Float) = 1}SubShader{CGINCLUDE#include "UnityCG.cginc"sampler2D _MainTex;half4 _MainTex_TexelSize;sampler2D _Bloom;float _LuminanmceThreshold;//float _BlurSize;struct v2f{float2 uv : TEXCOORD0;float4 vertex : SV_POSITION;};fixed4 luminance(float4 color){return 0.2125 * color.r + 0.7154 * color.g + 0.0721 * color.b;}ENDCGZTest AlwaysCull OffZWrite OffPass{CGPROGRAM#pragma vertex vert#pragma fragment fragstruct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};v2f vert (appdata_base v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = v.texcoord;return o;}fixed4 frag (v2f i) : SV_Target{fixed4 color = tex2D(_MainTex, i.uv);fixed4 value = clamp(luminance(color) - _LuminanmceThreshold, 0, 1);return color * value;}ENDCG}UsePass "ShaderProj/10/GaussianBlur/GAUSSIAN_BLUR_HORIZONTAL"UsePass "ShaderProj/10/GaussianBlur/GAUSSIAN_BLUR_VERTICAL"Pass{CGPROGRAM#pragma vertex vertBloom#pragma fragment fragBloomstruct v2fBloom{float4 pos: SV_POSITION;//xy主要用于对主纹理进行采样//zw主要用于对亮度模糊后的纹理采样half4 uv: TEXCOORD0;};v2fBloom vertBloom(appdata_base v){v2fBloom o;o.pos = UnityObjectToClipPos(v.vertex);o.uv.xy = v.texcoord;o.uv.zw = v.texcoord;// 注意:亮度纹理的UV坐标需要判断是否进行Y轴翻转// 因为使用RENDERTEXTURE写入到SHADER的纹理变量时// UNITY可能会对其进行Y轴翻转// 用宏去判断uv坐标是否被翻转#if UNITY_UV_STARTS_AT_TOP //如果纹素的y小于0 为负数 表示需要对Y轴进行调整if (_MainTex_TexelSize.y < 0) { o.uv.w = 1 - o.uv.w;}#endifreturn o;}fixed4 fragBloom(v2fBloom i):SV_TARGET{return tex2D(_MainTex, i.uv.xy) + tex2D(_Bloom, i.uv.zw);}ENDCG}}Fallback Off
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Bloom : PostEffectBase
{[Range(0, 4)]public float luminanceThreshod = .5f;[Range(1, 8)]public int downSample = 1;[Range(1, 16)]public int iterations = 1;[Range(0, 3)]public float blurSpread = .6f;protected override void OnRenderImage(RenderTexture source, RenderTexture destination) {if (material != null) {material.SetFloat("_LuminanmceThreshold", luminanceThreshod);int rtW = source.width / downSample;int rtH = source.height / downSample;RenderTexture buffer = RenderTexture.GetTemporary(rtW, rtH, 0);//采用双线性过滤模式来缩放 可以让缩放效果更平滑buffer.filterMode = FilterMode.Bilinear;// 提取Graphics.Blit(source, buffer, material, 0);// 模糊for (int i = 0; i < iterations; i++) {material.SetFloat("_BlurSpread", 1 + i * blurSpread);RenderTexture buffer1 = RenderTexture.GetTemporary(rtW, rtH, 0);Graphics.Blit(buffer, buffer1, material, 1); //Color1RenderTexture.ReleaseTemporary(buffer);buffer = buffer1;buffer1 = RenderTexture.GetTemporary(rtW, rtH, 0);Graphics.Blit(buffer, buffer1, material, 2);RenderTexture.ReleaseTemporary(buffer);buffer = buffer1;}material.SetTexture("_Bloom", buffer);// 合成Graphics.Blit(source, destination, material, 3);RenderTexture.ReleaseTemporary(buffer);} else {Graphics.Blit(source, destination);}}
}
相关文章:
Bloom 效果
1、Bloom 效果是什么 Bloom效果(中文也可以叫做高光溢出效果),是一种使画面中亮度较高的区域产生一种光晕或发光效果的图像处理技术,Bloom效果的主要目的是模拟现实世界中强光源在相机镜头或人眼中造成的散射和反射现象ÿ…...
AWS 机器学习,推动 AI 技术的健康发展
目录 一、AI 正在改变生产方式二、从炒作走向务实1、选对场景2、重视数据3、产品思维4、持续优化 三、人才是最稀缺的资源四、负责任的 AI 开发五、未来已来六、启示与思考七、结语 如果说传统软件开发是手工作坊,那么 AI 就像工业革命带来的机器生产。 在最新的一…...
MCPTT 与BTC
MCPTT(Mission Critical Push-to-Talk)和B-TrunC(宽带集群)是两种关键通信标准,它们分别由不同的组织制定和推广。 MCPTT(Mission Critical Push-to-Talk)标准由3GPP(第三代合作伙伴…...
Jackson - JsonGenerator创建JSON、JsonParser解析JSON
以下是关于如何使用Jackson的JsonGenerator类来创建JSON内容以及如何使用JsonParser类来读取JSON内容的教程。 依赖项 首先,在pom.xml文件中添加以下依赖项以引入Jackson库: <dependency><groupId>com.fasterxml.jackson.core</groupI…...
Linux-音频应用编程
ALPHA I.MX6U 开发板支持音频,板上搭载了音频编解码芯片 WM8960,支持播放以及录音功能!本章我们来学习 Linux 下的音频应用编程,音频应用编程相比于前面几个章节所介绍的内容、其难度有所上升,但是笔者仅向大家介绍 Li…...
《QT 示例宝库:探索丰富的编程世界》
《QT 示例宝库:探索丰富的编程世界》 一、QT 基础示例(一)QRadioButton 示例(二)拦截关闭事件示例 二、QT 常用代码示例(一)QObject 相关操作(二)Qt 基本容器遍历&#x…...
腾讯云流式湖仓统一存储实践
点击蓝字⬆ 关注我们 本文共计5107 预计阅读时长16分钟 * 本文将分享腾讯云流式湖仓的架构与实践。主要内容包括: 流计算Oceanus介绍腾讯云流式湖仓架构腾讯云流式湖仓实践腾讯云流式湖仓发展规划 一、流计算Oceanus介绍 随着大数据技术的发展࿰…...
18 设计模式之迭代器模式(书籍遍历案例)
一、什么是迭代器模式 迭代器模式(Iterator Pattern)是一种行为型设计模式,允许客户端通过统一的接口顺序访问一个集合对象中的元素,而无需暴露集合对象的内部实现。这个模式主要用于访问聚合对象(如集合、数组等&…...
超清4K视频素材哪里找?优质下载资源网站分享
我是你们的自媒体UP主小李。现在是高清、4K视频大行其道的时代,想要制作出吸引眼球的优质内容,超清4K视频素材必不可少。今天就为大家分享几个宝藏网站,让你的视频创作更轻松、更出彩! 蛙学网 首先推荐 蛙学网,这是国内…...
刷题日志【1】
目录 1.全排列【力扣】 代码1: 代码2: 2、子集【力扣】 3、全排列Ⅱ【力扣】 4、组合【力扣】 1.全排列【力扣】 代码1: class Solution {bool check[7];vector <int> path;vector<vector<int>> ret;public:vecto…...
【C++算法】32.前缀和_矩阵区域和
文章目录 题目链接:题目描述:解法C 算法代码: 题目链接: 1314. 矩阵区域和 题目描述: 解法 防止有人看不明白题目,先解释一下题目 二维前缀和思想: 使用前缀和矩阵 ret [x1,y1]~[x2,y2] D …...
使用堆栈(Stack)
集合类型(Collection)下篇_xml collection-CSDN博客 以上是堆栈的简单介绍,下方是堆栈的使用 题目:给定一个逆波兰表达式(后缀表达式)的字符串数组tokens,其中每个元素是一个操作数(数字&…...
雨晨 2610(2)0.2510 Windows 11 24H2 Iot 企业版 LTSC 2024 极简 2in1
文件: 雨晨 2610(2)0.2510 Windows 11 24H2 Iot 企业版 LTSC 2024 极简 2in1 install.esd 索引: 1 名称: Windows 11 IoT 企业版 LTSC 极简 26100.2510 描述: Windows 11 IoT 企业版 LTSC 极简 26100.2510 By YCDISM RTM 2025 24-12-07 大小: 8,176,452,990 个字节 索引: 2 …...
HDD 2025年技术趋势深度分析报告
随着数据量的指数级增长以及人工智能(AI)、物联网(IoT)、云计算和视频监控等领域的需求激增,硬盘驱动器(HDD)行业正面临着前所未有的挑战与机遇。本报告旨在深入剖析2025年HDD技术的发展方向&am…...
算法-字符串-22.括号生成
一、题目 二、思路解析 1.思路: 生成所有可能并且有效的括号组合——回溯方法 2.常用方法: a.数组,因为需要增删元素,所以选择LinkedList LinkedList<String> resnew LinkedList<>(); b.StringBuilder创建࿰…...
Free-RTOS实现LED闪烁
开发板:正点原子探索者 F407 LED定时定时闪烁 本次实验验证: 配置文件 1、打开CubeMX 2、选择芯片型号,然后点击开始项目 3、配置时钟 配置烧录引脚,与FreeRTOS系统时钟 选择FreeRTOS 这里已经默认有一个任务ÿ…...
NLP论文速读(斯坦福大学)|使用Tree将语法隐藏到Transformer语言模型中正则化
论文速读|Sneaking Syntax into Transformer Language Models with Tree Regularization 论文信息: 简介: 本文的背景是基于人类语言理解的组合性特征,即语言处理本质上是层次化的:语法规则将词级别的意义组合成更大的成分的意义&…...
再谈多重签名与 MPC
目录 什么是 MPC 钱包以及它们是如何出现的 多重签名和智能合约钱包已经成熟 超越 MPC 钱包 关于小队 多重签名已经成为加密货币领域的一部分,但近年来,随着 MPC(多方计算)钱包的出现,多重签名似乎被掩盖了。MPC 钱包之…...
CTF学习24.11.19[音频隐写]
MISC07[音频隐写] 隐写术 隐写术是一门关于信息隐藏的技巧与科学,所谓信息隐藏指的是不让除预期的接收者之外的任何人知晓信息的传递事件或者信息的内容。隐写术的英文叫做Steganography,来源于特里特米乌斯的一本讲述密码学与隐写术的著作Steganograp…...
vue的watch是否可以取消? 怎么取消?
发现宝藏 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【宝藏入口】。 Vue 可以通过 watch API 返回的一个 取消函数,可以在需要时取消该监听。 如何取消 watch? 当你使用 Vu…...
GD32F4实战:在FreeRTOS上跑LWIP,网线热插拔怎么搞才稳?
GD32F4实战:FreeRTOS与LWIP深度整合中的网线热插拔稳定性设计 在工业物联网和边缘计算场景中,嵌入式设备的网络稳定性直接关系到系统可靠性。GD32F4系列作为国产MCU的优秀代表,配合FreeRTOS和LWIP的黄金组合,为开发者提供了高性价…...
Linux下adb调试小米手机报错Exception的5种解决方法(附详细排查步骤)
Linux下adb调试小米手机报错Exception的5种深度解决方案 最近在Linux环境下用adb调试小米手机时,不少开发者遇到了Exception occurred while executing put这个让人头疼的错误。作为一名常年与adb打交道的开发者,我深知这种问题一旦出现,轻则…...
Python中数据分块处理的实现方法
在实际的数据处理任务中,我们经常需要处理大规模数据集。一次性加载所有数据到内存可能会导致内存溢出,这时数据分块处理就显得尤为重要。本文将介绍Python中三种高效的数据分块处理方法。 一、为什么需要数据分块处理? 在处理大型数据集时…...
终极指南:如何用qmc-decoder轻松解锁QQ音乐加密文件
终极指南:如何用qmc-decoder轻松解锁QQ音乐加密文件 【免费下载链接】qmc-decoder Fastest & best convert qmc 2 mp3 | flac tools 项目地址: https://gitcode.com/gh_mirrors/qm/qmc-decoder 你是否曾经从QQ音乐下载了喜爱的歌曲,却发现只能…...
全面解析数据库锁机制:从行锁到死锁的深度剖析
锁是数据库并发控制的核心机制,也是面试中绕不开的高频考点。很多开发者对锁的理解停留在“加锁就行了”,但遇到死锁、锁等待超时、性能骤降等问题时往往束手无策。本文将系统讲解数据库锁的分类、实现原理、锁与事务隔离级别的关系,并结合 M…...
基于SpringBoot + Vue的新农村信息平台建设(角色:企业村民村委会管理员)
文章目录前言一、详细操作演示视频二、具体实现截图三、技术栈1.前端-Vue.js2.后端-SpringBoot3.数据库-MySQL4.系统架构-B/S四、系统测试1.系统测试概述2.系统功能测试3.系统测试结论五、项目代码参考六、数据库代码参考七、项目论文示例结语前言 💛博主介绍&#…...
终极GitHub加速解决方案:让你的代码下载速度提升100倍
终极GitHub加速解决方案:让你的代码下载速度提升100倍 【免费下载链接】Fast-GitHub 国内Github下载很慢,用上了这个插件后,下载速度嗖嗖嗖的~! 项目地址: https://gitcode.com/gh_mirrors/fa/Fast-GitHub 你是否曾经因为G…...
工作中常用linux命令汇总
①启动jar包:nohup java -jar ruoyi-admin.jar > app.log 2>&1 &②指定端口启动jar包:nohup java -jar -Dserver.port8081 ruoyi-admin.jar > app.log 2>&1 &③根据jar包判断启动的进程:jps -l | grep ruoyi-adm…...
mapbox 基于 Turf.js 实现高精度多边形分割(支持带空洞 / 坐标无损)
在 GIS 前端开发中,多边形分割是高频需求(如图斑拆分、地块划分)。本文基于 Turf.js 封装了一套高精度多边形分割工具类,支持普通模式 / 兼容模式,可处理带空洞的多边形,且能 100% 保留原始坐标,…...
开源大模型部署新选择:cv_unet_image-colorization低门槛AI视觉实践
开源大模型部署新选择:cv_unet_image-colorization低门槛AI视觉实践 1. 引言 你是否翻出过家里的老相册,看着那些泛黄的黑白照片,想象着它们当年真实的色彩?或者,作为一名内容创作者,你是否曾为一张构图完…...
