TA入门笔记(二十一)

参考
may佬《技术美术百人计划》
冯乐乐《UnityShader 入门精要》
Unity 关于仿崩坏3部分Bloom(部分泛光)效果实现原理
Y(luma)=0.2126 R + 0.7152 G + 0.0722 B
https://github.com/mattatz/unity-mask-bloom

图形4.1 Bloom算法 辉光效果

Bloom算法介绍

效果展示

画面中发亮的部分扩散到周围的效果。如下图中机甲周围的光晕
在这里插入图片描述下图对比中可以看到,使用了Bloom的画面远处的云更亮了,并且带有一种朦胧的感觉

在这里插入图片描述
对于会发光的特效比如烟花来说,是否使用Bloom的差距还是比较大的

在这里插入图片描述

定义

Bloom,也称辉光效果,用来模拟真实世界中摄像机的图像效果,可以让画面中比较亮的区域扩散到周围来达到真实的明亮效果

在这里插入图片描述

实现思路

通过设定阈值来提取原图像中比较亮的区域,然后利用高斯模糊对提取后的图像进行模糊处理来模拟光线向外扩散的效果,最后将模糊后的图像与原图像进行混合来得到最后的Bloom效果
在这里插入图片描述

前置知识

HDR

复习:图形2.7 LDR与HDR

LDR(Low Dynamic Range,低动态范围)

  • jpg、png格式图片
  • RGB范围在[0,1]之间

HDR(High Dynamic Range,高动态范围)

  • HDR、EXR格式图片
  • RGB范围可在[0,1]之外
高斯模糊

高斯模糊(Gaussian Blur)是一种图像模糊的方式,能够减少图像噪声、降低细节层次。本质上是通过高斯函数去定义一个卷积核,再利用这个卷积核对图像进行卷积运算,从而达到平滑效果
在这里插入图片描述

卷积:利用一个卷积核对图像中的每个像素进行操作,卷积核通常为正方形,每个格子内会有一个权重值

  • 图为不同尺寸的卷积核
    在这里插入图片描述

将卷积核的中心放在图像的起始像素上,对卷积核翻转180度后依次计算核中每个元素和对应被核覆盖的像素乘积并求和,得到的结果就是这个位置的新像素;之后重复这一步骤直到全部的像素的值被重新计算。
请添加图片描述

高斯模糊使用的卷积核为高斯核,通过高斯函数计算出核内的权重值,为了保证卷积后的图像不变暗,需要对权重进行归一化(每个权重/权重总和)

  • 图为一个大小为3×3,标准差σ=1.5的高斯核计算过程
    在这里插入图片描述

高斯核的一些性质:

  • 高斯核越大,对图像的模糊效果越明显
    请添加图片描述

  • 二维高斯核的计算量很大,一张w × h的图片使用n × n的卷积核需要进行n × n × w × h次纹理采样

  • 高斯核具有可分离性,二维高斯核可以拆成两个一维高斯核。使用两个一维高斯核先后对图像进行卷积,结果与使用二维高斯核一样,但是计算量会变为2 × n × w × h
    请添加图片描述
    高斯核具有对称性,如一个一维的高斯核只需要记录三个权重值

Bloom效果实现

实现思路

  • C#:在脚本中调用OnRenderImage函数得到当前的渲染纹理,将实现Bloom效果的参数和这张渲染纹理传到shader
  • shader:使用4个Pass来完成Bloom效果
    • 第一个Pass用来根据设定的阈值
    • 第二三个Pass用来对图像分别进行竖直方向和水平方向的高斯模糊
    • 第四个Pass用来将模糊前后的图像与原图进行叠加得到最终的Bloom效果

C#:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Bloom : PostEffectsBase
{
   
    //1.首先声明Bloom效果需要的shader及需要的材质
    public Shader BloomShader;
    private Material BloomMaterial = null;
    //2.定义该material,在get方法里调用这个函数进行检查
    public Material material
    {
   
        get
        {
   
            BloomMaterial = CheckShaderAndCreateMaterial(BloomShader, BloomMaterial);
            return BloomMaterial;
        }
    }
    //3.定义需要传给shader的参数
    [Range(0, 4)]
    public int iterations = 3;                  //高斯模糊的迭代次数,迭代次数越多越模糊
    [Range(0.2f, 3.0f)]
    public float blurSpread = 0.6f;             //高斯模糊的范围
    [Range(1, 8)]
    public int downSample = 2;                  //下采样次数,越大则渲染纹理就越小,需要模糊的像素也越少
    [Range(0.0f, 4.0f)]
    public float luminanceThreshold = 0.6f;      //阈值,因为会开启HDR所以可以大于1

    //4.使用OnRenderImage函数获取当前的屏幕图像的渲染纹理
    void OnRenderImage(RenderTexture src, RenderTexture dest)
    
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值