Exemple #1
0
        /// <summary>
        /// Reads back a lobe texture histogram into an array
        /// </summary>
        /// <param name="_texHistogram_CPU"></param>
        /// <param name="_scatteringOrder"></param>
        /// <returns></returns>
        public static double[,] HistogramTexture2Array(Texture2D _texHistogram_CPU, int _scatteringOrder)
        {
            int scattMin = _scatteringOrder - 1;                        // Because scattering order 1 is actually stored in first slice of the texture array
            int scattMax = scattMin + 1;                                // To simulate a single scattering order
//			int	scattMax = MAX_SCATTERING_ORDER;	// To simulate all scattering orders accumulated

            int W = _texHistogram_CPU.Width;
            int H = _texHistogram_CPU.Height;

            double[,]       histogramData = new double[W, H];

            for (int scatteringOrder = scattMin; scatteringOrder < scattMax; scatteringOrder++)
            {
                PixelsBuffer Content = _texHistogram_CPU.Map(0, scatteringOrder);
                using (BinaryReader R = Content.OpenStreamRead())
                    for (int Y = 0; Y < H; Y++)
                    {
                        for (int X = 0; X < W; X++)
                        {
                            histogramData[X, Y] += W * H * R.ReadSingle();
                        }
                    }
                Content.CloseStream();
                _texHistogram_CPU.UnMap(0, scatteringOrder);
            }

            return(histogramData);
        }
        private void    FFT_CPUInOut(Complex[,] _input, Complex[,] _output, float _sign)
        {
            try {
                //////////////////////////////////////////////////////////////////////////
                // Load initial content
                PixelsBuffer           loadingBuffer = m_texBufferCPU.MapWrite(0, 0);
                System.IO.BinaryWriter W             = loadingBuffer.OpenStreamWrite();
                for (int Y = 0; Y < m_size; Y++)
                {
                    for (int X = 0; X < m_size; X++)
                    {
                        W.Write((float)_input[X, Y].r);
                        W.Write((float)_input[X, Y].i);
                    }
                }
                loadingBuffer.CloseStream();
                m_texBufferCPU.UnMap(loadingBuffer);
                m_texBufferIn.CopyFrom(m_texBufferCPU);

                //////////////////////////////////////////////////////////////////////////
                // Apply multiple shader passes
                FFT_GPUInOut(_sign);

                //////////////////////////////////////////////////////////////////////////
                // Read back content
                m_texBufferCPU.CopyFrom(m_texBufferOut);

                PixelsBuffer           resultBuffer = m_texBufferCPU.MapRead(0, 0);
                System.IO.BinaryReader R            = resultBuffer.OpenStreamRead();
                for (int Y = 0; Y < m_size; Y++)
                {
                    for (int X = 0; X < m_size; X++)
                    {
                        _output[X, Y].Set(R.ReadSingle(), R.ReadSingle());
                    }
                }
                resultBuffer.CloseStream();
                m_texBufferCPU.UnMap(resultBuffer);
            } catch (Exception _e) {
                throw new Exception("An error occurred while performing the FFT!", _e);
            }
        }
Exemple #3
0
        void    CheckAgainstFFTW()
        {
            if (m_FFTW_2D == null)
            {
                m_FFTW_2D       = new fftwlib.FFT2D(SIGNAL_SIZE_2D, SIGNAL_SIZE_2D);
                m_test_CPU      = new Texture2D(m_device2D, SIGNAL_SIZE_2D, SIGNAL_SIZE_2D, 1, 1, ImageUtility.PIXEL_FORMAT.RG32F, ImageUtility.COMPONENT_FORMAT.AUTO, true, false, null);
                m_FFTW2D_Output = new Texture2D(m_device2D, SIGNAL_SIZE_2D, SIGNAL_SIZE_2D, 1, 1, ImageUtility.PIXEL_FORMAT.RG32F, ImageUtility.COMPONENT_FORMAT.AUTO, false, true, null);
            }

            // Retrieve input as CPU-accessible
            m_test_CPU.CopyFrom(m_FFT2D_GPU.Input);
            PixelsBuffer bufferIn = m_test_CPU.MapRead(0, 0);

            m_test_CPU.UnMap(bufferIn);

            float2[,]       input_GPU = new float2[SIGNAL_SIZE_2D, SIGNAL_SIZE_2D];
            using (System.IO.BinaryReader R = bufferIn.OpenStreamRead())
                for (int Y = 0; Y < SIGNAL_SIZE_2D; Y++)
                {
                    for (int X = 0; X < SIGNAL_SIZE_2D; X++)
                    {
                        input_GPU[X, Y].Set(R.ReadSingle(), R.ReadSingle());
                    }
                }
            bufferIn.Dispose();

            // Apply FFT
            m_FFT2D_GPU.FFT_GPUInOut(-1.0f);

            // Retrieve output as CPU-accessible
            m_test_CPU.CopyFrom(m_FFT2D_GPU.Output);
            PixelsBuffer bufferOut = m_test_CPU.MapRead(0, 0);

            m_test_CPU.UnMap(bufferOut);

            float2[,]       output_GPU = new float2[SIGNAL_SIZE_2D, SIGNAL_SIZE_2D];
            using (System.IO.BinaryReader R = bufferOut.OpenStreamRead())
                for (int Y = 0; Y < SIGNAL_SIZE_2D; Y++)
                {
                    for (int X = 0; X < SIGNAL_SIZE_2D; X++)
                    {
                        output_GPU[X, Y].Set(R.ReadSingle(), R.ReadSingle());
                    }
                }
            bufferOut.Dispose();

            // Process input with FFTW
            m_FFTW_2D.FillInputSpatial((int _x, int _y, out float _r, out float _i) => {
                _r = input_GPU[_x, _y].x;
                _i = input_GPU[_x, _y].y;
            });
            m_FFTW_2D.Execute(fftwlib.FFT2D.Normalization.DIMENSIONS_PRODUCT);
            float2[,]       output_FFTW = new float2[SIGNAL_SIZE_2D, SIGNAL_SIZE_2D];
            m_FFTW_2D.GetOutput((int _x, int _y, float _r, float _i) => {
                output_FFTW[_x, _y].Set(_r, _i);
            });

            // Upload FFTW output to GPU
            bufferOut = m_test_CPU.MapWrite(0, 0);
            using (System.IO.BinaryWriter W = bufferOut.OpenStreamWrite())
                for (int Y = 0; Y < SIGNAL_SIZE_2D; Y++)
                {
                    for (int X = 0; X < SIGNAL_SIZE_2D; X++)
                    {
                        W.Write(output_FFTW[X, Y].x);
                        W.Write(output_FFTW[X, Y].y);
                    }
                }
            m_test_CPU.UnMap(bufferOut);
            bufferOut.Dispose();
            m_FFTW2D_Output.CopyFrom(m_test_CPU);

            // Compare
            float sumSqDiffR = 0.0f;
            float sumSqDiffI = 0.0f;

            for (int Y = 0; Y < SIGNAL_SIZE_2D; Y++)
            {
                for (int X = 0; X < SIGNAL_SIZE_2D; X++)
                {
                    float2 GPU  = output_GPU[X, Y];
                    float2 FFTW = output_FFTW[X, Y];
                    float2 diff = GPU - FFTW;
                    sumSqDiffR += diff.x * diff.x;
                    sumSqDiffI += diff.y * diff.y;
                }
            }
            labelDiff2D.Text = "SqDiff = " + sumSqDiffR.ToString("G3") + " , " + sumSqDiffI.ToString("G3");
        }
Exemple #4
0
        private void    Generate()
        {
            try {
                tabControlGenerators.Enabled = false;

                //////////////////////////////////////////////////////////////////////////
                // 1] Apply bilateral filtering to the input texture as a pre-process
                ApplyBilateralFiltering(m_textureSourceHeightMap, m_textureTarget0, floatTrackbarControlBilateralRadius.Value, floatTrackbarControlBilateralTolerance.Value, checkBoxWrap.Checked);


                //////////////////////////////////////////////////////////////////////////
                // 2] Compute directional occlusion
                m_textureTarget1.RemoveFromLastAssignedSlots();

                // Prepare computation parameters
                m_textureTarget0.SetCS(0);
                m_textureTarget1.SetCSUAV(0);
                m_SB_Rays.SetInput(1);

                m_CB_Input.m.RaysCount       = (UInt32)Math.Min(MAX_THREADS, integerTrackbarControlRaysCount.Value);
                m_CB_Input.m.MaxStepsCount   = (UInt32)integerTrackbarControlMaxStepsCount.Value;
                m_CB_Input.m.Tile            = (uint)(checkBoxWrap.Checked ? 1 : 0);
                m_CB_Input.m.TexelSize_mm    = TextureSize_mm / Math.Max(W, H);
                m_CB_Input.m.Displacement_mm = TextureHeight_mm;

                // Start
                if (!m_CS_GenerateSSBumpMap.Use())
                {
                    throw new Exception("Can't generate self-shadowed bump map as compute shader failed to compile!");
                }

                uint h          = Math.Max(1, MAX_LINES * 1024 / W);
                uint callsCount = (uint)Math.Ceiling((float)H / h);
                for (uint i = 0; i < callsCount; i++)
                {
                    m_CB_Input.m.Y0 = i * h;
                    m_CB_Input.UpdateData();

                    m_CS_GenerateSSBumpMap.Dispatch(W, h, 1);

                    m_device.Present(true);

                    progressBar.Value = (int)(0.01f * (BILATERAL_PROGRESS + (100 - BILATERAL_PROGRESS) * (i + 1) / (callsCount)) * progressBar.Maximum);
//					for ( int a=0; a < 10; a++ )
                    Application.DoEvents();
                }

                m_textureTarget1.RemoveFromLastAssignedSlotUAV();                       // So we can use it as input for next stage

                progressBar.Value = progressBar.Maximum;

                // Compute in a single shot (this is madness!)
//              m_CB_Input.m.y = 0;
//              m_CB_Input.UpdateData();
//              m_CS_GenerateSSBumpMap.Dispatch( W, H, 1 );


                //////////////////////////////////////////////////////////////////////////
                // 3] Copy target to staging for CPU readback and update the resulting bitmap
                m_textureTarget_CPU.CopyFrom(m_textureTarget1);

                if (m_imageResult != null)
                {
                    m_imageResult.Dispose();
                }
                m_imageResult = null;
                m_imageResult = new ImageUtility.ImageFile(W, H, ImageUtility.PIXEL_FORMAT.RGBA8, m_linearProfile);

                float4[]     scanline = new float4[W];
                PixelsBuffer pixels   = m_textureTarget_CPU.MapRead(0, 0);
                using (System.IO.BinaryReader R = pixels.OpenStreamRead())
                    for (uint Y = 0; Y < H; Y++)
                    {
                        R.BaseStream.Position = Y * pixels.RowPitch;
                        for (int X = 0; X < W; X++)
                        {
                            scanline[X].Set(R.ReadSingle(), R.ReadSingle(), R.ReadSingle(), R.ReadSingle());
                        }
                        m_imageResult.WriteScanline(Y, scanline);
                    }

                m_textureTarget_CPU.UnMap(pixels);

                // Assign result
                viewportPanelResult.Image = m_imageResult;
            } catch (Exception _e) {
                MessageBox("An error occurred during generation!\r\n\r\nDetails: ", _e);
            } finally {
                tabControlGenerators.Enabled = true;
            }
        }