private static double ComputeSummedDifferences( BRDFSample[] _Samples, double _Normalizer, double[] _GoalBDRF, CosineLobe[] _LobeEstimates )
{
// Sum differences between current ZH estimates and current SH goal estimates
double SumSquareDifference = 0.0;
double GoalValue, CurrentValue, TempLobeDot;
int SamplesCount = _Samples.Length;
int LobesCount = _LobeEstimates.Length;
for ( int SampleIndex=0; SampleIndex < SamplesCount; SampleIndex++ )
{
BRDFSample Sample = _Samples[SampleIndex];
// Get BRDF value for that sample
GoalValue = _GoalBDRF[Sample.m_BRDFIndex];
// if ( GoalValue < 0.0 )
// throw new Exception( "Unexpected negative value!" );
if ( double.IsNaN( GoalValue ) )
throw new Exception( "Unexpected NaN!" );
// DEBUG => Multiply by cos(ThetaIn) to test if it gets us a better conditioning
GoalValue *= Sample.m_CosThetaIn;
// Estimate cosine lobe value in that direction
CurrentValue = 0.0;
for ( int LobeIndex=0; LobeIndex < LobesCount; LobeIndex++ )
{
CosineLobe Lobe = _LobeEstimates[LobeIndex];
TempLobeDot = Lobe.C.x * Sample.m_DotProduct.x + Lobe.C.y * Sample.m_DotProduct.y + Lobe.C.z * Sample.m_DotProduct.z;
TempLobeDot = Math.Max( 0.0, TempLobeDot );
TempLobeDot = Math.Pow( TempLobeDot, Lobe.N );
CurrentValue += TempLobeDot;
}
// Sum difference between estimate and goal
SumSquareDifference += (CurrentValue - GoalValue) * (CurrentValue - GoalValue);
// SumSquareDifference += Math.Abs( CurrentValue - GoalValue ); // Just to avoid super large numbers!
}
// Normalize
SumSquareDifference *= _Normalizer;
return SumSquareDifference;
}