HLSL:高斯模糊效果
HLSL: Gaussian Blur Effect
我正在尝试使用 post 处理实现高斯模糊。我有两个渲染通道;第一遍渲染场景,第二遍用于效果。
这是我的像素着色器代码:
const float offset[] = {
0.0, 1.0, 2.0, 3.0, 4.0
};
const float weight[] = {
0.2270270270, 0.1945945946, 0.1216216216,
0.0540540541, 0.0162162162
};
ppColour = SceneTexture.Sample(PointSample, ppIn.UV) * weight[0];
float3 FragmentColor = float3(0.0f, 0.0f, 0.0f);
for (int i = 1; i < 5; i++) {
// Horizontal-pass
FragmentColor +=
SceneTexture.Sample(PointSample, ppIn.UV + float2(0.0f, offset[i]))*weight[i] +
SceneTexture.Sample(PointSample, ppIn.UV - float2(0.0f, offset[i]))*weight[i];
// Vertical-pass
FragmentColor +=
SceneTexture.Sample(PointSample, ppIn.UV + float2(offset[i], 0.0f))*weight[i] +
SceneTexture.Sample(PointSample, ppIn.UV - float2(offset[i], 0.0f))*weight[i];
}
ppColour += FragmentColor;
return (ppColour,1.0);
我看到了一个 string-y 外观,如下所示:
我做错了什么?
我认为您需要使用如下着色器代码分别渲染水平和垂直通道,但方向不同(参见 dir
uniform 变量)。所以你需要3个步骤
- 使用默认着色器将场景渲染到纹理 A
- 使用高斯模糊着色器水平渲染纹理 A 到纹理 B (dir={1.0,0.0})
- 使用相同的高斯模糊着色器将纹理 B 垂直渲染到屏幕 (dir={0.0,1.0})
uniform vec2 dir;
const float offset[] = {0.0, 1.0, 2.0, 3.0, 4.0};
const float weight[] = {
0.2270270270, 0.1945945946, 0.1216216216,
0.0540540541, 0.0162162162
};
ppColour = SceneTexture.Sample(PointSample, ppIn.UV) * weight[0];
float3 FragmentColor = float3(0.0f, 0.0f, 0.0f);
//(1.0, 0.0) -> horizontal blur
//(0.0, 1.0) -> vertical blur
float hstep = dir.x;
float vstep = dir.y;
for (int i = 1; i < 5; i++) {
FragmentColor +=
SceneTexture.Sample(PointSample, ppIn.UV + float2(hstep*offset[i], vstep*offset[i]))*weight[i] +
SceneTexture.Sample(PointSample, ppIn.UV - float2(hstep*offset[i], vstep*offset[i]))*weight[i];
}
ppColour += FragmentColor;
return (ppColour,1.0);
我正在尝试使用 post 处理实现高斯模糊。我有两个渲染通道;第一遍渲染场景,第二遍用于效果。
这是我的像素着色器代码:
const float offset[] = {
0.0, 1.0, 2.0, 3.0, 4.0
};
const float weight[] = {
0.2270270270, 0.1945945946, 0.1216216216,
0.0540540541, 0.0162162162
};
ppColour = SceneTexture.Sample(PointSample, ppIn.UV) * weight[0];
float3 FragmentColor = float3(0.0f, 0.0f, 0.0f);
for (int i = 1; i < 5; i++) {
// Horizontal-pass
FragmentColor +=
SceneTexture.Sample(PointSample, ppIn.UV + float2(0.0f, offset[i]))*weight[i] +
SceneTexture.Sample(PointSample, ppIn.UV - float2(0.0f, offset[i]))*weight[i];
// Vertical-pass
FragmentColor +=
SceneTexture.Sample(PointSample, ppIn.UV + float2(offset[i], 0.0f))*weight[i] +
SceneTexture.Sample(PointSample, ppIn.UV - float2(offset[i], 0.0f))*weight[i];
}
ppColour += FragmentColor;
return (ppColour,1.0);
我看到了一个 string-y 外观,如下所示:
我做错了什么?
我认为您需要使用如下着色器代码分别渲染水平和垂直通道,但方向不同(参见 dir
uniform 变量)。所以你需要3个步骤
- 使用默认着色器将场景渲染到纹理 A
- 使用高斯模糊着色器水平渲染纹理 A 到纹理 B (dir={1.0,0.0})
- 使用相同的高斯模糊着色器将纹理 B 垂直渲染到屏幕 (dir={0.0,1.0})
uniform vec2 dir;
const float offset[] = {0.0, 1.0, 2.0, 3.0, 4.0};
const float weight[] = {
0.2270270270, 0.1945945946, 0.1216216216,
0.0540540541, 0.0162162162
};
ppColour = SceneTexture.Sample(PointSample, ppIn.UV) * weight[0];
float3 FragmentColor = float3(0.0f, 0.0f, 0.0f);
//(1.0, 0.0) -> horizontal blur
//(0.0, 1.0) -> vertical blur
float hstep = dir.x;
float vstep = dir.y;
for (int i = 1; i < 5; i++) {
FragmentColor +=
SceneTexture.Sample(PointSample, ppIn.UV + float2(hstep*offset[i], vstep*offset[i]))*weight[i] +
SceneTexture.Sample(PointSample, ppIn.UV - float2(hstep*offset[i], vstep*offset[i]))*weight[i];
}
ppColour += FragmentColor;
return (ppColour,1.0);