Пример #1
0
        void    RebuildNoise()
        {
            uint size     = m_handMadeBlueNoise.Width;
            uint halfSize = size >> 1;

            //////////////////////////////////////////////////////////////////////////
            // Reconstruct an artificial spectrum
            Complex[,]      handmadeSpectrum = new Complex[m_handMadeBlueNoise.Width, m_handMadeBlueNoise.Height];
            CreateNoiseSpectrum(handmadeSpectrum);
//CreateTestSpectrum( handmadeSpectrum );


            //////////////////////////////////////////////////////////////////////////
            // Reconstruct a hand-made "blue noise"
            Complex[,]      handMadeBlueNoise = new Complex[m_handMadeBlueNoise.Width, m_handMadeBlueNoise.Height];
            m_FFT.FFT_Inverse(handmadeSpectrum, handMadeBlueNoise);
//			m_FFT.FFT_Inverse( output, handMadeBlueNoise );


            //////////////////////////////////////////////////////////////////////////
            // Build the resulting images
            m_handMadeSpectrum.WritePixels((uint X, uint Y, ref float4 _color) => {
                uint Yoff = (Y + halfSize) & (size - 1);
                uint Xoff = (X + halfSize) & (size - 1);
                float R   = (float)handmadeSpectrum[Xoff, Yoff].r;
                R        *= 1.0f * size;
                R         = Math.Abs(R);

//              float	I = (float) handmadeSpectrum[Xoff,Yoff].i;
//              I *= 2.0f * size;

                _color.Set(R, R, R, 1.0f);
            });

            // Hand-made blue noise
            m_handMadeBlueNoise.WritePixels((uint X, uint Y, ref float4 _color) => {
                float R = (float)handMadeBlueNoise[X, Y].r;
                float I = (float)handMadeBlueNoise[X, Y].i;
                _color.Set(R, R, R, 1.0f);
            });

            UpdatePanels();
        }
Пример #2
0
        private void Convert(bool _centralValue, float _signX, float _signY)
        {
            // Initialize gradient filter
            Complex[,]      dx = new Complex[m_size, m_size];
            Complex[,]      dy = new Complex[m_size, m_size];
            Array.Clear(dx, 0, (int)(m_size * m_size));
            Array.Clear(dy, 0, (int)(m_size * m_size));

            if (_centralValue)
            {
                // Central-difference
                dx[m_size - 1, 0].Set(-_signX, 0);
                dx[1, 0].Set(_signX, 0);
                dy[0, m_size - 1].Set(_signY, 0);
                dy[0, 1].Set(-_signY, 0);
            }
            else
            {
                // One-sided difference
                dx[0, 0].Set(-_signX, 0);
                dx[1, 0].Set(_signX, 0);
                dy[0, 0].Set(_signY, 0);
                dy[0, 1].Set(-_signY, 0);
            }

            // Apply forward Fourier transform to obtain spectrum
            SharpMath.FFT.FFT2D_GPU FFT = new SharpMath.FFT.FFT2D_GPU(m_device, m_size);
            Complex[,]      NX = FFT.FFT_Forward(nx);
            Complex[,]      NY = FFT.FFT_Forward(ny);
            Complex[,]      DX = FFT.FFT_Forward(dx);
            Complex[,]      DY = FFT.FFT_Forward(dy);

            // Compute de-convolution
            float factor = m_imageNormal.Width * m_imageNormal.Height;

            Complex[,]      H = new Complex[m_size, m_size];
            Complex temp = new Complex(), sqrtTemp;

            for (uint Y = 0; Y < m_size; Y++)
            {
                for (uint X = 0; X < m_size; X++)
                {
#if !F**K
                    double sqNX = NX[X, Y].SquareMagnitude;
                    double sqNY = NY[X, Y].SquareMagnitude;
                    double num  = sqNX + sqNY;

                    double sqDX = DX[X, Y].SquareMagnitude;
                    double sqDY = DY[X, Y].SquareMagnitude;
                    double den  = factor * (sqDX + sqDY);

                    temp.Set(Math.Abs(den) > 0.0 ? num / den : 0.0, 0.0);
                    sqrtTemp = temp.Sqrt();

                    H[X, Y] = sqrtTemp;
#else
                    Complex Nx  = NX[X, Y];
                    Complex Ny  = NY[X, Y];
                    Complex Dx  = DX[X, Y];
                    Complex Dy  = DY[X, Y];
                    double  den = factor * (DX[X, Y].SquareMagnitude + DY[X, Y].SquareMagnitude);
                    if (Math.Abs(den) > 0.0)
                    {
                        temp    = -(Dx * Nx + Dy * Ny) / den;
                        H[X, Y] = temp;
                    }
                    else
                    {
                        H[X, Y].Zero();
                    }
#endif
                }
            }

            // Apply inverse transform
            Complex[,]      h = FFT.FFT_Inverse(H);

            Complex heightMin = new Complex(double.MaxValue, double.MaxValue);
            Complex heightMax = new Complex(-double.MaxValue, -double.MaxValue);
            for (uint Y = 0; Y < m_size; Y++)
            {
                for (uint X = 0; X < m_size; X++)
                {
                    Complex height = h[X, Y];
                    heightMin.Min(height);
                    heightMax.Max(height);
                }
            }

            // Render result
            if (m_imageHeight != null)
            {
                m_imageHeight.Dispose();
                m_imageHeight = null;
            }

            factor = 1.0f / (float)(heightMax.r - heightMin.r);
// heightMin.r = -1.0f;
// factor = 0.5f;

            m_imageHeight = new ImageFile(m_imageNormal.Width, m_imageNormal.Height, PIXEL_FORMAT.R16, new ColorProfile(ColorProfile.STANDARD_PROFILE.sRGB));
//			m_imageHeight.WritePixels( ( uint X, uint Y, ref float4 _color ) => { _color.x = 1e3f * (float) H[X,Y].Magnitude; } );
//			m_imageHeight.WritePixels( ( uint X, uint Y, ref float4 _color ) => { _color.x = 1e5f * (float) DX[X,Y].Magnitude; } );
            m_imageHeight.WritePixels((uint X, uint Y, ref float4 _color) => { _color.x = factor * (float)(h[X, Y].r - heightMin.r); });

            imagePanelHeight.Bitmap = m_imageHeight.AsBitmap;

            FFT.Dispose();
        }