public static void LookupBRDFTrilinear( Vector3[,,] _BRDF, double _ThetaHalf, double _ThetaDiff, double _PhiDiff, ref Vector3 _Result )
{
// (note that PhiHalf is ignored, since isotropic BRDFs are assumed)
Vector3 r;
int PhiDiffIndex0 = PhiDiff_index( _PhiDiff, out r.z );
int ThetaDiffIndex0 = ThetaDiff_index( _ThetaDiff, out r.y );
int ThetaHalfIndex0 = ThetaHalf_index( _ThetaHalf, out r.x );
int PhiDiffIndex1 = Math.Min( BRDF_SAMPLING_RES_PHI_D/2-1, PhiDiffIndex0+1 );
int ThetaDiffIndex1 = Math.Min( BRDF_SAMPLING_RES_THETA_D-1, ThetaDiffIndex0+1 );
int ThetaHalfIndex1 = Math.Min( BRDF_SAMPLING_RES_THETA_H-1, ThetaHalfIndex0+1 );
TempTrilerp[0,0,0] = _BRDF[ThetaHalfIndex0,ThetaDiffIndex0,PhiDiffIndex0];
TempTrilerp[0,0,1] = _BRDF[ThetaHalfIndex0,ThetaDiffIndex0,PhiDiffIndex1];
TempTrilerp[0,1,1] = _BRDF[ThetaHalfIndex0,ThetaDiffIndex1,PhiDiffIndex1];
TempTrilerp[0,1,0] = _BRDF[ThetaHalfIndex0,ThetaDiffIndex1,PhiDiffIndex0];
TempTrilerp[1,0,0] = _BRDF[ThetaHalfIndex1,ThetaDiffIndex0,PhiDiffIndex0];
TempTrilerp[1,0,1] = _BRDF[ThetaHalfIndex1,ThetaDiffIndex0,PhiDiffIndex1];
TempTrilerp[1,1,1] = _BRDF[ThetaHalfIndex1,ThetaDiffIndex1,PhiDiffIndex1];
TempTrilerp[1,1,0] = _BRDF[ThetaHalfIndex1,ThetaDiffIndex1,PhiDiffIndex0];
TempBilerp[0,0] = (1.0 - r.z) * TempTrilerp[0,0,0] + r.z * TempTrilerp[0,0,1];
TempBilerp[0,1] = (1.0 - r.z) * TempTrilerp[0,1,0] + r.z * TempTrilerp[0,1,1];
TempBilerp[1,1] = (1.0 - r.z) * TempTrilerp[1,1,0] + r.z * TempTrilerp[1,1,1];
TempBilerp[1,0] = (1.0 - r.z) * TempTrilerp[1,0,0] + r.z * TempTrilerp[1,0,1];
TempLerp[0] = (1.0 - r.y) * TempBilerp[0,0] + r.y * TempBilerp[0,1];
TempLerp[1] = (1.0 - r.y) * TempBilerp[1,0] + r.y * TempBilerp[1,1];
_Result = (1.0 - r.x) * TempLerp[0] + r.x * TempLerp[1];
}