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 */;
とを適当に近似。とはそれぞれ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);
との計算。
として、連立方程式を解く。x,y,zと3式できるが、そのうち2式で十分なので、法線ベクトルの小さい成分2つを使う。