【发布时间】:2020-11-26 15:59:44
【问题描述】:
我想计算二维高斯函数,输入为X,Y纹理UV坐标,得到对应的高斯值。
我在如何获得相应的 Texel 的 uv 高斯值方面遇到困难。
float Gaussian2D(float x, float y)
{
float x_y_squared = x * x + y * y;
float stDevSquared = 2 *_2D_StandardDeviation * _2D_StandardDeviation;
float div = x_y_squared / stDevSquared;
float gauss = pow(E, -div);
return gauss;
}
float Gaussian(int offset)
{
float stDevSquared = _StandardDeviation * _StandardDeviation;
float gauss = (1 / sqrt(2 * PI * stDevSquared)) * pow(E, -((offset * offset) / (2 * stDevSquared)));
return gauss;
}
fixed4 frag(v2f i) : SV_Target
{
fixed source = tex2D(_MainTex, i.uv).r;
float g0 = Gaussian(0);
float g1 = Gaussian(1);
float g2 = Gaussian(2);
float g3 = Gaussian(3);
float g4 = Gaussian(4);
float g5 = Gaussian(5);
float omega = g0 + g1 + g2 + g3 + g4 + g5;
float gauss = Gaussian2D(i.uv.x, i.uv.y);
fixed prev_a = tex2D(_HistoryA, i.uv).r;
fixed prev_b = tex2D(_HistoryB, i.uv).r;
fixed prev_c = tex2D(_HistoryC, i.uv).r;
fixed prev_d = tex2D(_HistoryD, i.uv).r;
fixed prev_e = tex2D(_HistoryE, i.uv).r;
fixed current = (gauss*source * g0 + gauss*prev_a * g1 + gauss*prev_b * g2 + gauss*prev_c * g3 + gauss*prev_d * g4 + gauss*prev_e * g5)/(omega);
float diff = source - prev_a;
if (diff <= _dataDelta)
{
return current;
}
return source;
}
ENDCG
}
更新 Spektre 的惊人作品
sampler2D _MainTex;
sampler2D _HistoryA;
sampler2D _HistoryB;
sampler2D _HistoryC;
sampler2D _HistoryD;
float4 _MainTex_TexelSize;
float _dataDelta;
float _blurRadius;
float _stepsDelta;
float _resolution;
float4 _MainTex_ST;
float _StandardDeviation;
#define E 2.71828182846
#define PI 3.14159265359
v2f vert(appdata v) {
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
float Gaussian(int offset)
{
float stDevSquared = _StandardDeviation * _StandardDeviation;
float gauss = (1 / sqrt(2 * PI * stDevSquared)) * pow(E, -((offset * offset) / (2 * stDevSquared)));
return gauss;
}
float blur2d_horizontal(sampler2D tex, v2f i, float hstep, float vstep) {
float2 uv = i.uv;
float sum = 0;
float2 tc = uv;
//blur radius in pixels
float blur = _blurRadius / _resolution / 4;
sum += tex2D(tex, float2(tc.x - 4.0 * blur * hstep, tc.y - 4.0 * blur * vstep)).r * 0.0162162162;
sum += tex2D(tex, float2(tc.x - 3.0 * blur * hstep, tc.y - 3.0 * blur * vstep)).r * 0.0540540541;
sum += tex2D(tex, float2(tc.x - 2.0 * blur * hstep, tc.y - 2.0 * blur * vstep)).r * 0.1216216216;
sum += tex2D(tex, float2(tc.x - 1.0 * blur * hstep, tc.y - 1.0 * blur * vstep)).r * 0.1945945946;
sum += tex2D(tex, float2(tc.x, tc.y)).r * 0.2270270270;
sum += tex2D(tex, float2(tc.x + 1.0 * blur * hstep, tc.y + 1.0 * blur * vstep)).r * 0.1945945946;
sum += tex2D(tex, float2(tc.x + 2.0 * blur * hstep, tc.y + 2.0 * blur * vstep)).r * 0.1216216216;
sum += tex2D(tex, float2(tc.x + 3.0 * blur * hstep, tc.y + 3.0 * blur * vstep)).r * 0.0540540541;
sum += tex2D(tex, float2(tc.x + 4.0 * blur * hstep, tc.y + 4.0 * blur * vstep)).r * 0.0162162162;
return sum;
}
fixed4 frag(v2f i) : SV_Target {
const int m = 5;
float d = 5.0;
float z[m];
float gauss_curve[m];
float zed;
_resolution = 900;
z[0] = tex2D(_MainTex, i.uv).r;// oldest 2 frames
z[1] = tex2D(_HistoryA, i.uv).r;
if (abs(z[0] - z[1]) < _dataDelta) // threshold depth change
{
// z[0] = 0.0;
// 2D spatial gauss blur of z0
z[0] = blur2d_horizontal(_MainTex, i, _stepsDelta, _stepsDelta);
// fetch depths from up to m frames
z[2] = tex2D(_HistoryB, i.uv).r;
z[3] = tex2D(_HistoryC, i.uv).r;
z[4] = tex2D(_HistoryD, i.uv).r;
zed = 0.0;
gauss_curve[0] = Gaussian(0);
gauss_curve[1] = Gaussian(1);
gauss_curve[2] = Gaussian(2);
gauss_curve[3] = Gaussian(3);
gauss_curve[4] = Gaussian(4);
float sum = 0.0;
// 1D temporal gauss blur
for (int idx = 1; idx <= m; idx++)
{
zed += gauss_curve[idx - 1] * z[idx - 1];
}
}
else
zed = z[0];
return fixed4(zed, zed, zed, 0.0);
}
【问题讨论】:
-
请参阅2D GLSL Gaussian blur 它可能会有所帮助,但是您的代码看起来不像原生 GLSL 着色器...如果它与统一相关,我无能为力,因为我不为统一编码 ...
-
@Spektre 你可以在任何 GLSL 中做到这一点,我知道你是这方面的专家。但是你能说明一下论文中的方程式是如何在伪代码中实现的吗?
-
@Spektre 你甚至可以在网络摄像头视频纹理或其他任何具有时间和空间噪声的东西上测试它
-
@Spektre 我被困在这 20 天,根本没有结果
-
@Spektre 这里是一个rgbd-dataset.cs.washington.edu
标签: c# unity3d graphics shader fragment-shader