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…...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
