这是我在《游戏架构-核心技术与面试精粹》看的,记录一下~
模糊原理:
当颜色的边缘不清楚时,就会呈现出模糊效果
核心就是:如何处理当前颜色受周围颜色的影响
最简单的就是:均值模糊
均值采样周围的像素值与原值混合,这样自身的色值就不那么突出了,从而达到模糊的效果
实现原理:
用两层 for 循环分别取得一个方形区域的点,算出这些颜色的平均值
(这个过程叫做:卷积)
代码如下:
Shader "Custom/Blur"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_BlurRadius ("_BlurRadius", Range(1, 10)) = 5
_TextureSizeX ("_TextureSizeX", Float) = 256
_TextureSizeY ("_TextureSizeY", Float) = 256
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
int _BlurRadius;
float _TextureSizeX;
float _TextureSizeY;
fixed4 BlurTextrue(float2 uv, float blurRadius, float textureSizeX, float textureSizeY)
{
float pixedDisX = 1.0 / textureSizeX;//像素间距X
float pixedDisY = 1.0 / textureSizeY;//像素间距Y
int count = blurRadius * 2 + 1;//每行的像素数量
count *= count;//总格子数
float4 tmpColor = float4(0, 0, 0, 0);
for (int x = -blurRadius; x <= blurRadius ; x++)
{
for (int y = -blurRadius; y <= blurRadius ; y++)
{
float4 color = tex2D( _MainTex, uv + float2(x * pixedDisX, y * pixedDisY));
tmpColor += color;
}
}
return tmpColor / count;
}
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = BlurTextrue(i.uv, _BlurRadius, _TextureSizeX, _TextureSizeY);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
}
挂在相机的后处理脚本上,运行就能看见效果
缺点:
1.平均取到一个区域的值,其实是不合理的,因为距离目标点越远的点,影响应该越小
因此计算卷积的过程中,会引入权重,也叫做:模板(Mask)或卷积核
不同的模板对应了不同的模糊策略
eg:
1.应用了正态分布的加权卷积就被称为高斯模糊,会让模糊后的图像保留更多色彩细节
2.改变卷积核,这套渲染流程也被广泛应用于边缘检测、径向模糊、浮雕、锐化等屏幕效果
网友评论