I would like to calculated the 2D Gaussian function and the input is X,Y texture UV coordinate and get the corresponding gaussian value.
I'm facing difficulties on how to get the corresponding Texel's uv gaussian value.
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
}
Update to the Amazing work by 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);
}
w=w0*exp((-xx-yy)/(2.0*rr));
... if I cross check with your codex_y_squared
i sthe same as minexx+yy
andstDevSquared
is mine(2.0*rr)
... however I have a slight deliberate difference in constants for slower 2D approachpow(r,1.975);
instead ofr*r
to compensate for rounding errors ... I do not understand the logic behind your convolution texel fetch_HistoryA,i.uv
??? that looks to me like you are probing the same texel position instead of neighbors up tor
distance. But as I do not recognize the code I might be wrong – Aftercare