Example #1
0
        private void    Generate_CPU(int _RaysCount)
        {
            try {
                tabControlGenerators.Enabled = false;

                // Half-life basis (Z points outside of the surface, as in normal maps)
                float3[] basis = new float3[] {
                    new float3((float)Math.Sqrt(2.0 / 3.0), 0.0f, (float)Math.Sqrt(1.0 / 3.0)),
                    new float3((float)-Math.Sqrt(1.0 / 6.0), (float)Math.Sqrt(1.0 / 2.0), (float)Math.Sqrt(1.0 / 3.0)),
                    new float3((float)-Math.Sqrt(1.0 / 6.0), (float)-Math.Sqrt(1.0 / 2.0), (float)Math.Sqrt(1.0 / 3.0)),
                };

//              // 1] Compute normal map
//              float3	dX = new float3();
//              float3	dY = new float3();
//              float3	N;
//              float			ddX = floatTrackbarControlPixelSize.Value;
//              float			ddH = floatTrackbarControlHeight.Value;
//              for ( int Y=0; Y < H; Y++ )
//              {
//                  int	Y0 = Math.Max( 0, Y-1 );
//                  int	Y1 = Math.Min( H-1, Y+1 );
//                  for ( int X=0; X < W; X++ )
//                  {
//                      int	X0 = Math.Max( 0, X-1 );
//                      int	X1 = Math.Min( W-1, X+1 );
//
//                      float	Hx0 = m_BitmapSource.ContentXYZ[X0,Y].y;
//                      float	Hx1 = m_BitmapSource.ContentXYZ[X1,Y].y;
//                      float	Hy0 = m_BitmapSource.ContentXYZ[X,Y0].y;
//                      float	Hy1 = m_BitmapSource.ContentXYZ[X,Y1].y;
//
//                      dX.Set( 2.0f * ddX, 0.0f, ddH * (Hx1 - Hx0) );
//                      dY.Set( 0.0f, 2.0f * ddX, ddH * (Hy1 - Hy0) );
//
//                      N = dX.Cross( dY ).Normalized;
//
//                      m_Normal[X,Y] = new float3(
//                          N.Dot( Basis[0] ),
//                          N.Dot( Basis[1] ),
//                          N.Dot( Basis[2] ) );
//                  }
//
//                  // Update and show progress
//                  UpdateProgress( m_Normal, Y, true );
//              }
//              UpdateProgress( m_Normal, H, true );

                float LobeExponent = 4.0f;                  //floatTrackbarControlLobeExponent.Value;

                float PixelSize_mm = 1000.0f / floatTrackbarControlPixelDensity.Value;

                float scale = 0.1f * PixelSize_mm / floatTrackbarControlHeight.Value;                   // Scale factor to apply to pixel distances so they're renormalized in [0,1], our "heights space"...
//						Scale *= floatTrackbarControlZFactor.Value;	// Cheat Z velocity so AO is amplified!

                // 2] Build local rays only once
                int raysCount = integerTrackbarControlRaysCount.Value;
                float3[,]       rays = new float3[3, raysCount];

                // Create orthonormal bases to orient the lobe
                float3 Xr = basis[0].Cross(float3.UnitZ).Normalized;                    // We can safely use (0,0,1) as the "up" direction since the HL2 basis doesn't have any vertical direction
                float3 Yr = Xr.Cross(basis[0]);
                float3 Xg = basis[1].Cross(float3.UnitZ).Normalized;                    // We can safely use (0,0,1) as the "up" direction since the HL2 basis doesn't have any vertical direction
                float3 Yg = Xg.Cross(basis[1]);
                float3 Xb = basis[2].Cross(float3.UnitZ).Normalized;                    // We can safely use (0,0,1) as the "up" direction since the HL2 basis doesn't have any vertical direction
                float3 Yb = Xb.Cross(basis[2]);

                double Exponent = 1.0 / (1.0 + LobeExponent);
                for (int RayIndex = 0; RayIndex < raysCount; RayIndex++)
                {
//                  if ( false ) {
//                      double	Phi = 2.0 * Math.PI * WMath.SimpleRNG.GetUniform();
// //						double	Theta = Math.Acos( Math.Pow( WMath.SimpleRNG.GetUniform(), Exponent ) );
//                      double	Theta = Math.PI / 3.0 * WMath.SimpleRNG.GetUniform();
//
//                      float3	RayLocal = new float3(
//                          (float) (Math.Cos( Phi ) * Math.Sin( Theta )),
//                          (float) (Math.Sin( Phi ) * Math.Sin( Theta )),
//                          (float) Math.Cos( Theta ) );
//
//                      Rays[0,RayIndex] = RayLocal.x * Xr + RayLocal.y * Yr + RayLocal.z * Basis[0];
//                      Rays[1,RayIndex] = RayLocal.x * Xg + RayLocal.y * Yg + RayLocal.z * Basis[1];
//                      Rays[2,RayIndex] = RayLocal.x * Xb + RayLocal.y * Yb + RayLocal.z * Basis[2];
//                  } else
                    {
                        double Phi   = Math.PI / 3.0 * (2.0 * SimpleRNG.GetUniform() - 1.0);
                        double Theta = 0.49 * Math.PI * SimpleRNG.GetUniform();
                        rays[0, RayIndex] = new float3(
                            (float)(Math.Cos(Phi) * Math.Sin(Theta)),
                            (float)(Math.Sin(Phi) * Math.Sin(Theta)),
                            (float)Math.Cos(Theta));

                        Phi               = Math.PI / 3.0 * (2.0 * SimpleRNG.GetUniform() - 1.0 + 2.0);
                        Theta             = 0.49 * Math.PI * SimpleRNG.GetUniform();
                        rays[1, RayIndex] = new float3(
                            (float)(Math.Cos(Phi) * Math.Sin(Theta)),
                            (float)(Math.Sin(Phi) * Math.Sin(Theta)),
                            (float)Math.Cos(Theta));

                        Phi               = Math.PI / 3.0 * (2.0 * SimpleRNG.GetUniform() - 1.0 + 4.0);
                        Theta             = 0.49 * Math.PI * SimpleRNG.GetUniform();
                        rays[2, RayIndex] = new float3(
                            (float)(Math.Cos(Phi) * Math.Sin(Theta)),
                            (float)(Math.Sin(Phi) * Math.Sin(Theta)),
                            (float)Math.Cos(Theta));
                    }

                    rays[0, RayIndex].z *= scale;
                    rays[1, RayIndex].z *= scale;
                    rays[2, RayIndex].z *= scale;
                }

                // 3] Compute directional occlusion
                float4[] scanline = new float4[W];
                float4   gammaRGB = float4.Zero;
                for (uint Y = 0; Y < H; Y++)
                {
                    for (uint X = 0; X < W; X++)
                    {
                        gammaRGB.x = ComputeAO(0, X, Y, scale, rays);
                        gammaRGB.y = ComputeAO(1, X, Y, scale, rays);
                        gammaRGB.z = ComputeAO(2, X, Y, scale, rays);
                        gammaRGB.w = (gammaRGB.x + gammaRGB.y + gammaRGB.z) / 3.0f;
                        m_sRGBProfile.GammaRGB2LinearRGB(gammaRGB, ref scanline[X]);
                    }
                    m_imageResult.WriteScanline(Y, scanline);

                    // Update and show progress
                    UpdateProgress(m_imageResult, Y, true);
                }
                UpdateProgress(m_imageResult, H, true);

//				m_BitmapResult.Save( "eye_generic_01_disp_hl2.png", ImageFormat.Png );
            }
            catch (Exception _e)
            {
                MessageBox("An error occurred during generation:\r\n" + _e.Message, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                tabControlGenerators.Enabled = true;
            }
        }