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

相关推荐
HONT16 小时前
Unity Crest Ocean System源码阅读
shader
那个村的李富贵16 小时前
Unity打包Webgl后 本地运行测试
unity·webgl
nnsix17 小时前
Unity OpenXR开发HTC Vive Cosmos
unity·游戏引擎
nnsix18 小时前
Unity OpenXR,扳机键交互UI时,必须按下扳机才触发
unity·游戏引擎
nnsix18 小时前
Unity XR 编辑器VR设备模拟功能
unity·编辑器·xr
老朱佩琪!18 小时前
Unity访问者模式
unity·游戏引擎·访问者模式
不定时总结的那啥18 小时前
Unity实现点击Console消息自动选中预制体的方法
unity·游戏引擎
nnsix19 小时前
Unity OpenXR 关闭手柄的震动
unity·游戏引擎
CreasyChan19 小时前
Unity 中的反射使用详解
unity·c#·游戏引擎·游戏开发
Jessica巨人19 小时前
Shader显示为黑色
unity·shader