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,今天就到这里。

相关推荐
向宇it31 分钟前
【从零开始入门unity游戏开发之——C#篇25】C#面向对象动态多态——virtual、override 和 base 关键字、抽象类和抽象方法
java·开发语言·unity·c#·游戏引擎
_oP_i2 小时前
unity webgl部署到iis报错
unity
Go_Accepted2 小时前
Unity全局雾效
unity
向宇it2 小时前
【从零开始入门unity游戏开发之——C#篇24】C#面向对象继承——万物之父(object)、装箱和拆箱、sealed 密封类
java·开发语言·unity·c#·游戏引擎
每日出拳老爷子5 小时前
【图形渲染】【Unity Shader】【Nvidia CG】有用的参考资料链接
unity·游戏引擎·图形渲染
北海65166 小时前
Dots 常用操作
unity
YY-nb13 小时前
Unity Apple Vision Pro 开发教程:物体识别跟踪
unity·游戏引擎·apple vision pro
Cool-浩13 小时前
Unity 开发Apple Vision Pro物体识别追踪ObjectTracking
unity·ar·apple vision pro·mr·物体识别·vision pro教程·objecttracking
向宇it1 天前
【从零开始入门unity游戏开发之——C#篇23】C#面向对象继承——`as`类型转化和`is`类型检查、向上转型和向下转型、里氏替换原则(LSP)
java·开发语言·unity·c#·游戏引擎·里氏替换原则
Cool-浩1 天前
Unity 开发Apple Vision Pro空间锚点应用Spatial Anchor
unity·游戏引擎·apple vision pro·空间锚点·spatial anchor·visionpro开发