Unity Shader学习(七)---bloom效果

本文详细介绍了如何使用Unity的Shader实现bloom效果,包括高斯模糊的步骤和代码实现,以及最终整合到bloom效果中的过程。通过多次迭代计算模糊,并通过调整模糊半径和采样率来控制效果。
摘要由CSDN通过智能技术生成
(一)bloom效果(全屏泛光)的基本原理
先了解HDR技术:就是用有限的高度分布模拟更高范围的高亮度分布,实现这样的功能的技术叫做色调映射技术(Tone Mapping)。
Tone Mapping计算像素的亮度:
Lum(P) = 0.27R + 0.67G + 0.06B
Lscale(x,y) = a * Lum(x,y)/Lumave---Lumave平局亮度
Lfinal = Lscale/(1+Lscale)
光晕效果就是抽出场景中色彩比较亮的部分,加以模糊,使较亮的像素扩散到周边的像素中,再把模糊后的图像叠加到Tone Mapping之后的图像上。
 那么HDR与bloom效果的差别到底在什么地方呢?
第一,HDR效果就是超亮的光照与超暗的黑暗的某种结合,这个效果是光照产生的,强度、颜色等方面是游戏程序可动态控制的,是一种即时动态光影;bloom效果则是物体本身发出的光照,仅仅是将光照范围调高到过饱和,是游戏程序无法动态控制的,是一种全屏泛光。
第二,bloom效果无需HDR就可以实现,但是bloom效果是很受限的,它只支持8位RGBA,而HDR最高支持到32位RGBA。
第三,bloom效果的实现很简单,比如《半条命2》的MOD就是一个很小的很简单的MOD,而且bloom效果不受显卡的规格的限制,你甚至可以在TNT显卡上实现bloom效果(当然效果很差)!而HDR,必须是6XXX以上的显卡才能够实现,这里的HDR是指nVIDIA的HDR。这时有必要谈nVIDIA和ATI的显卡所实现的HDR,两者还是有区别的,具体区别就很专业了,总之从真实性表现来看,nVIDIA的显卡实现的HDR更好一些。HDR是nVIDIA提出的概念,从技术上来讲,ATI当然无法严格克隆nVIDIA的技术,所以ATI的HDR是另一种途径实现的尽可能接近的HDR,不能算“真”HDR,据传ATI的R520能够真正实现FP16 HDR。
Bloom效果实现的流程与HDR的物理还原不同,它只是一种简单的近似模拟:
第一步:先获取屏幕图像,然后对每个像素进行亮度检测,若大于某个阀值即保留原始颜色值,否则置为黑色;
第二步:对上一步获取的图像,做一个模糊,通常使用高斯模糊。
第三步:将模糊后的图片和原图片做一个加权和。

通过这三步就可以达到一个全屏泛光的效果。

(二)高斯模糊

对于一个五维的高斯核,我们需要的是3个权重值就可以,由于对称性。高斯方程很好的模拟了每个像素对于当前处理像素的影响程度,距离越近,影响越大。

程序部分:

using UnityEngine;
using System.Collections;

public class GaussianBlur : PostEffectsBase {

    public Shader gaussianBlurShader;
    private Material gaussianBlurMaterial = null;

    public Material material {   
        get {
            gaussianBlurMaterial = CheckShaderAndCreateMaterial(gaussianBlurShader, gaussianBlurMaterial);
            return gaussianBlurMaterial;
        }  
    }

    // Blur iterations - larger number means more blur.
    [Range(0, 4)]
    public int iterations = 3;
    
    // Blur spread for each iteration - larger value means more blur
    [Range(0.2f, 3.0f)]
    public float blurSpread = 0.6f;
    [Range(1, 8)]
    public int downSample = 2;
    
    /// 3rd edition: use iterations for larger blur
    void OnRenderImage (RenderTexture src, RenderTexture dest) {
        if (material != null) {
            int rtW = src.width/downSample;//利用缩放对图样进行采样,减少需要处理的像素个数
            int rtH = src.height/downSample;

            RenderTexture buffer0 = RenderTexture.GetTemporary(rtW, rtH, 0);
            buffer0.filterMode = FilterMode.Bilinear;

            Graphics.Blit(src, buffer0);

            for (int i = 0; i < iterations; i++) { //多次迭代计算模糊
                material.SetFloat("_BlurSize", 1.0f + i * blurSpread);

                RenderTexture buffer1 = RenderTexture.GetTemporary(rtW, rtH, 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值