protected static void BRDFMappingLocalFunctionGradientEval( double[] _Coefficients, double[] _Gradients, object _Params )
{
BRDFFitEvaluationContext Context = _Params as BRDFFitEvaluationContext;
if ( _Coefficients[4] < EPS )
throw new Exception( "Invalid negative exponent!" );
double Normalizer = 1.0 / ms_BRDFSamples.Length;
// Compute derivatives for each coefficient
_Gradients[0] = 0.0;
for ( int DerivativeIndex=1; DerivativeIndex < _Coefficients.Length; DerivativeIndex++ )
{
// Copy coefficients and add a tiny delta for derivative estimate
_Coefficients.CopyTo( ms_TempCoefficientsLocal, 0 );
ms_TempCoefficientsLocal[DerivativeIndex] += DERIVATIVE_OFFSET;
// Copy current coefficients into the current cosine lobe
Context.m_Lobes[0].C.Set( ms_TempCoefficientsLocal[1], ms_TempCoefficientsLocal[2], ms_TempCoefficientsLocal[3] ); // Remember those stupid coefficients are indexed from 1!
Context.m_Lobes[0].N = Math.Max( EPS, ms_TempCoefficientsLocal[4] ); // Exponents are constrained to be strictly positive!
// Sum differences between current ZH estimates and current SH goal estimates
double SumSquareDifference = ComputeSummedDifferences( ms_BRDFSamples, Normalizer, Context.m_BRDF, Context.m_Lobes );
// Compute delta with fixed central square difference
_Gradients[DerivativeIndex] = (SumSquareDifference - Context.m_SumSquareDifference) / DERIVATIVE_OFFSET;
}
// _Gradients[4] = Math.Log( _Gradients[4] ); // Use log of gradient instead since we're dealing with an exponent here...
// _Gradients[4] = Math.Sign( _Gradients[4] ) * Math.Log( 1+Math.Abs(_Gradients[4]) ); // Use log of gradient instead since we're dealing with an exponent here...
}