 
     centerMoment /= centerMoment.z;
 
-    // UvZ.
-    float var = centerMoment.x - centerMoment.y * centerMoment.y;
+    float var = 0.0f;
+    float4 color = centerColor;
 
     if (frame < 4) {
         // ώZt[S or DisoccludedĂ.
         // 7x7birateral filterŋPxvZ.
 
-        static const int radius = 3;
-        static const float sigmaN = 0.005f;
-        static const float sigmaD = 0.005f;
-        static const float sigmaS = 0.965f;
-
         float3 centerNormal = make_float3(normalDepth.x, normalDepth.y, normalDepth.z);
 
-        float3 sum = make_float3(0);
-        float weight = 0.0f;
+        float3 momentSum = make_float3(centerMoment.x, centerMoment.y, centerMoment.z);
+        float weight = 1.0f;
 
-#if 0
+        float radius = frame > 1 ? 2 : 3;
+
         for (int v = -radius; v <= radius; v++)
         {
             for (int u = -radius; u <= radius; u++)
             {
-#else
-        static const int offsetx[] = {
-            -3, -2, -1, 0, 1, 2, 3,
-            -3, -2, -1, 0, 1, 2, 3,
-            -3, -2, -1, 0, 1, 2, 3,
-            -3, -2, -1, 0, 1, 2, 3,
-            -3, -2, -1, 0, 1, 2, 3,
-            -3, -2, -1, 0, 1, 2, 3,
-            -3, -2, -1, 0, 1, 2, 3,
-        };
+                if (u != 0 || v != 0) {
+                    int xx = clamp(ix + u, 0, width - 1);
+                    int yy = clamp(iy + v, 0, height - 1);
 
-        static const int offsety[] = {
-            -3, -3, -3, -3, -3, -3, -3,
-            -2,    -2,    -2,    -2,    -2,    -2,    -2,
-            -1,    -1,    -1,    -1,    -1,    -1,    -1,
-             0,     0,     0,     0,     0,     0,     0,
-             1,     1,     1,     1,     1,     1,     1,
-             2,     2,     2,     2,     2,     2,     2,
-             3,     3,     3,     3,     3,     3,     3,
-        };
+                    int pidx = getIdx(xx, yy, width);
+                    normalDepth = aovNormalDepth[pidx];
+                    texclrMeshid = aovTexclrMeshid[pidx];
+                    momentTemporalWeight = aovMomentTemporalWeight[pidx];
 
-#pragma unroll
-        for (int i = 0; i < 49; i++)
-        {
-            {
-                int u = offsetx[i];
-                int v = offsety[i];
-#endif
-                int xx = clamp(ix + u, 0, width - 1);
-                int yy = clamp(iy + v, 0, height - 1);
+                    float3 sampleNml = make_float3(normalDepth.x, normalDepth.y, normalDepth.z);
+                    float sampleDepth = normalDepth.w;
+                    int sampleMeshId = (int)texclrMeshid.w;
+                    auto sampleColor = aovColorVariance[pidx];
 
-                int pidx = getIdx(xx, yy, width);
-                normalDepth = aovNormalDepth[pidx];
-                texclrMeshid = aovTexclrMeshid[pidx];
-                momentTemporalWeight = aovMomentTemporalWeight[pidx];
+                    float3 moment = make_float3(momentTemporalWeight.x, momentTemporalWeight.y, momentTemporalWeight.z);
+                    moment /= moment.z;
 
-                float3 sampleNml = make_float3(normalDepth.x, normalDepth.y, normalDepth.z);
-                float sampleDepth = normalDepth.w;
-                int sampleMeshId = (int)texclrMeshid.w;
+                    float Wz = aten::abs(sampleDepth - centerDepth) / (pixelDistanceRatio * length(make_float2(u, v)) + 1e-2);
+                    float Wn = aten::pow(aten::cmpMax(0.0f, dot(sampleNml, centerNormal)), 128.0f);
 
-                float3 moment = make_float3(momentTemporalWeight.x, momentTemporalWeight.y, momentTemporalWeight.z);
-                moment /= moment.z;
+                    float Wm = centerMeshId == sampleMeshId ? 1.0f : 0.0f;
 
-#if 0
-                float n = 1 - dot(sampleNml, centerNormal);
-                float Wn = exp(-0.5f * n * n / (sigmaN * sigmaN));
+                    float W = exp(-Wz) * Wn * Wm;
 
-                float d = 1 - min(centerDepth, sampleDepth) / max(centerDepth, sampleDepth);
-                float Wd = exp(-0.5f * d * d / (sigmaD * sigmaD));
-
-                float Ws = exp(-0.5f * (u * u + v * v) / (sigmaS * sigmaS));
-#elif 0
-                float Wn = 1.0f;
-                {
-                    float normalCloseness = dot(sampleNml, centerNormal);
-                    normalCloseness = normalCloseness * normalCloseness;
-                    normalCloseness = normalCloseness * normalCloseness;
-                    float normalError = (1.0f - normalCloseness);
-                    Wn = max((1.0f - normalError), 0.0f);
+                    momentSum += moment * W;
+                    color += sampleColor * W;
+                    weight += W;
                 }
-
-                float Wd = max(0.0f, 1.0f - fabs(centerDepth - sampleDepth));
-
-                float Ws = 1.0f;
-                {
-                    auto sampleViewPos = computeViewSpace(ix + u, iy + v, sampleDepth, width, height, &mtxC2V);
-
-                    // Change in position in camera space.
-                    auto dq = centerViewPos - sampleViewPos;
-
-                    // How far away is this point from the original sample in camera space? (Max value is unbounded).
-                    auto dist2 = dot(dq, dq);
-
-                    // How far off the expected plane (on the perpendicular) is this point?  Max value is unbounded.
-                    float err = max(fabs(dot(dq, sampleNml)), abs(dot(dq, centerNormal)));
-
-                    Ws = (dist2 < 0.001f)
-                        ? 1.0
-                        : pow(max(0.0, 1.0 - 2.0 * err / sqrt(dist2)), 2.0);
-                }
-#else
-                float3 sampleViewPos = computeViewSpace(ix + u, iy + v, sampleDepth, width, height, &mtxC2V);
-
-                float Wn = C(centerNormal, sampleNml, 0.1f);
-                float Ws = C(centerViewPos, sampleViewPos, 0.1f);
-                float Wd = C(centerDepth, sampleDepth, 0.1f);
-#endif
-
-                float Wm = centerMeshId == sampleMeshId ? 1.0f : 0.0f;
-
-                float W = Ws * Wn * Wd * Wm;
-                sum += moment * W;
-                weight += W;
             }
         }
 
-        if (weight > 0.0f) {
-            sum /= weight;
-        }
+        momentSum /= weight;
+        color /= weight;
 
-        var = sum.x - sum.y * sum.y;
+        var = 1.0f + 3.0f * (1.0f - frame / 4.0f) * max(0.0, momentSum.y - momentSum.x * momentSum.x);
+    }
+    else {
+        var = max(0.0f, centerMoment.x - centerMoment.y * centerMoment.y);
     }
 
-    // TODO
-    // U̓}CiXɂȂȂEEEE
-    var = fabs(var);
-
-    aovColorVariance[idx].w = var;
+    color.w = var;
+    aovColorVariance[idx] = color;
 
     surf2Dwrite(
         make_float4(var, var, var, 1),

            m_aovColorVariance[curaov].ptr(),
            m_aovTexclrMeshid[curaov].ptr(),
            m_mtxC2V,
            width, height);

        checkCudaKernel(varianceEstimation);
    }

            (m_tileDomain.w + block.x - 1) / block.x,
            (m_tileDomain.h + block.y - 1) / block.y);

        float cameraDistance = height / (2.0f * aten::tan(0.5f * m_camParam.vfov));

        int curaov = getCurAovs();

        varianceEstimation << <grid, block, 0, m_stream >> > (
