C for Graphic:径向模糊

最近要做一系列特效需求,顺便记录一下。

径向模糊(也叫辐射模糊):一种由内向外发散的模糊的效果

原理:获取中心点(centeruv)到当前像素(pixeluv)的朝向法向量(ndir),pixeluv沿着ndir进行向前向后的像素颜色采样,并叠加到当前像素颜色(pixelcolor)

和以前聊过的高斯滤器模糊有点类似,核心都是将其他像素颜色叠加到当前像素颜色,无非叠加的计算规则不同

画个图:
以pixeluv为起点,ndir为朝向,向外、向内、或两端同时采样颜色进行叠加,为了保证叠加后亮度的统一,除以采样次数进行衰减即可

csharp 复制代码
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RadialBlurScreenEffect : MonoBehaviour
{
    public Material mat;

    [Range(1, 5)]
    public int downSample = 2;

    private int downWidth;
    private int downHeight;

    void Start()
    {
        downWidth = Screen.width / downSample;
        downHeight = Screen.height / downSample;
    }

    private void Update()
    {
        if (Input.GetMouseButton(1))
        {
            Vector2 spos = Input.mousePosition;
            Vector2 uv = new Vector2(spos.x / Screen.width, spos.y / Screen.height);
            mat.SetVector("_CenterUV", uv);
        }
    }

    private void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        if (mat != null)
        {
            //为了性能考虑,先降采样
            RenderTexture downRt = RenderTexture.GetTemporary(downWidth, downHeight, 0, RenderTextureFormat.ARGB32);

            Graphics.Blit(source, downRt);

            Graphics.Blit(downRt, destination, mat);

            RenderTexture.ReleaseTemporary(downRt);
        }
        else
        {
            Graphics.Blit(source, destination);
        }
    }
}

后处理控制器,降采样提升效率

csharp 复制代码
Shader "RadialBlur/RadialBlurImageEffectShader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _CenterUV("Center UV",vector) = (0.5,0.5,0,0)
        _SampleCount("Sample Count",Range(5,30)) = 10
        _SampleDistance("Sample Distance",Range(0.005,0.03)) = 0.01
        [Enum(InOut,1,In,2,Out,3)]_InOut("In Out Type",int) = 0
    }
    SubShader
    {
        // No culling or depth
        Cull Off ZWrite Off ZTest Always

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
                float2 ndir : TEXCOORD1;
            };

            float2 _CenterUV;
            int _SampleCount;
            float _SampleDistance;
            int _InOut;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                o.ndir = normalize(o.uv-_CenterUV.xy);
                return o;
            }

            sampler2D _MainTex;

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = fixed4(0,0,0,0);
                  
                fixed2 dir = i.ndir;

                if(_InOut == 1)
                {
                    int halfsample = _SampleCount/2;
                    for(int x=0;x<_SampleCount;x++)
                    {
                        int offset = x-halfsample;
                        col += (tex2D(_MainTex,i.uv+dir*(offset*_SampleDistance))/(float)_SampleCount);
                    }
                }
                else if(_InOut == 2)
                {
                    for(int x=0;x<_SampleCount;x++)
                    {
                        col += (tex2D(_MainTex,i.uv+dir*(x*_SampleDistance))/(float)_SampleCount);
                    }
                }
                else if(_InOut == 3)
                {
                    for(int x=0;x<_SampleCount;x++)
                    {
                        col += (tex2D(_MainTex,i.uv-dir*(x*_SampleDistance))/(float)_SampleCount);
                    }
                }
                return col;
            }
            ENDCG
        }
    }
}

后处理着色器,原理就是叠加颜色

最终效果如下:

ok,今天就到这里。

相关推荐
向宇it26 分钟前
【unity组件介绍】URP Decal Projector贴花投影器,将特定材质(贴花)投影到场景中的其他对象上。
游戏·3d·unity·c#·游戏引擎·材质
快乐觉主吖11 小时前
Unity网络通信的插件分享,及TCP粘包分包问题处理
tcp/ip·unity·游戏引擎
啊基米德2 天前
lua(xlua)基础知识点记录一
unity·lua·xlua
夜色。2 天前
Unity Android Logcat插件 输出日志中文乱码解决
android·unity
X-mj2 天前
Unity URP + XR 自定义 Skybox 在真机变黑问题全解析与解决方案(支持 Pico、Quest 等一体机)
unity·游戏引擎·xr
心疼你的一切2 天前
Unity 多人游戏框架学习系列一
学习·游戏·unity·c#·游戏引擎
示申○言舌3 天前
Unity沉浸式/360View/全景渲染
unity·游戏引擎·沉浸式·360view·全景视图·全景渲染
Unity___3 天前
Unity Editor下拉框,支持搜索,多层级
windows·unity·游戏引擎
枯萎穿心攻击3 天前
响应式编程入门教程第三节:ReactiveCommand 与 UI 交互
开发语言·ui·unity·架构·c#·游戏引擎·交互
死也不注释3 天前
第一章编辑器开发基础第一节绘制编辑器元素_4输入字段(4/7)
unity·编辑器