Unity shader学习之屏幕后期处理效果之Bloom效果

本文介绍游戏开发中Bloom特效的实现原理及过程。通过提取图像中的高亮度区域并进行高斯模糊处理,模拟真实摄像机的光线扩散效果。包含Unity代码示例及Shader编写。

Bloom特效是游戏中常见的一种屏幕效果。这种特效可以模拟真实摄像机的一种图像效果,它让画面中较亮的区域“扩散”到周围的区域中,造成一种朦胧的效果。

Bloom的实现原理很简单,首先根据一个阈值提取出图像中较亮的区域,把它们存储在一张渲染纹理中,再利用高斯模糊对这张渲染纹理进行模糊处理,模拟光线扩散的效果,最后再将其和原图像进行混合,得到最终的效果。

转载请注明出处:http://www.cnblogs.com/jietian331/p/7243444.html

如实现代码如下:

复制代码
 1 using UnityEngine;
 2 
 3 public class BloomRenderer : PostEffectRenderer
 4 {
 5     [Range(0f, 4f)]
 6     public float m_threshold = 0.4f;        // 光阈值
 7     [Range(1, 8)]
 8     public int m_downSample = 2;      // 降采样率
 9     [Range(0, 4)]
10     public int m_iterations = 3;        // 迭代次数
11     [Range(0.2f, 3f)]
12     public float m_blurSpread = 0.6f;        // 模糊扩散量
13 
14     protected override void OnRenderImage(RenderTexture src, RenderTexture dest)
15     {
16         int w = (int)(src.width / m_downSample);
17         int h = (int)(src.height / m_downSample);
18 
19         RenderTexture buffer0 = RenderTexture.GetTemporary(w, h);
20         RenderTexture buffer1 = RenderTexture.GetTemporary(w, h);
21         buffer0.filterMode = FilterMode.Bilinear;
22         buffer1.filterMode = FilterMode.Bilinear;
23 
24         // 提取亮光图
25         Mat.SetFloat("_Threshold", m_threshold);
26         Graphics.Blit(src, buffer0, Mat, 0);
27 
28         // 将亮光图高斯模糊化
29         for (int i = 0; i < m_iterations; i++)
30         {
31             Mat.SetFloat("_BlurSpread", 1 + i * m_blurSpread);
32 
33             Graphics.Blit(buffer0, buffer1, Mat, 1);
34             Graphics.Blit(buffer1, buffer0, Mat, 2);
35         }
36 
37         // 将亮光图与原图混合
38         Mat.SetTexture("_Bloom", buffer0);
39         Graphics.Blit(src, dest, Mat, 3);
40 
41         RenderTexture.ReleaseTemporary(buffer0);
42         RenderTexture.ReleaseTemporary(buffer1);
43     }
44 
45     protected override string ShaderName
46     {
47         get { return "Custom/Bloom"; }
48     }
49 }
复制代码

 

shader如下:

复制代码
  1 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
  2 
  3 Shader "Custom/Bloom"
  4 {
  5     Properties
  6     {
  7         _MainTex("Main Texture", 2D) = "white" {}
  8         _Threshold("Threshold", float) = 0.6
  9         _Bloom("Bloom", 2D) = "white" {}
 10     }
 11 
 12     SubShader
 13     {
 14         ZTest Always
 15         ZWrite Off
 16         Cull Off
 17 
 18         Pass
 19         {
 20             CGPROGRAM
 21             #pragma vertex vert
 22             #pragma fragment frag
 23             
 24             sampler2D _MainTex;
 25             float _Threshold;
 26 
 27             struct appdata
 28             {
 29                 float4 vertex : POSITION;
 30                 float2 uv : TEXCOORD0;
 31             };
 32 
 33             struct v2f
 34             {
 35                 float4 pos : SV_POSITION;
 36                 float2 uv : TEXCOORD0;
 37             };
 38 
 39             v2f vert(appdata v)
 40             {
 41                 v2f o;
 42                 o.pos = UnityObjectToClipPos(v.vertex);
 43                 o.uv = v.uv;
 44                 return o;
 45             }
 46 
 47             fixed4 frag(v2f i) : SV_TARGET
 48             {
 49                 fixed4 tex = tex2D(_MainTex, i.uv);
 50                 float lumiance = dot(fixed3(0.2125, 0.7154, 0.0721), tex.rgb);
 51                 return tex * saturate(lumiance - _Threshold);
 52             }
 53 
 54             ENDCG
 55         }
 56 
 57         UsePass "Custom/Gaussian Blur/HORIZONTAL"
 58         UsePass "Custom/Gaussian Blur/VERTICAL"
 59 
 60         Pass
 61         {
 62             CGPROGRAM
 63             #pragma vertex vert
 64             #pragma fragment frag
 65             
 66             sampler2D _MainTex;
 67             sampler2D _Bloom;
 68 
 69             struct appdata
 70             {
 71                 float4 vertex : POSITION;
 72                 float2 uv : TEXCOORD0;
 73             };
 74 
 75             struct v2f
 76             {
 77                 float4 pos : SV_POSITION;
 78                 float2 uv : TEXCOORD0;
 79             };
 80 
 81             v2f vert(appdata v)
 82             {
 83                 v2f o;
 84                 o.pos = UnityObjectToClipPos(v.vertex);
 85                 o.uv = v.uv;
 86                 return o;
 87             }
 88 
 89             fixed4 frag(v2f i) : SV_TARGET
 90             {
 91                 fixed4 tex = tex2D(_MainTex, i.uv);
 92                 fixed4 bloom = tex2D(_Bloom, i.uv);
 93                 return fixed4(tex.rgb + bloom.rgb, tex.a);
 94             }
 95 
 96             ENDCG
 97         }
 98     }
 99 
100     Fallback Off
101 }
复制代码

 

调整参数:

效果如下:

 

Unity 中实现相机后期处理效果,通常使用 **Post Processing Stack**(后处理栈)技术,这是一种基于着色器的图像处理系统,允许开发者在最终渲染图像上应用多种视觉效果,例如模糊、色调调整、景深、抗锯齿等。以下是实现相机后期处理效果的具体步骤和方法: ### 1. 配置项目以支持后处理 首先,确保项目中已安装 **Post Processing** 包。可以通过 Unity 的 Package Manager 安装该包,或者使用 URP(Universal Render Pipeline)自带的后处理功能。 - 在 URP 中启用后处理功能,需确保 `Renderer` 中启用了 Post Processing 选项。 - 创建一个 **Post Processing Volume**,用于定义后处理效果的作用范围和参数。 ### 2. 创建和配置 Post Processing Volume 在场景中创建一个空 GameObject,并为其添加 **Post Process Volume** 组件。该组件允许定义后处理效果的影响范围(如全局或局部)以及混合方式。 - 设置 **Is Global** 属性以决定是否对整个场景生效。 - 添加 **Post Process Layer** 组件到相机上,以确保该相机参与后处理效果的渲染。 ### 3. 添加后处理效果 通过 **Post Process Profile** 来定义具体的效果集合。可以在 Volume 组件中添加如下常见后处理效果: - **Bloom**:增强高亮区域,模拟光晕效果。 - **Color Grading**:调整整体色调、饱和度、对比度等。 - **Depth of Field**:模拟景深效果,使焦点外的物体模糊。 - **Motion Blur**:模拟运动模糊,增强动态画面的真实感。 - **Vignette**:添加暗角效果,突出画面中心。 - **Chromatic Aberration**:模拟镜头色差,增加画面风格化。 这些效果可以通过在 Profile 中启用相应模块并调整参数来实现[^1]。 ### 4. 多相机独立后处理 若希望为不同相机应用不同的后处理效果,可分别为每个相机创建独立的 Post Processing Volume,并设置其 **Culling Mask** 和 **Layer** 属性,确保只影响特定相机渲染的内容。 - 使用 **Target Texture** 将相机渲染到纹理,再对该纹理应用后处理效果。 - 通过调整 **Volume Weight** 控制后处理效果的强度和混合方式。 ### 5. 性能优化与调试 - 后处理效果可能对性能有一定影响,特别是在移动平台或低端设备上。建议通过降低分辨率、关闭不必要的效果或使用轻量级替代方案进行优化。 - 使用 **Frame Debugger** 工具查看后处理阶段的渲染流程,排查性能瓶颈或渲染异常。 ### 示例代码:创建后处理 Profile ```csharp using UnityEngine; using UnityEngine.Rendering.PostProcessing; public class PostProcessingSetup : MonoBehaviour { public PostProcessVolume volume; void Start() { // 创建一个新的后处理配置文件 PostProcessProfile profile = new PostProcessProfile(); profile.name = "Custom Post Processing"; // 添加颜色调整效果 profile.AddSettings<ColorGrading>(); var colorGrading = profile.GetSetting<ColorGrading>(); colorGrading.active = true; colorGrading.contrast.value = 1.2f; colorGrading.saturation.value = 0.8f; // 添加 Bloom 效果 profile.AddSettings<Bloom>(); var bloom = profile.GetSetting<Bloom>(); bloom.active = true; bloom.intensity.value = 2.0f; // 应用配置文件到 Volume volume.profile = profile; } } ``` ### 6. 自定义后处理效果 如果内置效果无法满足需求,可以编写自定义 Shader 和 Post Process Effect Shader Graph 来实现特定视觉风格。Unity 提供了 **Shader Graph** 工具简化着色器开发流程,同时支持 **VFX Graph** 实现更复杂的视觉特效。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值