public void BuildProbabilities(double _CameraTheta, ParametrizedSpace _Probas) { Vector ViewTS = new Vector(Math.Sin(_CameraTheta), 0.0, Math.Cos(_CameraTheta)); Vector LightTS = new Vector(0, 0, 0); double L = 2.0 * _CameraTheta / Math.PI; Vector2 Center = new Vector2(0, L); // We choose the center to be (0,ThetaD0) // Vector2 U = new Vector2( L, -L ); // U direction goes down to (ThetaH0,0) Vector2 U = new Vector2(0.5 / L, -0.5 / L); // U direction goes down to (ThetaH0,0) // Vector2 V = new Vector2( 1-L, 1-L ); // V direction goes up toward (PI/2, PI/2) (singularity when _CameraTheta=PI/2 !) // Vector2 V = new Vector2( 0.5 / (1-L), 0.5 / (1-L) ); // V direction goes up toward (PI/2, PI/2) (singularity when _CameraTheta=PI/2 !) Vector2 V = new Vector2(1.0 / (1 - L), 1.0 / (1 - L)); // V direction goes up toward (PI/2, PI/2) (singularity when _CameraTheta=PI/2 !) double Normalizer = 100.0 / (SAMPLES_COUNT_PHI * SAMPLES_COUNT_THETA); Vector2 ST = new Vector2(0, 0); Vector2 Delta = new Vector2(0, 0); Vector2 UV = new Vector2(0, 0); _Probas.Clear(); int ScaleAngle = Math.Min(89, (int)(90 * L)); for (var Y = 0; Y < SAMPLES_COUNT_PHI; Y++) { var PhiL = Math.PI * ((double)Y / SAMPLES_COUNT_PHI - 0.5); var CosPhiL = Math.Cos(PhiL); var SinPhiL = Math.Sin(PhiL); for (var X = 0; X < SAMPLES_COUNT_THETA; X++) { // var ThetaL = 0.5 * Math.PI * X / SAMPLES_COUNT_THETA; var ThetaL = Math.Asin(Math.Sqrt((double)X / SAMPLES_COUNT_THETA)); // Account for cosine weight of samples var CosThetaL = Math.Cos(ThetaL); var SinThetaL = Math.Sin(ThetaL); LightTS.x = SinThetaL * SinPhiL; LightTS.y = SinThetaL * CosPhiL; LightTS.z = CosThetaL; var Half = (ViewTS + LightTS).Normalize(); var ThetaH = Math.Acos(Half.z); var ThetaD = Math.Acos(ViewTS.Dot(Half)); // Normalize in ST space ST.x = 2 * ThetaH / Math.PI; ST.y = 2 * ThetaD / Math.PI; // Transform into UV space Delta = ST - Center; UV.x = Delta.Dot(U); UV.y = Delta.Dot(V); // Find scaling factor int ScaleX = Math.Max(0, Math.Min(PROBA_ARRAY_SIZE - 1, (int)(PROBA_ARRAY_SIZE * UV.x))); double Scale = m_Scales[ScaleAngle, ScaleX]; UV.y *= Scale; _Probas.Accumulate(UV, Normalizer); } } }
public void BuildProbabilities( double _CameraTheta, ParametrizedSpace _Probas ) { Vector ViewTS = new Vector( Math.Sin( _CameraTheta ), 0.0, Math.Cos( _CameraTheta ) ); Vector LightTS = new Vector( 0, 0, 0 ); double L = 2.0 * _CameraTheta / Math.PI; Vector2 Center = new Vector2( 0, L ); // We choose the center to be (0,ThetaD0) // Vector2 U = new Vector2( L, -L ); // U direction goes down to (ThetaH0,0) Vector2 U = new Vector2( 0.5 / L, -0.5 / L ); // U direction goes down to (ThetaH0,0) // Vector2 V = new Vector2( 1-L, 1-L ); // V direction goes up toward (PI/2, PI/2) (singularity when _CameraTheta=PI/2 !) // Vector2 V = new Vector2( 0.5 / (1-L), 0.5 / (1-L) ); // V direction goes up toward (PI/2, PI/2) (singularity when _CameraTheta=PI/2 !) Vector2 V = new Vector2( 1.0 / (1-L), 1.0 / (1-L) ); // V direction goes up toward (PI/2, PI/2) (singularity when _CameraTheta=PI/2 !) double Normalizer = 100.0 / (SAMPLES_COUNT_PHI * SAMPLES_COUNT_THETA); Vector2 ST = new Vector2( 0, 0 ); Vector2 Delta = new Vector2( 0, 0 ); Vector2 UV = new Vector2( 0, 0 ); _Probas.Clear(); int ScaleAngle = Math.Min( 89, (int) (90 * L) ); for ( var Y=0; Y < SAMPLES_COUNT_PHI; Y++ ) { var PhiL = Math.PI * ((double) Y / SAMPLES_COUNT_PHI - 0.5); var CosPhiL = Math.Cos( PhiL ); var SinPhiL = Math.Sin( PhiL ); for ( var X=0; X < SAMPLES_COUNT_THETA; X++ ) { // var ThetaL = 0.5 * Math.PI * X / SAMPLES_COUNT_THETA; var ThetaL = Math.Asin( Math.Sqrt( (double) X / SAMPLES_COUNT_THETA ) ); // Account for cosine weight of samples var CosThetaL = Math.Cos( ThetaL ); var SinThetaL = Math.Sin( ThetaL ); LightTS.x = SinThetaL * SinPhiL; LightTS.y = SinThetaL * CosPhiL; LightTS.z = CosThetaL; var Half = (ViewTS + LightTS).Normalize(); var ThetaH = Math.Acos( Half.z ); var ThetaD = Math.Acos( ViewTS.Dot( Half ) ); // Normalize in ST space ST.x = 2*ThetaH/Math.PI; ST.y = 2*ThetaD/Math.PI; // Transform into UV space Delta = ST - Center; UV.x = Delta.Dot( U ); UV.y = Delta.Dot( V ); // Find scaling factor int ScaleX = Math.Max( 0, Math.Min( PROBA_ARRAY_SIZE-1, (int) (PROBA_ARRAY_SIZE * UV.x) ) ); double Scale = m_Scales[ScaleAngle,ScaleX]; UV.y *= Scale; _Probas.Accumulate( UV, Normalizer ); } } }