 	cur.w = 1;
 
 	if (isInsideX && isInsideY) {
-		int px = prevPos.x * (width - 1);
-		int py = prevPos.y * (height - 1);
+		int px = (int)(prevPos.x * (width - 1) + 0.5f);
+		int py = (int)(prevPos.y * (height - 1) + 0.5f);
+
+		px = min(px, width - 1);
+		py = min(py, height - 1);
 
 		const auto pidx = getIdx(px, py, width);
 
 		const auto prevAov = prevAOVs[pidx];
 		const auto prevDepth = aten::clamp(prevAov.y, CAMERA_NEAR, CAMERA_FAR);
 
-		if (abs(centerDepth - prevDepth) <= 0.5) {
+		if (abs(centerDepth - prevDepth) <= 0.1f
+			&& aov.x == prevAov.x)
+		{
 			float4 prev;
 			surf2Dread(&prev, outSurface, px * sizeof(float4), py);
 
 			int n = (int)prev.w;
 
-			cur = prev * n + cur;
-			cur /= (float)(n + 1);
-			cur.w = n + 1;
+			// TODO
+			n = min(1, n);
+
+			cur = prev * n + cur * path.samples;
+			cur /= (float)(n + path.samples);
+			cur.w = n + path.samples;
 		}
 	}
 

	const aten::mat4 mtxPrevV2C = mtxs[1];

	const auto aov = aovs[idx];
	const auto centerDepth = aten::clamp(aov.y, CAMERA_NEAR, CAMERA_FAR);

	// NOTE

// TODO
#define CAMERA_NEAR		(0.001f)
#define CAMERA_FAR		(10000.0f)
#define CAMERA_EPSILON	(CAMERA_NEAR / (CAMERA_FAR - CAMERA_NEAR))

__global__ void temporalReprojection(
	const idaten::PathTracing::Path* __restrict__ paths,
	const float4* __restrict__ aovs,
	const float4* __restrict__ prevAOVs,
