Ylisar 发表于 2022-6-8 20:50

Unity3D分层的Bloom(泛光)效果(一)

前几天接了个需求,给自己参与的Unity项目添加一个屏幕后处理泛光效果,要求只能是灯有泛光效果,而其它不发光的物体不能出现泛光的效果。在写这个特效的时候遇到了一些坑,并且在网上查找解决方案的时候网上往往说的都是全屏的泛光效果,而对于需要分层的泛光效果能找到的资料很少。因此在这里记录一下,一方面加强一下自己的记忆另一方面希望能帮到有同样需求的同学。下面展示一组从LearnOpenGL盗来的没有泛光效果与添加了泛光效果的对比图:


       从这组对比图中我们可以体会到,泛光可以极大提升场景中的光照效果。有泛光效果的场景让更符合现实世界中的情况。
       基于屏幕后处理的泛光效果一种比较简单的屏幕后处理的特效,可以分为以下几步实现:1.在一张纹理A中提取屏幕中的光亮区域,存储在一张渲染纹理B中;2.对B渲染纹理进行高斯模糊处理,得到纹理C;3.将经过高斯模糊处理的纹理C与纹理A进行混合,将结果输出即可。
       下面我们来实现一遍上面的步骤,先实现shader部分:
       提取光亮部分其实就是将采样得到的颜色转换为亮度,如果该亮度大于我们设定的阈值,则该点为一个亮点
Shader "Unlit/Bloom"
{
    Properties
    {
      _MainTex("输入的渲染纹理", 2D) = "white" {}
      _Bloom("高斯模糊后的较亮区域", 2D) = "black" {}
      _LuminanceThreshold("用于提取较亮区域的阈值", Float) = 0.5
      _BlurSize("用于控制不同迭代之间的高斯模糊的模糊区域范围", Float) = 1.0
    }

    SubShader
    {
      CGINCLUDE

      #include "UnityCG.cginc"

      sampler2D _MainTex;
      half4 _MainTex_TexelSize;
      sampler2D _Bloom;
      float _LuminanceThreshold;
      float _BlurSize;

      struct v2f
      {
            float4 pos : SV_POSITION;
            half2 uv : TEXCOORD0;
      };

      // 顶点着色器
      v2f vertExtractBright(appdata_img v)
      {
            v2f o;
            o.pos = UnityObjectToClipPos(v.vertex);
            o.uv = v.texcoord;
            return o;
      }

      // 将传入的颜色转换为亮度
      fixed luminance(fixed4 color)
      {
            return0.2125 * color.r + 0.7154 * color.g + 0.0721 * color.b;
      }

      // 片元着色器
      fixed4 fragExtractBright(v2f i) : SV_Target
      {

mypro334 发表于 2022-6-8 20:55

我有个问题你摄像机都设置false了
只调用render就可以了吗

johnsoncodehk 发表于 2022-6-8 21:05

对,即使将摄像机的激活状态设置为false,调用Render方法也会强制摄像机进行一次渲染,该方法更多的介绍可以查看Unity - Scripting API: Camera.Render

Doris232 发表于 2022-6-8 21:06

所以说还是用了2个摄像机喽。
页: [1]
查看完整版本: Unity3D分层的Bloom(泛光)效果(一)