版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
UnityShader开发之径向模糊(可调节中心点 、 可调整中心点周围有一圈不模糊)
原图:
1. 无模糊开始半径
1.1 算法
(1)求得当前像素坐标与模糊中心点的坐标相减求得的带有大小的方向向量
(2)取得方向向量上的值,将方向向量切分为整数倍份(例如10份),分别取得当模糊中心点加上每份方向向量后取得的坐标所对应的颜色值,累加起来。(取小于方向向量的等分是为了将内部的颜色发散出去,如果需要聚焦,即缩小,则取倍数于其方向向量上的颜色值)
(3)除于切分成的数量,取到的就是当前像素点的值
1.2 代码
1.2.1 C#端
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]//在编辑器模式下也运行
[RequireComponent(typeof(Camera))]//必须有Camera组件
public class RadiaBlur :MonoBehaviour{
public Shader RadiaBlurShader;
public Material RadiaBlurMaterial;
[Range(1,100)]
public float Level = 10;
[Range(0, 1)]
public float CenterX = 0.5f;
[Range(0, 1)]
public float CenterY = 0.5f;
private void Awake()
{
RadiaBlurMaterial = new Material(RadiaBlurShader);
}
void OnRenderImage(RenderTexture src, RenderTexture dest)
{
if (RadiaBlurMaterial != null)
{
RadiaBlurMaterial.SetFloat("_Level", Level);
RadiaBlurMaterial.SetFloat("_CenterX", CenterX);
RadiaBlurMaterial.SetFloat("_CenterY", CenterY);
Graphics.Blit(src, dest, RadiaBlurMaterial);
}
else
{
Graphics.Blit(src, dest);
}
}
}
1.2.2 Shader
Shader "Custom/RadiaBlur" {
Properties {
_MainTex("纹理",2D)="while"{}
_Level("强度",Range(1,100))=10
_CenterX("中心X坐标",Range(0,1))=0.5
_CenterY("中心Y坐标",Range(0,1))=0.5
_BufferRadius("缓冲半径",Range(0,1))=0
}
SubShader {
Tags { "RenderType"="Opaque" }
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
float _Level;
float _CenterX;
float _CenterY;
float _BufferRadius;
struct v2f{
fixed4 vertex:POSITION;
fixed2 uv:TEXCOORD;
};
v2f vert(appdata_base v)
{
v2f o;
o.vertex=UnityObjectToClipPos(v.vertex);
o.uv=v.texcoord;
return o;
}
fixed4 frag(v2f i):COLOR
{
fixed4 finalColor;
fixed2 center=fixed2(_CenterX,_CenterY);
fixed2 uv=i.uv-center;
fixed3 tempColor=fixed3(0,0,0);
fixed blurParams=distance(i.uv,center);
for(fixed j=0;j<_Level;j++){
tempColor+=tex2D(_MainTex,uv*(1-0.01*j)+center).rgb;
}
finalColor.rgb=tempColor/_Level;
finalColor.a=1;
return finalColor;
}
ENDCG
}
}
FallBack "Diffuse"
}
1.3 效果图
Level:16
CenterX:0.5
CenterY:0.5
2.具有模糊缓冲半径
2.1 算法
(1)求得当前像素坐标与模糊中心点的坐标相减求得的带有大小的方向向量
(2)取得方向向量上的值,将方向向量切分为整数倍份(例如10份),然后将乘于影响因素(距离/缓冲半径),这样子就可以通过控制缓冲半径来控制模糊开始的半径
(3)分别取得当模糊中心点加上每份经过处理后的方向向量后取得的坐标所对应的颜色值,进行累加
(4)除于切分成的数量,取到的就是当前像素点的值。
2.2 代码
2.2.1 C#端
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]//在编辑器模式下也运行
[RequireComponent(typeof(Camera))]//必须有Camera组件
public class RadiaBlur :MonoBehaviour{
public Shader RadiaBlurShader;
public Material RadiaBlurMaterial;
[Range(1,100)]
public float Level = 10;
[Range(0, 1)]
public float BufferRadius = 0.5f;
[Range(0, 1)]
public float CenterX = 0.5f;
[Range(0, 1)]
public float CenterY = 0.5f;
private void Awake()
{
RadiaBlurMaterial = new Material(RadiaBlurShader);
}
void OnRenderImage(RenderTexture src, RenderTexture dest)
{
if (RadiaBlurMaterial != null)
{
RadiaBlurMaterial.SetFloat("_Level", Level);
RadiaBlurMaterial.SetFloat("_CenterX", CenterX);
RadiaBlurMaterial.SetFloat("_CenterY", CenterY);
RadiaBlurMaterial.SetFloat("_BufferRadius", BufferRadius);
Graphics.Blit(src, dest, RadiaBlurMaterial);
}
else
{
Graphics.Blit(src, dest);
}
}
}
2.2.2 Shader
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Custom/RadiaBlur" {
Properties {
_MainTex("纹理",2D)="while"{}
_Level("强度",Range(1,100))=10
_CenterX("中心X坐标",Range(0,1))=0.5
_CenterY("中心Y坐标",Range(0,1))=0.5
_BufferRadius("缓冲半径",Range(0,1))=0
}
SubShader {
Tags { "RenderType"="Opaque" }
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
float _Level;
float _CenterX;
float _CenterY;
float _BufferRadius;
struct v2f{
fixed4 vertex:POSITION;
fixed2 uv:TEXCOORD;
};
v2f vert(appdata_base v)
{
v2f o;
o.vertex=UnityObjectToClipPos(v.vertex);
o.uv=v.texcoord;
return o;
}
fixed4 frag(v2f i):COLOR
{
fixed4 finalColor;
fixed2 center=fixed2(_CenterX,_CenterY);
fixed2 uv=i.uv-center;
fixed3 tempColor=fixed3(0,0,0);
fixed blurParams=distance(i.uv,center);
for(fixed j=0;j<_Level;j++){
tempColor+=tex2D(_MainTex,uv*(1-0.01*j*saturate( blurParams/_BufferRadius))+center).rgb;
}
finalColor.rgb=tempColor/_Level;
finalColor.a=1;
return finalColor;
}
ENDCG
}
}
FallBack "Diffuse"
}
2.3 效果图
Level:16
CenterX:0.5
CenterY:0.5
BufferRadius:0.5