Esempio n. 1
0
        private void LoadResults( System.IO.FileInfo _FileName )
        {
            try {
                groupBoxOptions.Enabled = false;

                // Dispose of existing resources
                if ( m_TextureTargets[0][0] != null ) {
                    m_TextureTargets[0][0].Dispose();
                    m_TextureTargets[0][1].Dispose();
                    m_TextureTargets[1][0].Dispose();
                    m_TextureTargets[1][1].Dispose();
                    m_TextureTargets[2][0].Dispose();
                    m_TextureTargets[2][1].Dispose();
                    m_TextureTargetCombined.Dispose();
                }
                m_TextureTargets[0][0] = null;
                m_TextureTargets[0][1] = null;
                m_TextureTargets[1][0] = null;
                m_TextureTargets[1][1] = null;
                m_TextureTargets[2][0] = null;
                m_TextureTargets[2][1] = null;
                m_TextureTargetCombined = null;

                if ( m_imageResults[0] != null )
                    m_imageResults[0].Dispose();
                if ( m_imageResults[1] != null )
                    m_imageResults[1].Dispose();
                if ( m_imageResults[2] != null )
                    m_imageResults[2].Dispose();
                if ( m_imageResultCombined != null )
                    m_imageResultCombined.Dispose();
            //				m_imageResults[0] = new ImageUtility.ImageFile( W, H, ImageUtility.ImageFile.PIXEL_FORMAT.R8, m_sRGBProfile );
            //				m_imageResults[1] = new ImageUtility.ImageFile( W, H, ImageUtility.ImageFile.PIXEL_FORMAT.R8, m_sRGBProfile );
            //				m_imageResults[2] = new ImageUtility.ImageFile( W, H, ImageUtility.ImageFile.PIXEL_FORMAT.R8, m_sRGBProfile );
            //				m_imageResultCombined = new ImageUtility.ImageFile( W, H, ImageUtility.ImageFile.PIXEL_FORMAT.RGBA8, m_sRGBProfile );
                m_imageResults[0] = new ImageUtility.ImageFile();
                m_imageResults[1] = new ImageUtility.ImageFile();
                m_imageResults[2] = new ImageUtility.ImageFile();
                m_imageResultCombined = new ImageUtility.ImageFile();

                // Load the result images assuming it's in sRGB space
                string[]		FileNames = new string[4] {
                    System.IO.Path.Combine( System.IO.Path.GetDirectoryName( _FileName.FullName ), System.IO.Path.GetFileNameWithoutExtension( _FileName.FullName ) + "_translucency0.png" ),
                    System.IO.Path.Combine( System.IO.Path.GetDirectoryName( _FileName.FullName ), System.IO.Path.GetFileNameWithoutExtension( _FileName.FullName ) + "_translucency1.png" ),
                    System.IO.Path.Combine( System.IO.Path.GetDirectoryName( _FileName.FullName ), System.IO.Path.GetFileNameWithoutExtension( _FileName.FullName ) + "_translucency2.png" ),
                    System.IO.Path.Combine( System.IO.Path.GetDirectoryName( _FileName.FullName ), System.IO.Path.GetFileNameWithoutExtension( _FileName.FullName ) + "_translucency.png" ),
                };
                ImageUtility.ImageFile[]	images = new ImageUtility.ImageFile[] {
                    m_imageResults[0],
                    m_imageResults[1],
                    m_imageResults[2],
                    m_imageResultCombined
                };
                Texture2D[]		Results = new Texture2D[] {
                    m_TextureTargets[0][0],
                    m_TextureTargets[1][0],
                    m_TextureTargets[2][0],
                    m_TextureTargetCombined,
                };
                ImagePanel[]	Panels = new ImagePanel[] {
                    imagePanelResult0,
                    imagePanelResult1,
                    imagePanelResult2,
                    imagePanelResult3,
                };

                for ( int i=0; i < 4; i++ ) {
                    ImageUtility.ImageFile	B = images[i];
                    B.Load( new System.IO.FileInfo( FileNames[i] ) );

                    Panels[i].Image = B;

                    // Build the texture assuming sRGB sources
                    float4[]	scanline = new float4[B.Width];
                    float4		linearRGB = float4.Zero;

                    PixelsBuffer	sourceMap = new PixelsBuffer( B.Width*B.Height*16 );
                    using ( System.IO.BinaryWriter Wr = sourceMap.OpenStreamWrite() )
                        for ( uint Y=0; Y < B.Height; Y++ ) {
                            B.ReadScanline( Y, scanline );
                            for ( uint X=0; X < B.Width; X++ ) {
                                m_sRGBProfile.GammaRGB2LinearRGB( scanline[X], ref linearRGB );
                                Wr.Write( linearRGB.x );
                                Wr.Write( linearRGB.y );
                                Wr.Write( linearRGB.z );
                                Wr.Write( linearRGB.w );
                            }
                        }

                    Results[i] = new Texture2D( m_Device, W, H, 1, 1, PIXEL_FORMAT.RGBA32_FLOAT, false, true, new PixelsBuffer[] { sourceMap } );
                }

                m_TextureTargets[0][0] = Results[0];
                m_TextureTargets[0][1] = Results[0];
                m_TextureTargets[1][0] = Results[1];
                m_TextureTargets[1][1] = Results[1];
                m_TextureTargets[2][0] = Results[2];
                m_TextureTargets[2][1] = Results[2];
                m_TextureTargetCombined = Results[3];
            }
            catch ( Exception _e ) {
                MessageBox( "An error occurred while opening the result maps \"" + _FileName.FullName + "\":\n\n", _e );
            }
        }
Esempio n. 2
0
        private void Generate()
        {
            try {
                groupBoxOptions.Enabled = false;

                //////////////////////////////////////////////////////////////////////////
                // 0] Assign empty textures
                if ( m_imageSourceNormal == null )
                    LoadNormalMap( new System.IO.FileInfo( "default_normal.png" ) );
                if ( m_imageSourceTransmittance == null )
                    LoadTransmittanceMap( new System.IO.FileInfo( "default_transmittance.png" ) );
                if ( m_imageSourceAlbedo == null )
                    LoadAlbedoMap( new System.IO.FileInfo( "default_albedo.png" ) );

                m_TextureTargets[0][0].RemoveFromLastAssignedSlots();
                m_TextureTargets[0][1].RemoveFromLastAssignedSlots();
                m_TextureTargets[1][0].RemoveFromLastAssignedSlots();
                m_TextureTargets[1][1].RemoveFromLastAssignedSlots();
                m_TextureTargets[2][0].RemoveFromLastAssignedSlots();
                m_TextureTargets[2][1].RemoveFromLastAssignedSlots();

                //////////////////////////////////////////////////////////////////////////
                // 1] Apply bilateral filtering to the input texture as a pre-process
                ApplyBilateralFiltering( m_TextureSourceThickness, m_TextureFilteredThickness, floatTrackbarControlBilateralRadius.Value, floatTrackbarControlBilateralTolerance.Value, false );

                //////////////////////////////////////////////////////////////////////////
                // 2] Compute visibility texture
                BuildVisibilityMap( m_TextureFilteredThickness, m_TextureSourceVisibility );
            //BuildVisibilityMap( m_TextureSourceThickness, m_TextureSourceVisibility );	// While we're not using bilateral filtering...

            //*				//////////////////////////////////////////////////////////////////////////
                // 3] Compute directional occlusion
                if ( !m_CS_GenerateTranslucencyMap.Use() )
                    throw new Exception( "Can't generate translucency map as compute shader failed to compile!" );

                // Prepare computation parameters
                m_CB_Generate.m._Width = (uint) W;
                m_CB_Generate.m._Height = (uint) H;
                m_CB_Generate.m._TexelSize_mm = TextureSize_mm / Math.Max( W, H );
                m_CB_Generate.m._Thickness_mm = Thickness_mm;
                m_CB_Generate.m._KernelSize = (uint) integerTrackbarControlKernelSize.Value;
                m_CB_Generate.m._Sigma_a = floatTrackbarControlAbsorptionCoefficient.Value;
                m_CB_Generate.m._Sigma_s = floatTrackbarControlScatteringCoefficient.Value;
                m_CB_Generate.m._g = floatTrackbarControlScatteringAnisotropy.Value;

                float	IOR = floatTrackbarControlRefractionIndex.Value;
                m_CB_Generate.m._F0 = (IOR - 1.0f) / (IOR + 1.0f);
                m_CB_Generate.m._F0 *= m_CB_Generate.m._F0;

                // Assign inputs
                m_TextureFilteredThickness.SetCS( 0 );
            //m_TextureSourceThickness.SetCS( 0 );	// While we're not using bilateral filtering...
                m_TextureSourceNormal.SetCS( 1 );
                m_TextureSourceTransmittance.SetCS( 2 );
                m_TextureSourceAlbedo.SetCS( 3 );
                m_TextureSourceVisibility.SetCS( 4 );

                uint	groupsCountX = (W + 15) >> 4;
                uint	groupsCountY = (H + 15) >> 4;

                uint	raysCount = (uint) integerTrackbarControlRaysCount.Value;
                uint	updateCountMax = Math.Max( 1, raysCount / 100 );
                uint	updateCount = 0;

                // For each HL2 basis direction
                for ( int i=0; i < 3; i++ ) {

            // 					switch ( i ) {
            // 						case 0: m_CB_Generate.m._Light = new float3( (float) Math.Sqrt( 2.0 / 3.0 ), 0.0f, (float) Math.Sqrt( 1.0 / 3.0 ) ); break;
            // 						case 1: m_CB_Generate.m._Light = new float3( (float) -Math.Sqrt( 1.0 / 6.0 ), (float)  Math.Sqrt( 1.0 / 2.0 ), (float) Math.Sqrt( 1.0 / 3.0 ) ); break;
            // 						case 2: m_CB_Generate.m._Light = new float3( (float) -Math.Sqrt( 1.0 / 6.0 ), (float) -Math.Sqrt( 1.0 / 2.0 ), (float) Math.Sqrt( 1.0 / 3.0 ) ); break;
            // 					}

                    // Clear initial target
                    m_Device.Clear( m_TextureTargets[i][0], float4.Zero );

                    // Start
                    for ( uint rayIndex=0; rayIndex < raysCount; rayIndex++ ) {

                        m_CB_Generate.m._Light = m_rays[i][rayIndex];
            //m_CB_Generate.m._Light = float3.UnitZ;
                        m_CB_Generate.UpdateData();

                        m_TextureTargets[i][0].SetCS( 5 );
                        m_TextureTargets[i][1].SetCSUAV( 0 );

             					m_CS_GenerateTranslucencyMap.Dispatch( groupsCountX, groupsCountY, 1 );

                        m_TextureTargets[i][0].RemoveFromLastAssignedSlots();
                        m_TextureTargets[i][1].RemoveFromLastAssignedSlotUAV();

                        // Swap targets
                        Texture2D	Temp = m_TextureTargets[i][0];
                        m_TextureTargets[i][0] = m_TextureTargets[i][1];
                        m_TextureTargets[i][1] = Temp;

                        // Progress
                        if ( updateCount++ >= updateCountMax ) {
                            updateCount = 0;

                            m_Device.Present( true );

                            float	progress = (float) (raysCount*i+1) / (3*raysCount);
                            progressBar.Value = (int) (0.01f * (VISIBILITY_PROGRESS + (100-VISIBILITY_PROGRESS) * progress) * progressBar.Maximum);
                            Application.DoEvents();
                        }
                    }
                }

             				progressBar.Value = progressBar.Maximum;

                //////////////////////////////////////////////////////////////////////////
                // 3] Normalize results
                if ( !m_CS_Helper_Normalize.Use() )
                    throw new Exception( "Can't normalize translucency map as normalization compute shader failed to compile!" );

                for ( int i=0; i < 3; i++ ) {

                    m_CB_Helper.m._Width = (uint) W;
                    m_CB_Helper.m._Height = (uint) H;
                    m_CB_Helper.m._Parms = (1.0f / raysCount) * float3.One;
                    m_CB_Helper.UpdateData();

                    m_TextureTargets[i][0].SetCS( 0 );
                    m_TextureTargets[i][1].SetCSUAV( 0 );

                    m_CS_Helper_Normalize.Dispatch( groupsCountX, groupsCountY, 1 );

                    m_TextureTargets[i][0].RemoveFromLastAssignedSlots();
                    m_TextureTargets[i][1].RemoveFromLastAssignedSlotUAV();

                    // Swap targets
                    Texture2D	Temp = m_TextureTargets[i][0];
                    m_TextureTargets[i][0] = m_TextureTargets[i][1];
                    m_TextureTargets[i][1] = Temp;
                }
            //*/

                //////////////////////////////////////////////////////////////////////////
                // 4] Copy target to staging for CPU readback and update the resulting bitmaps
                ImagePanel[]	ImagePanels = new ImagePanel[3] {
                    imagePanelResult0,
                    imagePanelResult1,
                    imagePanelResult2,
                };
                for ( int i=0; i < 3; i++ ) {
                    if ( m_imageResults[i] != null )
                        m_imageResults[i].Dispose();
            //					m_BitmapResults[i] = new ImageUtility.Bitmap( W, H, m_LinearProfile );
                    m_imageResults[i] = new ImageUtility.ImageFile( W, H, ImageUtility.ImageFile.PIXEL_FORMAT.R8, m_sRGBProfile );

                    // Copy from GPU to CPU
                    m_TextureTarget_CPU.CopyFrom( m_TextureTargets[i][0] );

                    float4[]		scanline = new float4[W];
                    float4			gammaRGB = float4.Zero;
                    PixelsBuffer	Pixels = m_TextureTarget_CPU.Map( 0, 0 );
                    using ( System.IO.BinaryReader R = Pixels.OpenStreamRead() )
                        for ( uint Y=0; Y < H; Y++ ) {
                            R.BaseStream.Position = Y * Pixels.RowPitch;
                            for ( uint X=0; X < W; X++ ) {
                                gammaRGB.Set( R.ReadSingle(), R.ReadSingle(), R.ReadSingle(), R.ReadSingle() );
                                m_sRGBProfile.LinearRGB2GammaRGB( gammaRGB, ref scanline[X] );
                            }
                            m_imageResults[i].WriteScanline( Y, scanline );
                        }

                    Pixels.Dispose();
                    m_TextureTarget_CPU.UnMap( 0, 0 );

                    // Assign result
                    ImagePanels[i].Image = m_imageResults[i];
                }

                //////////////////////////////////////////////////////////////////////////
                // 5] Mix results
                MixResults( MixColor );

            } catch ( Exception _e ) {
                MessageBox( "An error occurred during generation!\r\n\r\nDetails: ", _e );
            } finally {
                groupBoxOptions.Enabled = true;
            }
        }