(转载请注明出处)
很久没更新博客了, 有点忙, 最近有点疲惫了, 写写新的东西也不错, 这次接着说Direct2D 的特效篇. 有一年多没更新这部分了. 发现代码水平比一年前又提高了不少:)
自从用了vs2015, 腰不酸了, 腿不疼了, 一口气码几百行也不费劲儿. 所以工程代码可能需要Win10 SDK + VS2015才能编译成功. 理论Win8可以, 稍微改下Win7也行, 但是Win10能保证没问题:)
这次要要说说径向模糊:
微软提供的内建特效中拥有高斯模糊和定向模糊. 对于基本应用来说还差个径向模糊.
那么我们现在就动手做一个吧, 先做一个”游戏版”的径向模糊, 稍微简单点:
模糊算法我们大概都懂: 处理后的像素点是原来”附近”几个采样点的加权平均值. 高斯模糊就是高斯函数的加权, 普通就算术平均值即可, 简单.
所以理论上我们只要顺着一个中心点, 进行采样即可.
比如8个采样点, 强度大致上60%, (当然这是我提供的样图而已, 实际是64个采样点否则不能这么细腻),
这个输出像素点颜色就是:
这个特殊情况的算法
point = ?, ?
center = ?, ?
step = (center - point) / 8 * 0.6
color = 0
for(i: 0...8) color += get_color(point + step*i)
color /= 8
怎么样, 简单吧, 如果强度达到100%, 基本每个点都为有中心点的”基因”(忘记用啥词了).
所以这次依然是用像素着色器, 不过带有常量缓存区了(cbuffer):
// 2D纹理 第一个输入储存在t0
Texture2D InputTexture : register(t0);
// 采样器状态 第一个储存在s0
SamplerState InputSampler : register(s0);
// 常量缓存 (b0)
cbuffer RadialBlurProperties : register(b0) {
float2 center : packoffset(c0);
float magnitude : packoffset(c0.z);
float samples : packoffset(c0.w);
};
// Shader入口
float4 main(
float4 clipSpaceOutput : SV_POSITION,
float4 sceneSpaceOutput : SCENE_POSITION,
float4 texelSpaceInput0 : TEXCOORD0
) : SV_Target {
// 初始化
float4 color = 0;
// 计算步进值
float2 step = (center - texelSpaceInput0.xy) / samples * magnitude;
// 遍历每个采样点
for(float i = 0; i < samples; ++i) {
// 计算采样地点
float2 pos = texelSpaceInput0.xy + step * i;
// 添加采样数据
color += InputTexture.Sample(InputSampler, pos);
}
// 平均
return color / samples;
}
main函数没什么说的吧, 与之前的特殊情况基本一个道理.