Differential Ray関連の計算。

自分用メモ。

基本的にpbrt本と同じ処理をしています。

	// approximate this differential geometry as a plane
	// compute where each differential rays will intersect
	FPlane plane(vPos, vNormal);

	FVector3 px, py;
	plane.computeRayIntersection(&px, rayd.rayx);
	plane.computeRayIntersection(&py, rayd.rayy);

スクリーン座標でx方向、y方向に1ピクセル分だけずらしたレイを接平面と交差判定。

	// approximate DPDX and DPDY
	vDPDX = px - vPos /* / 1.0 */;
	vDPDY = py - vPos /* / 1.0 */;

\frac{\partial P}{\partial x}\frac{\partial P}{\partial y}を適当に近似。 \Delta x \Delta yはそれぞれ1.0。(1ピクセルずらしたので)

	// p' = p + du * dp/du + dv * dp/dv
	// [ (p' - p)_x ]   [ dp_x/du   dp_x/dv ]
	// [ (p' - p)_y ] = [ dp_y/du   dp_y/dv ] * [du, dv]
	// [ (p' - p)_z ]   [ dp_z/du   dp_z/dv ]

	// solve for [du, dv]
	// carefully choose two equations to make it solvable
	// -- choose axises but the axis that have largest normal vector magnitude
	float A[4], Bx[2], By[2];

	switch(FLargestOfThree<REAL>(Fabs(vNormal.x), Fabs(vNormal.y), Fabs(vNormal.z)))
	{
	case 0:
		// choose Y and Z axis
		A[0 /* _11 */] = vDPDU[1];	A[1 /* _12 */] = vDPDV[1];
		A[2 /* _21 */] = vDPDU[2];	A[3 /* _22 */] = vDPDV[2];

		Bx[0] = vDPDX[1];
		Bx[1] = vDPDX[2];
		By[0] = vDPDY[1];
		By[1] = vDPDY[2];

		break;
    略
        }

	// -- solve and store results
	bool ret;
	ret = FSolveLinearSystem22(A, Bx, vDUVDX.n);
	if(!ret)
		vDUVDX = FVector2((REAL)1.0, (REAL)0.0);

	ret = FSolveLinearSystem22(A, By, vDUVDY.n);
	if(!ret)
		vDUVDY = FVector2((REAL)0.0, (REAL)1.0);

 \frac{\partial T}{\partial x}\frac{\partial T}{\partial y}の計算。

 P' = P + \Delta T_u \frac{\partial P}{\partial T_u} + \Delta T_v \frac{\partial P}{\partial T_v}
として、連立方程式を解く。x,y,zと3式できるが、そのうち2式で十分なので、法線ベクトルの小さい成分2つを使う。