/// <summary> /// Concatenates multiple tables into one single texture 2D array /// </summary> /// <param name="_tablesFileNames"></param> /// <param name="_targetFileName"></param> /// <param name="_foramt"></param> static void ExportTexture(FileInfo[] _tablesFileNames, FileInfo _targetFileName, ImageUtility.PIXEL_FORMAT _format) { // Load tables LTC[][,] tables = new LTC[_tablesFileNames.Length][, ]; for (int i = 0; i < _tablesFileNames.Length; i++) { int validResultsCount; LTC[,] table = FitterForm.LoadTable(_tablesFileNames[i], out validResultsCount); if (validResultsCount != table.Length) { throw new Exception("Not all table results are valid!"); } tables[i] = table; if (i != 0 && (table.GetLength(0) != tables[0].GetLength(0) || table.GetLength(1) != tables[0].GetLength(1))) { throw new Exception("Table dimensions mismatch!"); } } // Create the Texture2DArray uint W = (uint)tables[0].GetLength(0); uint H = (uint)tables[0].GetLength(1); ImageUtility.ImagesMatrix M = new ImageUtility.ImagesMatrix(); M.InitTexture2DArray(W, H, (uint)tables.Length, 1); M.AllocateImageFiles(_format, new ImageUtility.ColorProfile(ImageUtility.ColorProfile.STANDARD_PROFILE.LINEAR)); for (int i = 0; i < tables.Length; i++) { LTC[,] table = tables[i]; // ImageUtility.ImageFile I = new ImageUtility.ImageFile( W, H, _format, profile ); // M[(uint) i][0][0] = I; double largest = 0; ImageUtility.ImageFile I = M[(uint)i][0][0]; I.WritePixels((uint _X, uint _Y, ref float4 _color) => { LTC ltc = table[_X, _Y]; const double tol = 1e-6; // if ( Mathf.Abs( ltc.invM[2,2] - 1 ) > tol ) // throw new Exception( "Not one!" ); if (Mathf.Abs(ltc.invM[0, 1]) > tol || Mathf.Abs(ltc.invM[1, 0]) > tol || Mathf.Abs(ltc.invM[1, 2]) > tol || Mathf.Abs(ltc.invM[2, 1]) > tol) { throw new Exception("Not zero!"); } largest = Math.Max(largest, Math.Abs(ltc.invM[2, 2] - 1)); double factor = 1.0 / ltc.invM[2, 2]; _color.x = (float)(factor * ltc.invM[0, 0]); _color.y = (float)(factor * ltc.invM[0, 2]); _color.z = (float)(factor * ltc.invM[1, 1]); _color.w = (float)(factor * ltc.invM[2, 0]); }); } M.DDSSaveFile(_targetFileName, ImageUtility.COMPONENT_FORMAT.AUTO); }
Texture2D LoadFalseColors(FileInfo _fileName) { using (ImageUtility.ImageFile sourceImage = new ImageUtility.ImageFile(_fileName, ImageUtility.ImageFile.FILE_FORMAT.PNG)) { ImageUtility.ImageFile convertedImage = new ImageUtility.ImageFile(); convertedImage.ConvertFrom(sourceImage, ImageUtility.PIXEL_FORMAT.BGRA8); using (ImageUtility.ImagesMatrix image = new ImageUtility.ImagesMatrix(convertedImage, ImageUtility.ImagesMatrix.IMAGE_TYPE.sRGB)) return(new Texture2D(m_device, image, ImageUtility.COMPONENT_FORMAT.UNORM_sRGB)); } }
private unsafe void UpdateProgress(ImageUtility.ImageFile _image, uint Y, bool _Bias) { const uint REFRESH_EVERY_N_SCANLINES = 4; if (Y == 0 || (Y & (REFRESH_EVERY_N_SCANLINES - 1)) != 0) { return; } viewportPanelResult.Image = _image; Application.DoEvents(); }
void ConvertCrossToCubeMap(FileInfo _crossMapFile, FileInfo _cubeMapFile) { using (ImageUtility.ImageFile crossMap = new ImageUtility.ImageFile(_crossMapFile)) { using (ImageUtility.ImagesMatrix cubeMap = new ImageUtility.ImagesMatrix()) { cubeMap.ConvertCrossToCubeMap(crossMap, true); cubeMap.DDSSaveFile(_cubeMapFile, ImageUtility.COMPONENT_FORMAT.AUTO); // Optional: BC6H Compress //ImageUtility.ImagesMatrix compressedCubeMap = m_device.DDSCompress( cubeMap, ImageUtility.ImagesMatrix.COMPRESSION_TYPE.BC6H, ImageUtility.COMPONENT_FORMAT.AUTO ); //compressedCubeMap.DDSSaveFile( _cubeMapFile, ImageUtility.COMPONENT_FORMAT.AUTO ); } } }
protected override void OnLoad(EventArgs e) { base.OnLoad(e); try { m_device.Init(panelOutput.Handle, false, true); } catch (Exception _e) { m_device = null; MessageBox.Show("Failed to initialize DX device!\n\n" + _e.Message, "Heat Wave Test", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } m_CB_Main = new ConstantBuffer <CB_Main>(m_device, 0); m_shader_HeatDiffusion0 = new Shader(m_device, new FileInfo("./Shaders/HeatDiffusion.hlsl"), VERTEX_FORMAT.Pt4, "VS", null, "PS"); m_shader_HeatDiffusion1 = new Shader(m_device, new FileInfo("./Shaders/HeatDiffusion2.hlsl"), VERTEX_FORMAT.Pt4, "VS", null, "PS"); m_shader_RenderHeatMap = new Shader(m_device, new FileInfo("./Shaders/RenderHeatMap.hlsl"), VERTEX_FORMAT.Pt4, "VS", null, "PS"); m_shader_DrawObstacles = new Shader(m_device, new FileInfo("./Shaders/DrawObstacles.hlsl"), VERTEX_FORMAT.Pt4, "VS", null, "PS"); m_tex_HeatMap_Staging = new Texture2D(m_device, (uint)GRAPH_SIZE, (uint)GRAPH_SIZE, 1, 1, ImageUtility.PIXEL_FORMAT.RGBA32F, ImageUtility.COMPONENT_FORMAT.AUTO, true, false, null); m_tex_HeatMap0 = new Texture2D(m_device, (uint)GRAPH_SIZE, (uint)GRAPH_SIZE, 1, 1, ImageUtility.PIXEL_FORMAT.RGBA32F, ImageUtility.COMPONENT_FORMAT.AUTO, false, false, null); m_tex_HeatMap1 = new Texture2D(m_device, (uint)GRAPH_SIZE, (uint)GRAPH_SIZE, 1, 1, ImageUtility.PIXEL_FORMAT.RGBA32F, ImageUtility.COMPONENT_FORMAT.AUTO, false, false, null); m_tex_Obstacles0 = new Texture2D(m_device, (uint)GRAPH_SIZE + 2, (uint)GRAPH_SIZE + 2, 1, 1, ImageUtility.PIXEL_FORMAT.RGBA8, ImageUtility.COMPONENT_FORMAT.UNORM, false, false, null); m_tex_Obstacles1 = new Texture2D(m_device, (uint)GRAPH_SIZE + 2, (uint)GRAPH_SIZE + 2, 1, 1, ImageUtility.PIXEL_FORMAT.RGBA8, ImageUtility.COMPONENT_FORMAT.UNORM, false, false, null); m_tex_Obstacles_Staging = new Texture2D(m_device, (uint)GRAPH_SIZE + 2, (uint)GRAPH_SIZE + 2, 1, 1, ImageUtility.PIXEL_FORMAT.RGBA8, ImageUtility.COMPONENT_FORMAT.UNORM, true, false, null); ClearObstacles(); buttonResetObstacles_Click(null, EventArgs.Empty); m_tex_Search = new Texture2D(m_device, (uint)GRAPH_SIZE, (uint)GRAPH_SIZE, 1, 1, ImageUtility.PIXEL_FORMAT.RGBA8, ImageUtility.COMPONENT_FORMAT.UNORM, false, false, null); m_tex_Search_Staging = new Texture2D(m_device, (uint)GRAPH_SIZE, (uint)GRAPH_SIZE, 1, 1, ImageUtility.PIXEL_FORMAT.RGBA8, ImageUtility.COMPONENT_FORMAT.UNORM, true, false, null); // Load false colors using (ImageUtility.ImageFile sourceImage = new ImageUtility.ImageFile(new FileInfo("../../Data/Images/Gradients/Magma.png"), ImageUtility.ImageFile.FILE_FORMAT.PNG)) { ImageUtility.ImageFile convertedImage = new ImageUtility.ImageFile(); convertedImage.ConvertFrom(sourceImage, ImageUtility.PIXEL_FORMAT.BGRA8); using (ImageUtility.ImagesMatrix image = new ImageUtility.ImagesMatrix(convertedImage, ImageUtility.ImagesMatrix.IMAGE_TYPE.sRGB)) m_tex_FalseColors0 = new Texture2D(m_device, image, ImageUtility.COMPONENT_FORMAT.UNORM_sRGB); } using (ImageUtility.ImageFile sourceImage = new ImageUtility.ImageFile(new FileInfo("../../Data/Images/Gradients/Viridis.png"), ImageUtility.ImageFile.FILE_FORMAT.PNG)) { ImageUtility.ImageFile convertedImage = new ImageUtility.ImageFile(); convertedImage.ConvertFrom(sourceImage, ImageUtility.PIXEL_FORMAT.BGRA8); using (ImageUtility.ImagesMatrix image = new ImageUtility.ImagesMatrix(convertedImage, ImageUtility.ImagesMatrix.IMAGE_TYPE.sRGB)) m_tex_FalseColors1 = new Texture2D(m_device, image, ImageUtility.COMPONENT_FORMAT.UNORM_sRGB); } // BuildGraph(); Application.Idle += Application_Idle; }
void BuildFont() { string charSet = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~éèêëôöàçÔÖÂÊÉœûüù"; m_fontRectangles = new Rectangle[charSet.Length]; for (int charIndex = 0; charIndex < charSet.Length; charIndex++) { char C = charSet[charIndex]; int index = (int)C; m_char2Index[index] = charIndex; } // Load atlas & rectangles using (ImageUtility.ImageFile file = new ImageUtility.ImageFile(new FileInfo("Atlas.png"))) { ImageUtility.ImageFile file2 = new ImageUtility.ImageFile(file, ImageUtility.PIXEL_FORMAT.RGBA8); using (ImageUtility.ImagesMatrix M = new ImageUtility.ImagesMatrix(file2, ImageUtility.ImagesMatrix.IMAGE_TYPE.sRGB)) { m_tex_FontAtlas = new Texture2D(m_device, M, ImageUtility.COMPONENT_FORMAT.UNORM_sRGB); } } using (FileStream S = new FileInfo("Atlas.rect").OpenRead()) using (BinaryReader R = new BinaryReader(S)) { // Read both CPU and GPU versions float recW = 1.0f / m_tex_FontAtlas.Width; float recH = 1.0f / m_tex_FontAtlas.Height; using (PixelsBuffer content = new PixelsBuffer((uint)(16 * m_fontRectangles.Length))) { using (BinaryWriter W = content.OpenStreamWrite()) { for (int i = 0; i < m_fontRectangles.Length; i++) { m_fontRectangles[i].X = R.ReadInt32(); m_fontRectangles[i].Y = R.ReadInt32(); m_fontRectangles[i].Width = R.ReadInt32(); m_fontRectangles[i].Height = R.ReadInt32(); W.Write(recW * (float)m_fontRectangles[i].X); W.Write(recH * (float)m_fontRectangles[i].Y); W.Write(recW * (float)m_fontRectangles[i].Width); W.Write(recH * (float)m_fontRectangles[i].Height); } } m_tex_FontRectangle = new Texture2D(m_device, (uint)m_fontRectangles.Length, 1, 1, 1, ImageUtility.PIXEL_FORMAT.RGBA32F, ImageUtility.COMPONENT_FORMAT.AUTO, false, false, new PixelsBuffer[] { content }); } } }
void BuildNoiseTextures() { PixelsBuffer Content = new PixelsBuffer(NOISE_SIZE * NOISE_SIZE * NOISE_SIZE * 4); PixelsBuffer Content4D = new PixelsBuffer(NOISE_SIZE * NOISE_SIZE * NOISE_SIZE * 16); SimpleRNG.SetSeed(521288629, 362436069); float4 V = float4.Zero; using (BinaryWriter W = Content.OpenStreamWrite()) { using (BinaryWriter W2 = Content4D.OpenStreamWrite()) { for (int Z = 0; Z < NOISE_SIZE; Z++) { for (int Y = 0; Y < NOISE_SIZE; Y++) { for (int X = 0; X < NOISE_SIZE; X++) { V.Set((float)SimpleRNG.GetUniform(), (float)SimpleRNG.GetUniform(), (float)SimpleRNG.GetUniform(), (float)SimpleRNG.GetUniform()); W.Write(V.x); W2.Write(V.x); W2.Write(V.y); W2.Write(V.z); W2.Write(V.w); } } } } } m_tex_Noise = new Texture3D(m_device, NOISE_SIZE, NOISE_SIZE, NOISE_SIZE, 1, ImageUtility.PIXEL_FORMAT.R8, ImageUtility.COMPONENT_FORMAT.UNORM, false, false, new PixelsBuffer[] { Content }); m_tex_Noise4D = new Texture3D(m_device, NOISE_SIZE, NOISE_SIZE, NOISE_SIZE, 1, ImageUtility.PIXEL_FORMAT.RGBA8, ImageUtility.COMPONENT_FORMAT.UNORM, false, false, new PixelsBuffer[] { Content4D }); // Load blue noise using (ImageUtility.ImageFile I = new ImageUtility.ImageFile(new FileInfo("BlueNoise64x64_16bits.png"))) { ImageUtility.ImagesMatrix M = new ImageUtility.ImagesMatrix(new ImageUtility.ImageFile[, ] { { I } }); m_tex_BlueNoise = new Texture2D(m_device, M, ImageUtility.COMPONENT_FORMAT.UNORM); } }
public Texture2D Image2Texture(System.IO.FileInfo _fileName, ImageUtility.COMPONENT_FORMAT _componentFormat) { ImageUtility.ImagesMatrix images = null; if (_fileName.Extension.ToLower() == ".dds") { images = new ImageUtility.ImagesMatrix(); images.DDSLoadFile(_fileName); } else { ImageUtility.ImageFile image = new ImageUtility.ImageFile(_fileName); if (image.PixelFormat != ImageUtility.PIXEL_FORMAT.BGRA8) { ImageUtility.ImageFile badImage = image; image = new ImageUtility.ImageFile(); image.ConvertFrom(badImage, ImageUtility.PIXEL_FORMAT.BGRA8); badImage.Dispose(); } images = new ImageUtility.ImagesMatrix(new ImageUtility.ImageFile[1, 1] { { image } }); } return(new Texture2D(m_device, images, _componentFormat)); }
private void LoadThicknessMap( System.IO.FileInfo _FileName ) { try { groupBoxOptions.Enabled = false; // Dispose of existing resources if ( m_ImageSourceThickness != null ) m_ImageSourceThickness.Dispose(); m_ImageSourceThickness = null; if ( m_TextureSourceThickness != null ) m_TextureSourceThickness.Dispose(); m_TextureSourceThickness = null; if ( m_TextureSourceVisibility != null ) m_TextureSourceVisibility.Dispose(); m_TextureSourceVisibility = null; if ( m_TextureTarget_CPU != null ) { m_TextureTarget_CPU.Dispose(); } m_TextureTarget_CPU = null; if ( m_TextureFilteredThickness != null ) m_TextureFilteredThickness.Dispose(); m_TextureFilteredThickness = null; 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_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; if ( m_TextureTargetCombined != null ) m_TextureTargetCombined.Dispose(); m_TextureTargetCombined = null; // Load the source image m_SourceFileName = _FileName; m_ImageSourceThickness = new ImageUtility.ImageFile( _FileName ); imagePanelThicknessMap.Image = m_ImageSourceThickness; W = m_ImageSourceThickness.Width; H = m_ImageSourceThickness.Height; // Build the source texture assuming the image is in linear space float4[] scanline = new float4[W]; PixelsBuffer sourceHeightMap = new PixelsBuffer( W*H*4 ); using ( System.IO.BinaryWriter Wr = sourceHeightMap.OpenStreamWrite() ) for ( uint Y=0; Y < H; Y++ ) { m_ImageSourceThickness.ReadScanline( Y, scanline ); for ( uint X=0; X < W; X++ ) { Wr.Write( scanline[X].x ); } } m_TextureSourceThickness = new Texture2D( m_Device, W, H, 1, 1, PIXEL_FORMAT.R32_FLOAT, false, false, new PixelsBuffer[] { sourceHeightMap } ); // Build the 3D visibility texture m_TextureSourceVisibility = new Texture3D( m_Device, W, H, VISIBILITY_SLICES, 1, PIXEL_FORMAT.R16_FLOAT, false, true, null ); // Build the target UAV & staging texture for readback m_TextureFilteredThickness = new Texture2D( m_Device, W, H, 1, 1, PIXEL_FORMAT.R32_FLOAT, false, true, null ); for ( int i=0; i < 3; i++ ) { m_TextureTargets[i][0] = new Texture2D( m_Device, W, H, 1, 1, PIXEL_FORMAT.RGBA32_FLOAT, false, true, null ); m_TextureTargets[i][1] = new Texture2D( m_Device, W, H, 1, 1, PIXEL_FORMAT.RGBA32_FLOAT, false, true, null ); } m_TextureTargetCombined = new Texture2D( m_Device, W, H, 1, 1, PIXEL_FORMAT.RGBA32_FLOAT, false, true, null ); m_TextureTarget_CPU = new Texture2D( m_Device, W, H, 1, 1, PIXEL_FORMAT.RGBA32_FLOAT, true, false, null ); groupBoxOptions.Enabled = true; buttonGenerate.Focus(); } catch ( Exception _e ) { MessageBox( "An error occurred while opening the thickness map \"" + _FileName.FullName + "\":\n\n", _e ); } }
private void Generate() { try { panelParameters.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, BILATERAL_PROGRESS ); ////////////////////////////////////////////////////////////////////////// // 2] Compute directional occlusion m_textureTarget1.RemoveFromLastAssignedSlots(); // Prepare computation parameters m_textureTarget0.SetCS( 0 ); m_textureTarget1.SetCSUAV( 0 ); m_SB_Rays.SetInput( 1 ); m_TextureSourceNormal.SetCS( 2 ); 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_GenerateAOMap.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 ( int i=0; i < CallsCount; i++ ) { m_CB_Input.m.Y0 = (UInt32) (i * h); m_CB_Input.UpdateData(); m_CS_GenerateAOMap.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 ); // ImageUtility.ColorProfile profile = m_profilesRGB; // AO maps are sRGB! (although strange, that's certainly to have more range in dark values) ImageUtility.ColorProfile profile = m_profileLinear; float3 whitePoint_xyY = new float3( profile.Chromas.White, 0 ); float3 whitePoint_XYZ = new float3(); ImageUtility.Bitmap tempBitmap = new ImageUtility.Bitmap( W, H ); Renderer.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++ ) { whitePoint_xyY.z = R.ReadSingle(); // Linear value ImageUtility.ColorProfile.xyY2XYZ( whitePoint_xyY, ref whitePoint_XYZ ); tempBitmap[X,Y] = new float4( whitePoint_XYZ, 1 ); } } Pixels.Dispose(); m_textureTarget_CPU.UnMap( 0, 0 ); // Convert to RGB ImageUtility.ImageFile temmpImageRGBA32F = new ImageUtility.ImageFile(); tempBitmap.ToImageFile( temmpImageRGBA32F, profile ); if ( m_imageResult == null ) m_imageResult = new ImageUtility.ImageFile(); m_imageResult.ToneMapFrom( temmpImageRGBA32F, ( float3 _HDR, ref float3 _LDR ) => { _LDR = _HDR; // Return as-is.. } ); // Assign result viewportPanelResult.Bitmap = m_imageResult.AsBitmap; } catch ( Exception _e ) { MessageBox( "An error occurred during generation!\r\n\r\nDetails: ", _e ); } finally { panelParameters.Enabled = true; } }
private void buttonTestBilateral_Click( object sender, EventArgs e ) { try { panelParameters.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, 100 ); progressBar.Value = progressBar.Maximum; ////////////////////////////////////////////////////////////////////////// // 2] Copy target to staging for CPU readback and update the resulting bitmap m_textureTarget_CPU.CopyFrom( m_textureTarget0 ); ImageUtility.Bitmap tempBitmap = new ImageUtility.Bitmap( W, H ); Renderer.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++ ) { float AO = R.ReadSingle(); tempBitmap[X,Y] = new float4( AO, AO, AO, 1 ); } } Pixels.Dispose(); m_textureTarget_CPU.UnMap( 0, 0 ); // Convert to RGB // ImageUtility.ColorProfile Profile = m_ProfilesRGB; // AO maps are sRGB! (although strange, that's certainly to have more range in dark values) ImageUtility.ColorProfile Profile = m_profilesRGB; // AO maps are sRGB! (although strange, that's certainly to have more range in dark values) if ( m_imageResult != null ) m_imageResult.Dispose(); m_imageResult = new ImageUtility.ImageFile(); tempBitmap.ToImageFile( m_imageResult, Profile ); // Assign result viewportPanelResult.Bitmap = m_imageResult.AsCustomBitmap( ( ref float4 _color ) => {} ); } catch ( Exception _e ) { MessageBox( "An error occurred during generation!\r\n\r\nDetails: ", _e ); } finally { panelParameters.Enabled = true; } }
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.ImageFile.PIXEL_FORMAT.RGBA8, m_linearProfile ); float4[] scanline = new float4[W]; 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 ( int X=0; X < W; X++ ) { scanline[X].Set( R.ReadSingle(), R.ReadSingle(), R.ReadSingle(), R.ReadSingle() ); } m_imageResult.WriteScanline( Y, scanline ); } pixels.Dispose(); m_textureTarget_CPU.UnMap( 0, 0 ); // Assign result viewportPanelResult.Image = m_imageResult; } catch ( Exception _e ) { MessageBox( "An error occurred during generation!\r\n\r\nDetails: ", _e ); } finally { tabControlGenerators.Enabled = true; } }
private void LoadHeightMap( System.IO.FileInfo _FileName ) { try { tabControlGenerators.Enabled = false; // Dispose of existing resources if ( m_imageSourceHeightMap != null ) m_imageSourceHeightMap.Dispose(); m_imageSourceHeightMap = null; if ( m_textureTarget_CPU != null ) m_textureTarget_CPU.Dispose(); m_textureTarget_CPU = null; if ( m_textureTarget0 != null ) m_textureTarget0.Dispose(); m_textureTarget0 = null; if ( m_textureTarget1 != null ) m_textureTarget1.Dispose(); m_textureTarget1 = null; if ( m_textureSourceHeightMap != null ) m_textureSourceHeightMap.Dispose(); m_textureSourceHeightMap = null; // Load the source image m_SourceFileName = _FileName; m_imageSourceHeightMap = new ImageUtility.ImageFile( _FileName ); outputPanelInputHeightMap.Image = m_imageSourceHeightMap; W = m_imageSourceHeightMap.Width; H = m_imageSourceHeightMap.Height; // Build the source texture assuming the image is in linear space float4[] scanline = new float4[W]; PixelsBuffer SourceHeightMap = new PixelsBuffer( W*H*4 ); using ( System.IO.BinaryWriter Wr = SourceHeightMap.OpenStreamWrite() ) for ( uint Y=0; Y < H; Y++ ) { m_imageSourceHeightMap.ReadScanline( Y, scanline ); for ( int X=0; X < W; X++ ) Wr.Write( scanline[X].x ); } m_textureSourceHeightMap = new Texture2D( m_device, W, H, 1, 1, PIXEL_FORMAT.R32_FLOAT, false, false, new PixelsBuffer[] { SourceHeightMap } ); // Build the target UAV & staging texture for readback m_textureTarget0 = new Texture2D( m_device, W, H, 1, 1, PIXEL_FORMAT.R32_FLOAT, false, true, null ); m_textureTarget1 = new Texture2D( m_device, W, H, 1, 1, PIXEL_FORMAT.RGBA32_FLOAT, false, true, null ); m_textureTarget_CPU = new Texture2D( m_device, W, H, 1, 1, PIXEL_FORMAT.RGBA32_FLOAT, true, false, null ); tabControlGenerators.Enabled = true; buttonGenerate.Focus(); } catch ( Exception _e ) { MessageBox( "An error occurred while opening the image:\n\n", _e ); } }
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 ); } }
public static void DummyLoadWebPage(Uri _URL, WebPageSourceAvailable _onSourceAvailable, WebPagePieceRendered _onPieceRendered, WebPageSuccess _onSuccess, WebPageError _onError) { // string content = "DUMMY CONTENT!"; string content = "<blockquote class=\"twitter-tweet\"><p lang=\"en\" dir=\"ltr\">Appropriate for December. <a href=\"https://t.co/dzNBXmcreS\">pic.twitter.com/dzNBXmcreS</a></p>— In Otter News (@Otter_News)" + "<a href=\"https://twitter.com/Otter_News/status/1204733982149160960?ref_src=twsrc%5Etfw\">December 11, 2019</a></blockquote> <script async src=\"https://platform.twitter.com/widgets.js\" charset=\"utf-8\"></script>"; /*string content = @"<blockquote class=""Tweet h-entry js-tweetIdInfo subject expanded"" cite=""https://twitter.com/Poulin2012/status/1204065818432167937"" data-tweet-id=""1204065818432167937"" data-scribe=""section:subject""> * <div class=""Tweet-header""> * <a class=""TweetAuthor-avatar Identity-avatar u-linkBlend"" data-scribe=""element:user_link"" href=""https://twitter.com/Poulin2012"" aria-label=""Alexis Poulin (nom d'utilisateur : Poulin2012)""><img class=""Avatar"" data-scribe=""element:avatar"" data-src-2x=""https://pbs.twimg.com/profile_images/1110858983357771778/aTqqWLFY_bigger.jpg"" alt="""" data-src-1x=""https://pbs.twimg.com/profile_images/1110858983357771778/aTqqWLFY_normal.jpg"" src=""https://pbs.twimg.com/profile_images/1110858983357771778/aTqqWLFY_normal.jpg""></a> * * * * * <div class=""TweetAuthor js-inViewportScribingTarget"" data-scribe=""component:author""> * <a class=""TweetAuthor-link Identity u-linkBlend"" data-scribe=""element:user_link"" href=""https://twitter.com/Poulin2012"" aria-label=""Alexis Poulin (nom d'utilisateur : Poulin2012)""> * <div class=""TweetAuthor-nameScreenNameContainer""> * <span class=""TweetAuthor-decoratedName""> * <span class=""TweetAuthor-name Identity-name customisable-highlight"" title=""Alexis Poulin"" data-scribe=""element:name"">Alexis Poulin</span> * <span class=""TweetAuthor-verifiedBadge"" data-scribe=""element:verified_badge""><div class=""Icon Icon--verified "" aria-label=""Compte certifié"" title=""Compte certifié"" role=""img""></div> * <b class=""u-hiddenVisually"">✔</b></span> * </span> * <span class=""TweetAuthor-screenName Identity-screenName"" title=""@Poulin2012"" data-scribe=""element:screen_name"" dir=""ltr"">@Poulin2012</span> * </div> * </a> * </div> * * <div class=""Tweet-brand""> * <a href=""https://twitter.com/Poulin2012/status/1204065818432167937"" data-scribe=""element:logo""><span class=""FollowButton-bird""><div class=""Icon Icon--twitter "" aria-label=""Voir sur Twitter"" title=""Voir sur Twitter"" role=""presentation""></div> * </span></a> * </div> * </div> * <div class=""Tweet-body e-entry-content"" data-scribe=""component:tweet""> * * <div class=""Tweet-target js-inViewportScribingTarget""></div> * <p class=""Tweet-text e-entry-title"" lang=""fr"" dir=""ltr"">A propos de « la haine » qui visiblement en novlangue veut dire « capter des images de violences policières »... <a href=""https://t.co/6W9zbPCuCG"" rel=""nofollow noopener"" dir=""ltr"" data-expanded-url=""https://twitter.com/davduf/status/1204059641413586946"" class=""link customisable"" target=""_blank"" title=""https://twitter.com/davduf/status/1204059641413586946"" data-tweet-id=""1204059641413586946"" data-tweet-item-type=""23"" data-scribe=""element:url""><span class=""u-hiddenVisually"">https://</span>twitter.com/davduf/status/<span class=""u-hiddenVisually"">1204059641413586946 </span>…</a></p> * * * * <div class=""Tweet-card""> * <div class=""QuoteTweet"" tabindex=""0"" data-scribe=""section:quote""> * <a class=""QuoteTweet-link"" data-tweet-id=""1204059641413586946"" data-tweet-item-type=""23"" href=""https://twitter.com/davduf/status/1204059641413586946"" target=""_blank"" rel=""noopener""> * <div class=""QuoteTweet-nonMediaContainer""> * * * * <div class=""TweetAuthor js-inViewportScribingTarget TweetAuthor--oneLine"" data-scribe=""component:author""> * * <div class=""TweetAuthor-nameScreenNameContainer""> * <span class=""TweetAuthor-decoratedName""> * <span class=""TweetAuthor-name Identity-name customisable-highlight"" title=""David Dufresne"" data-scribe=""element:name"">David Dufresne</span> * <span class=""TweetAuthor-verifiedBadge"" data-scribe=""element:verified_badge""><div class=""Icon Icon--verified "" aria-label=""Compte certifié"" title=""Compte certifié"" role=""img""></div> * <b class=""u-hiddenVisually"">✔</b></span> * </span> * <span class=""TweetAuthor-screenName Identity-screenName"" title=""@davduf"" data-scribe=""element:screen_name"" dir=""ltr"">@davduf</span> * </div> * * </div> * * <div></div> * <p class=""QuoteTweet-text e-entry-title"" lang=""fr"" dir=""ltr"">Le sénateur Grand, profitant de la proposition de loi de « Lutte contre la haine » sur internet (PPL), propose une amande de 15 000 € pour captation d'image de policiers. <span class=""PrettyLink-prefix"">#</span><span class=""PrettyLink-value"">ViolencesPolicières</span> <span class=""PrettyLink-prefix"">#</span><span class=""PrettyLink-value"">LibertédInformer</span><br><br>Source: <span class=""u-hiddenVisually"">http://www.</span>senat.fr/amendements/co<span class=""u-hiddenVisually"">mmissions/2018-2019/645/Amdt_COM-13.html </span>…</p> * </div> * <div class=""QuotedTweet-media""> * * <article class=""MediaCard * * customisable-border"" data-scribe=""component:card"" dir=""ltr""> * <div class=""MediaCard-media"" data-scribe=""element:photo""> * * <div class=""MediaCard-widthConstraint js-cspForcedStyle"" style=""max-width: 1200px"" data-style=""max-width: 1200px""> * <div class=""MediaCard-mediaContainer js-cspForcedStyle MediaCard--roundedBottom"" style=""padding-bottom: 68.9167%"" data-style=""padding-bottom: 68.9167%""> * <div class=""MediaCard-mediaAsset NaturalImage""> * <img class=""NaturalImage-image"" data-image=""https://pbs.twimg.com/media/ELWt20_W4AAea8q"" data-image-format=""png"" width=""1200"" height=""827"" title=""Voir l'image sur Twitter"" alt=""Voir l'image sur Twitter"" src=""https://pbs.twimg.com/media/ELWt20_W4AAea8q?format=png&name=small""> * </div> * </div> * </div> * </div> * </article> * * * * </div> * </a> * </div> * </div> * * * <div class=""TweetInfo""> * <div class=""TweetInfo-like""> * <a class=""TweetInfo-heart"" title=""J'aime"" href=""https://twitter.com/intent/like?tweet_id=1204065818432167937"" data-scribe=""component:actions""> * <div data-scribe=""element:heart""><div class=""Icon Icon--heart "" aria-label=""J'aime"" title=""J'aime"" role=""img""></div> * </div> * <span class=""TweetInfo-heartStat"" data-scribe=""element:heart_count"">704</span> * </a> * </div> * <div class=""TweetInfo-timeGeo""> * * <a class=""u-linkBlend u-url customisable-highlight long-permalink"" data-datetime=""2019-12-09T15:50:36+0000"" data-scribe=""element:full_timestamp"" href=""https://twitter.com/Poulin2012/status/1204065818432167937""> * * * * * * * * * <time class=""dt-updated"" datetime=""2019-12-09T15:50:36+0000"" pubdate="""" title=""Heure de publication : 09 décembre 2019 15:50:36 (UTC)"">10:50 - 9 déc. 2019</time></a></div> * <div class=""tweet-InformationCircle"" data-scribe=""element:notice""><a href=""https://support.twitter.com/articles/20175256"" class=""Icon Icon--informationCircleWhite js-inViewportScribingTarget"" title=""Informations sur les Publicités Twitter et confidentialité""><span class=""u-hiddenVisually"">Informations sur les Publicités Twitter et confidentialité</span></a> * </div> * </div> * </div> * </blockquote>"; * //*/ // string title = "dummy title"; // return new Fiche( _title, _URL, null, Fiche.BuildHTMLDocument( title, content ) ); string dummyTitle = "Dummy Title"; string dummyHTML = BuildHTMLDocument(dummyTitle, content); uint seed = (uint)_URL.GetHashCode(); ImageUtility.ImageFile dummyPage = new ImageUtility.ImageFile(Fiche.ChunkWebPageSnapshot.ms_defaultWebPageWidth, Fiche.ChunkWebPageSnapshot.ms_defaultWebPageHeight, ImageUtility.PIXEL_FORMAT.BGRA8, new ImageUtility.ColorProfile(ImageUtility.ColorProfile.STANDARD_PROFILE.sRGB)); dummyPage.WritePixels((uint _X, uint _Y, ref float4 _color) => { _color.x = Mathf.Sin(0.1f * (seed + _X)); _color.y = Mathf.Sin(0.123f * (seed + _Y)); _color.z = Mathf.Sin(0.01234f * (seed + _X + _Y)); _color.w = 1.0f; }); // Notify _onSourceAvailable(dummyTitle, dummyHTML, null); _onPieceRendered(0, new Rectangle(0, 0, (int)Fiche.ChunkWebPageSnapshot.ms_defaultWebPageWidth, (int)Fiche.ChunkWebPageSnapshot.ms_defaultWebPageHeight), dummyPage); _onSuccess(); }
private void LoadAlbedoMap( System.IO.FileInfo _FileName ) { try { // Dispose of existing resources if ( m_imageSourceAlbedo != null ) m_imageSourceAlbedo.Dispose(); m_imageSourceAlbedo = null; if ( m_TextureSourceAlbedo != null ) m_TextureSourceAlbedo.Dispose(); m_TextureSourceAlbedo = null; // Load the source image m_imageSourceAlbedo = new ImageUtility.ImageFile( _FileName ); imagePanelAlbedoMap.Image = m_imageSourceAlbedo; uint W = m_imageSourceAlbedo.Width; uint H = m_imageSourceAlbedo.Height; // Build the source texture assuming the image's color profile float4[] scanline = new float4[W]; float4 linearRGB = float4.Zero; ImageUtility.ColorProfile imageProfile = m_imageSourceAlbedo.ColorProfile; // ImageUtility.ColorProfile imageProfile = m_sRGBProfile; // float4[,] ContentRGB = new float4[W,H]; // m_LinearProfile.XYZ2RGB( m_imageSourceAlbedo.ContentXYZ, ContentRGB ); PixelsBuffer SourceMap = new PixelsBuffer( W*H*16 ); using ( System.IO.BinaryWriter Wr = SourceMap.OpenStreamWrite() ) for ( uint Y=0; Y < H; Y++ ) { m_imageSourceAlbedo.ReadScanline( Y, scanline ); for ( uint X=0; X < W; X++ ) { imageProfile.GammaRGB2LinearRGB( scanline[X], ref linearRGB ); Wr.Write( linearRGB.x ); Wr.Write( linearRGB.y ); Wr.Write( linearRGB.z ); Wr.Write( linearRGB.w ); } } m_TextureSourceAlbedo = new Texture2D( m_Device, W, H, 1, 1, PIXEL_FORMAT.RGBA32_FLOAT, false, false, new PixelsBuffer[] { SourceMap } ); } catch ( Exception _e ) { MessageBox( "An error occurred while opening the albedo map \"" + _FileName.FullName + "\":\n\n", _e ); } }
private void LoadNormalMap( System.IO.FileInfo _FileName ) { try { // Dispose of existing resources if ( m_imageSourceNormal != null ) m_imageSourceNormal.Dispose(); m_imageSourceNormal = null; if ( m_TextureSourceNormal != null ) m_TextureSourceNormal.Dispose(); m_TextureSourceNormal = null; // Load the source image m_imageSourceNormal = new ImageUtility.ImageFile( _FileName ); imagePanelNormalMap.Image = m_imageSourceNormal; uint W = m_imageSourceNormal.Width; uint H = m_imageSourceNormal.Height; // Build the source texture assuming the image is in linear space float4[] scanline = new float4[W]; PixelsBuffer sourceNormalMap = new PixelsBuffer( W*H*16 ); using ( System.IO.BinaryWriter Wr = sourceNormalMap.OpenStreamWrite() ) for ( uint Y=0; Y < H; Y++ ) { m_imageSourceNormal.ReadScanline( Y, scanline ); for ( uint X=0; X < W; X++ ) { Wr.Write( scanline[X].x ); Wr.Write( scanline[X].y ); Wr.Write( scanline[X].z ); Wr.Write( 1.0f ); } } m_TextureSourceNormal = new Texture2D( m_Device, W, H, 1, 1, PIXEL_FORMAT.RGBA32_FLOAT, false, false, new PixelsBuffer[] { sourceNormalMap } ); } catch ( Exception _e ) { MessageBox( "An error occurred while opening the normal map \"" + _FileName.FullName + "\":\n\n", _e ); } }
private void LoadNormalMap( System.IO.FileInfo _FileName ) { try { // Dispose of existing resources if ( m_imageSourceNormal != null ) m_imageSourceNormal.Dispose(); m_imageSourceNormal = null; if ( m_TextureSourceNormal != null ) m_TextureSourceNormal.Dispose(); m_TextureSourceNormal = null; // Load the source image // Assume it's in linear space (all normal maps should be in linear space, with the default value being (0.5, 0.5, 1)) m_imageSourceNormal = new ImageUtility.ImageFile( _FileName ); imagePanelNormalMap.Bitmap = m_imageSourceNormal.AsBitmap; uint W = m_imageSourceNormal.Width; uint H = m_imageSourceNormal.Height; // Build the source texture float4[] scanline = new float4[W]; Renderer.PixelsBuffer SourceNormalMap = new Renderer.PixelsBuffer( W*H*4*4 ); using ( System.IO.BinaryWriter Wr = SourceNormalMap.OpenStreamWrite() ) for ( int Y=0; Y < H; Y++ ) { m_imageSourceNormal.ReadScanline( (uint) Y, scanline ); for ( int X=0; X < W; X++ ) { float Nx = 2.0f * scanline[X].x - 1.0f; float Ny = 1.0f - 2.0f * scanline[X].y; float Nz = 2.0f * scanline[X].z - 1.0f; Wr.Write( Nx ); Wr.Write( Ny ); Wr.Write( Nz ); Wr.Write( 1.0f ); } } m_TextureSourceNormal = new Renderer.Texture2D( m_device, W, H, 1, 1, Renderer.PIXEL_FORMAT.RGBA32_FLOAT, false, false, new Renderer.PixelsBuffer[] { SourceNormalMap } ); } catch ( Exception _e ) { MessageBox( "An error occurred while opening the image:\n\n", _e ); } }
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; } }
protected override void OnLoad(EventArgs e) { base.OnLoad(e); try { m_device.Init(panelOutput.Handle, false, true); } catch (Exception _e) { m_device = null; MessageBox.Show("Failed to initialize DX device!\n\n" + _e.Message, "Heat Wave Test", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } try { ////////////////////////////////////////////////////////////////////////// // Load the graph we need to simulate m_graph = new ProtoParser.Graph(); // FileInfo file = new FileInfo( "../../../AI/Projects/Semantic Memory/Tests/Birds Database/Tools/ProtoParser/Concepts.graph" ); FileInfo file = new FileInfo("../../../AI/Projects/Semantic Memory/Tests/Birds Database/Tools/ProtoParser/TestGraph.graph"); if (!file.Exists) { file = new FileInfo("./Graphs/TestGraph.graph"); } using (FileStream S = file.OpenRead()) using (BinaryReader R = new BinaryReader(S)) m_graph.Read(R); ProtoParser.Neuron[] neurons = m_graph.Neurons; m_nodesCount = (uint)neurons.Length; /* * m_nodesCount = 2; * neurons = new ProtoParser.Neuron[2]; * neurons[0] = new ProtoParser.Neuron(); * neurons[1] = new ProtoParser.Neuron(); * neurons[0].LinkChild( neurons[1] ); * //*/ ////////////////////////////////////////////////////////////////////////// m_CB_Main = new ConstantBuffer <CB_Main>(m_device, 0); m_CB_Simulation = new ConstantBuffer <CB_Simulation>(m_device, 1); m_CB_Text = new ConstantBuffer <CB_Text>(m_device, 2); m_shader_ComputeForces = new ComputeShader(m_device, new FileInfo("./Shaders/SimulateGraph.hlsl"), "CS"); m_shader_Simulate = new ComputeShader(m_device, new FileInfo("./Shaders/SimulateGraph.hlsl"), "CS2"); #if RENDER_GRAPH_PROPER m_shader_RenderGraphNode = new Shader(m_device, new FileInfo("./Shaders/RenderGraph2.hlsl"), VERTEX_FORMAT.Pt4, "VS", null, "PS"); m_shader_RenderGraphLink = new Shader(m_device, new FileInfo("./Shaders/RenderGraph2.hlsl"), VERTEX_FORMAT.Pt4, "VS2", null, "PS2"); #else m_shader_RenderGraph = new Shader(m_device, new FileInfo("./Shaders/RenderGraph.hlsl"), VERTEX_FORMAT.Pt4, "VS", null, "PS"); #endif m_shader_RenderText = new Shader(m_device, new FileInfo("./Shaders/RenderText.hlsl"), VERTEX_FORMAT.Pt4, "VS", null, "PS"); // Build node info m_SB_Nodes = new StructuredBuffer <SB_NodeInfo>(m_device, m_nodesCount, true); m_neuron2ID = new Dictionary <ProtoParser.Neuron, uint>(neurons.Length); float maxMass = 0.0f; for (int neuronIndex = 0; neuronIndex < m_nodesCount; neuronIndex++) { ProtoParser.Neuron N = neurons[neuronIndex]; m_neuron2ID[N] = (uint)neuronIndex; uint linksCount = (uint)(N.ParentsCount + N.ChildrenCount + N.FeaturesCount); // m_SB_Nodes.m[neuronIndex].m_mass = (1 + 10.0f * linksCount) / (0.1f + N.Distance2Root); // Works with S=1e4 D=-1e3 // m_SB_Nodes.m[neuronIndex].m_mass = (1 + 1.0f * linksCount) / (0.01f + 0.0f * N.Distance2Root); // Works with S=1e4 D=-1e3 // m_SB_Nodes.m[neuronIndex].m_mass = (1 + 0.1f * linksCount) / (0.1f + N.Distance2Root); // Works with S=10 D=-10 m_SB_Nodes.m[neuronIndex].m_mass = 100.0f * (1 + 1.0f * linksCount); // Works with S=1e4 D=-1e3 m_SB_Nodes.m[neuronIndex].m_linkOffset = m_totalLinksCount; m_SB_Nodes.m[neuronIndex].m_linksCount = linksCount; m_SB_Nodes.m[neuronIndex].m_flags = 0U; maxMass = Mathf.Max(maxMass, m_SB_Nodes.m[neuronIndex].m_mass); m_totalLinksCount += linksCount; } m_SB_Nodes.m[0].m_mass = 1e4f; m_SB_Nodes.Write(); // Build node links m_SB_Links = new StructuredBuffer <uint>(m_device, m_totalLinksCount, true); m_SB_LinkSources = new StructuredBuffer <uint>(m_device, m_totalLinksCount, true); m_totalLinksCount = 0; for (int neuronIndex = 0; neuronIndex < m_nodesCount; neuronIndex++) { ProtoParser.Neuron N = neurons[neuronIndex]; foreach (ProtoParser.Neuron O in N.Parents) { m_SB_LinkSources.m[m_totalLinksCount] = (uint)neuronIndex; m_SB_Links.m[m_totalLinksCount++] = m_neuron2ID[O]; } foreach (ProtoParser.Neuron O in N.Children) { m_SB_LinkSources.m[m_totalLinksCount] = (uint)neuronIndex; m_SB_Links.m[m_totalLinksCount++] = m_neuron2ID[O]; } foreach (ProtoParser.Neuron O in N.Features) { m_SB_LinkSources.m[m_totalLinksCount] = (uint)neuronIndex; m_SB_Links.m[m_totalLinksCount++] = m_neuron2ID[O]; } } m_SB_Links.Write(); m_SB_LinkSources.Write(); // Setup initial CB m_CB_Main.m._nodesCount = m_nodesCount; m_CB_Main.m._resX = (uint)panelOutput.Width; m_CB_Main.m._resY = (uint)panelOutput.Height; m_CB_Main.m._maxMass = maxMass; m_CB_Main.m._cameraCenter = float2.Zero; m_CB_Main.m._cameraSize.Set(10.0f, 10.0f); m_CB_Main.m._hoveredNodeIndex = ~0U; m_CB_Main.UpdateData(); // Initialize sim buffers m_SB_Forces = new StructuredBuffer <float2>(m_device, m_nodesCount * m_nodesCount, false); m_SB_NodeSims[0] = new StructuredBuffer <SB_NodeSim>(m_device, m_nodesCount, true); m_SB_NodeSims[1] = new StructuredBuffer <SB_NodeSim>(m_device, m_nodesCount, true); buttonReset_Click(null, EventArgs.Empty); // m_shader_HeatDiffusion = new Shader( m_device, new FileInfo( "./Shaders/HeatDiffusion.hlsl" ), VERTEX_FORMAT.Pt4, "VS", null, "PS", null ); // m_tex_Search = new Texture2D( m_device, (uint) GRAPH_SIZE, (uint) GRAPH_SIZE, 1, 1, ImageUtility.PIXEL_FORMAT.RGBA8, ImageUtility.COMPONENT_FORMAT.UNORM, false, false, null ); // m_tex_Search_Staging = new Texture2D( m_device, (uint) GRAPH_SIZE, (uint) GRAPH_SIZE, 1, 1, ImageUtility.PIXEL_FORMAT.RGBA8, ImageUtility.COMPONENT_FORMAT.UNORM, true, false, null ); // Load false colors // using ( ImageUtility.ImageFile sourceImage = new ImageUtility.ImageFile( new FileInfo( "../../Images/Gradients/Viridis.png" ), ImageUtility.ImageFile.FILE_FORMAT.PNG ) ) { using (ImageUtility.ImageFile sourceImage = new ImageUtility.ImageFile(new FileInfo("../../Images/Gradients/Magma.png"), ImageUtility.ImageFile.FILE_FORMAT.PNG)) { ImageUtility.ImageFile convertedImage = new ImageUtility.ImageFile(); convertedImage.ConvertFrom(sourceImage, ImageUtility.PIXEL_FORMAT.BGRA8); using (ImageUtility.ImagesMatrix image = new ImageUtility.ImagesMatrix(convertedImage, ImageUtility.ImagesMatrix.IMAGE_TYPE.sRGB)) m_tex_FalseColors = new Texture2D(m_device, image, ImageUtility.COMPONENT_FORMAT.UNORM_sRGB); } // Prepare font atlas m_SB_Text = new StructuredBuffer <SB_Letter>(m_device, 1024U, true); BuildFont(); Application.Idle += Application_Idle; } catch (Exception _e) { m_device = null; MessageBox.Show("Failed to initialize shaders!\n\n" + _e.Message, "Heat Wave Test", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } }
private void LoadHeightMap(System.IO.FileInfo _FileName) { try { tabControlGenerators.Enabled = false; // Dispose of existing resources if (m_imageSourceHeightMap != null) { m_imageSourceHeightMap.Dispose(); } m_imageSourceHeightMap = null; if (m_textureTarget_CPU != null) { m_textureTarget_CPU.Dispose(); } m_textureTarget_CPU = null; if (m_textureTarget0 != null) { m_textureTarget0.Dispose(); } m_textureTarget0 = null; if (m_textureTarget1 != null) { m_textureTarget1.Dispose(); } m_textureTarget1 = null; if (m_textureSourceHeightMap != null) { m_textureSourceHeightMap.Dispose(); } m_textureSourceHeightMap = null; // Load the source image m_SourceFileName = _FileName; m_imageSourceHeightMap = new ImageUtility.ImageFile(_FileName); outputPanelInputHeightMap.Image = m_imageSourceHeightMap; W = m_imageSourceHeightMap.Width; H = m_imageSourceHeightMap.Height; // Build the source texture assuming the image is in linear space float4[] scanline = new float4[W]; PixelsBuffer SourceHeightMap = new PixelsBuffer(W * H * 4); // using ( System.IO.BinaryWriter Wr = SourceHeightMap.OpenStreamWrite() ) // for ( uint Y=0; Y < H; Y++ ) { // m_imageSourceHeightMap.ReadScanline( Y, scanline ); // for ( int X=0; X < W; X++ ) // Wr.Write( scanline[X].x ); // } using (System.IO.BinaryWriter Wr = SourceHeightMap.OpenStreamWrite()) { m_imageSourceHeightMap.ReadPixels((uint X, uint Y, ref float4 _color) => { Wr.Write(_color.x); }); } m_textureSourceHeightMap = new Texture2D(m_device, W, H, 1, 1, ImageUtility.PIXEL_FORMAT.R32F, ImageUtility.COMPONENT_FORMAT.AUTO, false, false, new PixelsBuffer[] { SourceHeightMap }); // Build the target UAV & staging texture for readback m_textureTarget0 = new Texture2D(m_device, W, H, 1, 1, ImageUtility.PIXEL_FORMAT.R32F, ImageUtility.COMPONENT_FORMAT.AUTO, false, true, null); m_textureTarget1 = new Texture2D(m_device, W, H, 1, 1, ImageUtility.PIXEL_FORMAT.RGBA32F, ImageUtility.COMPONENT_FORMAT.AUTO, false, true, null); m_textureTarget_CPU = new Texture2D(m_device, W, H, 1, 1, ImageUtility.PIXEL_FORMAT.RGBA32F, ImageUtility.COMPONENT_FORMAT.AUTO, true, false, null); tabControlGenerators.Enabled = true; buttonGenerate.Focus(); } catch (Exception _e) { MessageBox("An error occurred while opening the image:\n\n", _e); } }
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; } }
void GenerateMaterial(AxFService.AxFFile.Material _material, System.IO.DirectoryInfo _targetDirectory, TEXTURE_TYPE[] _textureTypes, string[] _textureGUIDs) { string templateTexture = " - <TEX_VARIABLE_NAME>:\n" + " m_Texture: {fileID: <FILE ID>, guid: <GUID>, type: 3}\n" + " m_Scale: {x: 1, y: 1}\n" + " m_Offset: {x: 0, y: 0}\n"; string materialContent = Properties.Resources.TemplateMaterial; ////////////////////////////////////////////////////////////////////////// // Generate textures array bool hasClearCoat = false; bool hasHeightMap = false; string texturesArray = ""; float specularLobeScaleFactor = 1.0f; float BRDFColorScaleFactor = 1.0f; float BTFFlakeScaleFactor = 1.0f; for (int textureIndex = 0; textureIndex < _textureTypes.Length; textureIndex++) { AxFService.AxFFile.Material.Texture texture = _material.Textures[textureIndex]; // int fileID = 2800000 + textureIndex; int fileID = 2800000; string GUID = _textureGUIDs[textureIndex]; string variableName = null; switch (_textureTypes[textureIndex]) { case TEXTURE_TYPE.ANISOTROPY_ANGLE: variableName = "_SVBRDF_AnisotropicRotationAngleMap"; break; case TEXTURE_TYPE.CLEARCOAT_COLOR: variableName = "_SVBRDF_ClearCoatColorMap_sRGB"; hasClearCoat = true; break; case TEXTURE_TYPE.CLEARCOAT_IOR: variableName = "_SVBRDF_ClearCoatIORMap_sRGB"; hasClearCoat = true; break; case TEXTURE_TYPE.CLEARCOAT_NORMAL: variableName = "_SVBRDF_ClearCoatNormalMap"; hasClearCoat = true; break; case TEXTURE_TYPE.DIFFUSE_COLOR: variableName = "_SVBRDF_DiffuseColorMap_sRGB"; break; case TEXTURE_TYPE.FRESNEL: variableName = "_SVBRDF_FresnelMap_sRGB"; break; case TEXTURE_TYPE.HEIGHT: variableName = "_SVBRDF_HeightMap"; hasHeightMap = true; break; case TEXTURE_TYPE.NORMAL: variableName = "_SVBRDF_NormalMap"; break; case TEXTURE_TYPE.OPACITY: variableName = "_SVBRDF_OpacityMap"; break; case TEXTURE_TYPE.SPECULAR_COLOR: variableName = "_SVBRDF_SpecularColorMap_sRGB"; break; case TEXTURE_TYPE.SPECULAR_LOBE: variableName = "_SVBRDF_SpecularLobeMap"; specularLobeScaleFactor = Mathf.Max(1, texture.MaxValue); break; // Car Paint case TEXTURE_TYPE.BRDF_COLOR: variableName = "_CarPaint_BRDFColorMap_sRGB"; BRDFColorScaleFactor = Mathf.Max(1, texture.MaxValue); break; case TEXTURE_TYPE.BTF_FLAKES: variableName = "_CarPaint_BTFFlakesMap_sRGB"; BTFFlakeScaleFactor = Mathf.Max(1, texture.MaxValue); break; default: throw new Exception("Unsupported texture type! Can't match to variable name..."); } string textureEntry = templateTexture.Replace("<FILE ID>", fileID.ToString()); textureEntry = textureEntry.Replace("<GUID>", GUID); textureEntry = textureEntry.Replace("<TEX_VARIABLE_NAME>", variableName); texturesArray += textureEntry; } ////////////////////////////////////////////////////////////////////////// // Generate uniforms array string uniformsArray = ""; string colorsArray = ""; uniformsArray += " - _materialSizeU_mm: 10\n"; uniformsArray += " - _materialSizeV_mm: 10\n"; switch (_material.Type) { case AxFService.AxFFile.Material.TYPE.SVBRDF: uniformsArray += " - _AxF_BRDFType: 0\n"; break; case AxFService.AxFFile.Material.TYPE.CARPAINT: uniformsArray += " - _AxF_BRDFType: 1\n"; break; case AxFService.AxFFile.Material.TYPE.BTF: uniformsArray += " - _AxF_BRDFType: 2\n"; break; } switch (_material.Type) { case AxFService.AxFFile.Material.TYPE.SVBRDF: { // Setup flags uint flags = 0; flags |= _material.IsAnisotropic ? 1U : 0; flags |= hasClearCoat ? 2U : 0; flags |= _material.GetPropertyInt("cc_no_refraction", 0) == 1 ? 0 : 4U; // Explicitly use no refraction flags |= hasHeightMap ? 8U : 0; uniformsArray += " - _flags: " + flags + "\n"; // Setup SVBRDF diffuse & specular types uint BRDFType = 0; BRDFType |= (uint)_material.DiffuseType; BRDFType |= ((uint)_material.SpecularType) << 1; uniformsArray += " - _SVBRDF_BRDFType: " + BRDFType + "\n"; // Setup SVBRDF fresnel and specular variants uint BRDFVariants = 0; BRDFVariants |= ((uint)_material.FresnelVariant & 3); switch (_material.SpecularVariant) { // Ward variants case AxFService.AxFFile.Material.SVBRDF_SPECULAR_VARIANT.GEISLERMORODER: BRDFVariants |= 0U << 2; break; case AxFService.AxFFile.Material.SVBRDF_SPECULAR_VARIANT.DUER: BRDFVariants |= 1U << 2; break; case AxFService.AxFFile.Material.SVBRDF_SPECULAR_VARIANT.WARD: BRDFVariants |= 2U << 2; break; // Blinn variants case AxFService.AxFFile.Material.SVBRDF_SPECULAR_VARIANT.ASHIKHMIN_SHIRLEY: BRDFVariants |= 0U << 4; break; case AxFService.AxFFile.Material.SVBRDF_SPECULAR_VARIANT.BLINN: BRDFVariants |= 1U << 4; break; case AxFService.AxFFile.Material.SVBRDF_SPECULAR_VARIANT.VRAY: BRDFVariants |= 2U << 4; break; case AxFService.AxFFile.Material.SVBRDF_SPECULAR_VARIANT.LEWIS: BRDFVariants |= 3U << 4; break; } uniformsArray += " - _SVBRDF_BRDFVariants: " + BRDFVariants + "\n"; // Write scale factor for specular lobe uniformsArray += " - _SVBRDF_SpecularLobeMap_Scale: " + specularLobeScaleFactor + "\n"; float heightMapSize_mm = 0.0f; // @TODO! uniformsArray += " - _SVBRDF_heightMapMax_mm: " + heightMapSize_mm + "\n"; break; } case AxFService.AxFFile.Material.TYPE.CARPAINT: { // Setup flags uint flags = 0; flags |= _material.IsAnisotropic ? 1U : 0; flags |= hasClearCoat ? 2U : 0; flags |= _material.GetPropertyInt("cc_no_refraction", 0) == 1 ? 0 : 4U; // Explicitly use no refraction // flags |= hasHeightMap ? 8U : 0; uniformsArray += " - _flags: " + flags + "\n"; uniformsArray += " - _CarPaint_CT_diffuse: " + _material.GetPropertyFloat("CT_diffuse", 0) + "\n"; uniformsArray += " - _CarPaint_IOR: " + _material.GetPropertyFloat("IOR", 1) + "\n"; uniformsArray += " - _CarPaint_maxThetaI: " + _material.GetPropertyInt("max_thetaI", 0) + "\n"; uniformsArray += " - _CarPaint_numThetaF: " + _material.GetPropertyInt("num_thetaF", 0) + "\n"; uniformsArray += " - _CarPaint_numThetaI: " + _material.GetPropertyInt("num_thetaI", 0) + "\n"; // Write scale factor for BRDF color uniformsArray += " - _CarPaint_BRDFColorMap_Scale: " + BRDFColorScaleFactor + "\n"; uniformsArray += " - _CarPaint_BTFFlakesMap_Scale: " + BTFFlakeScaleFactor + "\n"; // ========================================================================================= // Setup simple arrays as colors float[] CT_F0s = _material.GetPropertyRaw("CT_F0s") as float[]; if (CT_F0s == null || CT_F0s.Length != 3) { throw new Exception("Expected 3 float values for F0!"); } float[] CT_coeffs = _material.GetPropertyRaw("CT_coeffs") as float[]; if (CT_coeffs == null || CT_coeffs.Length != 3) { throw new Exception("Expected 3 float values for coefficients!"); } float[] CT_spreads = _material.GetPropertyRaw("CT_spreads") as float[]; if (CT_spreads == null || CT_spreads.Length != 3) { throw new Exception("Expected 3 float values for spreads!"); } uniformsArray += " - _CarPaint_lobesCount: " + CT_F0s.Length + "\n"; colorsArray += " - _CarPaint_CT_F0s: {r: " + CT_F0s[0] + ", g: " + CT_F0s[1] + ", b: " + CT_F0s[2] + ", a: 0 }\n"; colorsArray += " - _CarPaint_CT_coeffs: {r: " + CT_coeffs[0] + ", g: " + CT_coeffs[1] + ", b: " + CT_coeffs[2] + ", a: 0 }\n"; colorsArray += " - _CarPaint_CT_spreads: {r: " + CT_spreads[0] + ", g: " + CT_spreads[1] + ", b: " + CT_spreads[2] + ", a: 0 }\n"; // ========================================================================================= // Create a custom texture for sliceLUT int[] thetaFI_sliceLUT = _material.GetPropertyRaw("thetaFI_sliceLUT") as int[]; if (thetaFI_sliceLUT == null) { throw new Exception("Slice LUT not found!"); } ImageUtility.ImageFile texSliceLUT = new ImageUtility.ImageFile((uint)thetaFI_sliceLUT.Length, 1, ImageUtility.PIXEL_FORMAT.R8, new ImageUtility.ColorProfile(ImageUtility.ColorProfile.STANDARD_PROFILE.LINEAR)); texSliceLUT.WritePixels((uint _X, uint _Y, ref float4 _color) => { _color.x = thetaFI_sliceLUT[_X] / 255.0f; }); System.IO.FileInfo targetTextureFileName = new System.IO.FileInfo(System.IO.Path.Combine(_targetDirectory.FullName, _material.Name, "sliceLUT.png")); texSliceLUT.Save(targetTextureFileName, ImageUtility.ImageFile.FILE_FORMAT.PNG); string GUID = GenerateMeta(targetTextureFileName, checkBoxGenerateMeta.Checked, checkBoxOverwriteExistingMeta.Checked, false, false, false, false); string textureEntry = templateTexture.Replace("<FILE ID>", 2800000.ToString()); textureEntry = textureEntry.Replace("<GUID>", GUID); textureEntry = textureEntry.Replace("<TEX_VARIABLE_NAME>", "_CarPaint_thetaFI_sliceLUTMap"); texturesArray += textureEntry; break; } default: throw new Exception("TODO! Support feeding variables to other BRDF types!"); } ////////////////////////////////////////////////////////////////////////// // Replace placeholders in template materialContent = materialContent.Replace("<TEXTURES ARRAY>", texturesArray); materialContent = materialContent.Replace("<UNIFORMS ARRAY>", uniformsArray); materialContent = materialContent.Replace("<COLORS ARRAY>", colorsArray); // Write target file System.IO.FileInfo materialFileName = new System.IO.FileInfo(System.IO.Path.Combine(_targetDirectory.FullName, _material.Name, "material.mat")); using (System.IO.StreamWriter S = materialFileName.CreateText()) S.Write(materialContent); }
void DumpMaterial(AxFService.AxFFile.Material _material, System.IO.DirectoryInfo _targetDirectory) { System.IO.DirectoryInfo fullTargetDirectory = new System.IO.DirectoryInfo(System.IO.Path.Combine(_targetDirectory.FullName, _material.Name)); if (!fullTargetDirectory.Exists) { fullTargetDirectory.Create(); } AxFService.AxFFile.Material.Texture[] textures = _material.Textures; TEXTURE_TYPE[] textureTypes = new TEXTURE_TYPE[textures.Length]; string[] GUIDs = new string[textures.Length]; bool allGUIDsValid = true; for (int textureIndex = 0; textureIndex < textures.Length; textureIndex++) { AxFService.AxFFile.Material.Texture texture = textures[textureIndex]; TEXTURE_TYPE textureType = TEXTURE_TYPE.UNKNOWN; switch (texture.Name.ToLower()) { case "diffusecolor": textureType = TEXTURE_TYPE.DIFFUSE_COLOR; break; case "specularcolor": textureType = TEXTURE_TYPE.SPECULAR_COLOR; break; case "normal": textureType = TEXTURE_TYPE.NORMAL; break; case "fresnel": textureType = TEXTURE_TYPE.FRESNEL; break; case "specularlobe": textureType = TEXTURE_TYPE.SPECULAR_LOBE; break; case "anisorotation": textureType = TEXTURE_TYPE.ANISOTROPY_ANGLE; break; case "height": textureType = TEXTURE_TYPE.HEIGHT; break; case "opacity": textureType = TEXTURE_TYPE.OPACITY; break; case "clearcoatcolor": textureType = TEXTURE_TYPE.CLEARCOAT_COLOR; break; case "clearcoatnormal": textureType = TEXTURE_TYPE.CLEARCOAT_NORMAL; break; case "clearcoatior": textureType = TEXTURE_TYPE.CLEARCOAT_IOR; break; // Car Paint case "brdfcolors": textureType = TEXTURE_TYPE.BRDF_COLOR; break; case "btfflakes": textureType = TEXTURE_TYPE.BTF_FLAKES; break; default: throw new Exception("Unsupported texture type \"" + texture.Name + "\"!"); } textureTypes[textureIndex] = textureType; bool sRGB = ((int)textureType & (int)TEXTURE_TYPE.FLAG_sRGB) != 0; bool isNormalMap = ((int)textureType & (int)TEXTURE_TYPE.FLAG_NORMAL) != 0; bool isIOR = ((int)textureType & (int)TEXTURE_TYPE.FLAG_IOR) != 0; bool isAngle = ((int)textureType & (int)TEXTURE_TYPE.FLAG_ANGLE) != 0; bool isArray = ((int)textureType & (int)TEXTURE_TYPE.FLAG_2DARRAY) != 0; bool scale = ((int)textureType & (int)TEXTURE_TYPE.FLAG_SCALE_BY_MAX) != 0 && texture.MaxValue > 1; System.IO.FileInfo targetTextureFileName = new System.IO.FileInfo(System.IO.Path.Combine(fullTargetDirectory.FullName, texture.Name + ".png")); //* // // Dump as DDS // texture.Images.DDSSaveFile( new System.IO.FileInfo( @"D:\Workspaces\Unity Labs\AxF\AxF Shader\Assets\AxF Materials\X-Rite_14-LTH_Red_GoatLeather_4405_2479\" + texture.Name + ".dds" ), texture.ComponentFormat ); // Individual dump as RGBA8 files // ImageUtility.ImageFile source = texture.Images[0][0][0]; // ImageUtility.ImageFile temp = new ImageUtility.ImageFile(); // //temp.ConvertFrom( source, ImageUtility.PIXEL_FORMAT.BGRA8 ); // temp.ToneMapFrom( source, ( float3 _HDR, ref float3 _LDR ) => { _LDR =_HDR; } ); // temp.Save( new System.IO.FileInfo( @"D:\Workspaces\Unity Labs\AxF\AxF Shader\Assets\AxF Materials\X-Rite_14-LTH_Red_GoatLeather_4405_2479\" + texture.Name + ".png" ), ImageUtility.ImageFile.FILE_FORMAT.PNG ); uint mipsCount = texture.Images[0].MipLevelsCount; for (uint mipIndex = 0; mipIndex < mipsCount; mipIndex++) { // Individual dump as RGBA16 files ImageUtility.ImageFile source = texture.Images[0][mipIndex][0]; float factor = 1.0f; if (scale) { factor = 1.0f / texture.MaxValue; // Apply scale } // if ( textureType == TEXTURE_TYPE.BRDF_COLOR ) { // Random R = new Random(); // source.ReadWritePixels( ( uint _X, uint _Y, ref float4 _color ) => { // _color.x = (0.5f+_X) / 63.0f; // _color.y = (0.5f+_X) / 63.0f; // _color.z = (0.5f+_X) / 63.0f; // _color.w = (float) R.NextDouble(); // // // Apply sRGB // _color.x = Mathf.Pow( Math.Max( 0.0f, _color.x ), 1.0f / 2.2f ); // _color.y = Mathf.Pow( Math.Max( 0.0f, _color.y ), 1.0f / 2.2f ); // _color.z = Mathf.Pow( Math.Max( 0.0f, _color.z ), 1.0f / 2.2f ); // // } ); // } else if (sRGB) { source.ReadWritePixels((uint _X, uint _Y, ref float4 _color) => { _color.x = Mathf.Pow(Math.Max(0.0f, factor * _color.x), 1.0f / 2.2f); _color.y = Mathf.Pow(Math.Max(0.0f, factor * _color.y), 1.0f / 2.2f); _color.z = Mathf.Pow(Math.Max(0.0f, factor * _color.z), 1.0f / 2.2f); // _color.w = 1.0f; }); } if (isNormalMap) { source.ReadWritePixels((uint _X, uint _Y, ref float4 _color) => { _color.x = 0.5f * (1.0f + _color.x); _color.y = 0.5f * (1.0f + _color.y); _color.z = 0.5f * (1.0f + _color.z); }); } if (isIOR) { // Transform into F0 source.ReadWritePixels((uint _X, uint _Y, ref float4 _color) => { if (float.IsNaN(_color.x)) { _color.x = 1.2f; } if (float.IsNaN(_color.y)) { _color.y = 1.2f; } if (float.IsNaN(_color.z)) { _color.z = 1.2f; } _color.x = (_color.x - 1.0f) / (_color.x + 1.0f); // We apply the square below, during the sRGB conversion _color.y = (_color.y - 1.0f) / (_color.y + 1.0f); _color.z = (_color.z - 1.0f) / (_color.z + 1.0f); _color.x = Mathf.Pow(Mathf.Max(0.0f, _color.x), 2.0f / 2.2f); // <= Notice the 2/2.2 here! _color.y = Mathf.Pow(Mathf.Max(0.0f, _color.y), 2.0f / 2.2f); _color.z = Mathf.Pow(Mathf.Max(0.0f, _color.z), 2.0f / 2.2f); }); sRGB = true; // Also encoded as sRGB now } if (isAngle) { // Renormalize source.ReadWritePixels((uint _X, uint _Y, ref float4 _color) => { _color.x = 0.5f * (1.0f + _color.x * Mathf.INVPI); _color.y = 0.5f * (1.0f + _color.y * Mathf.INVPI); _color.z = 0.5f * (1.0f + _color.z * Mathf.INVPI); }); } ImageUtility.ImageFile temp = new ImageUtility.ImageFile(); // if ( texture.Name.ToLower() == "diffusecolor" ) // temp.ToneMapFrom( source, ( float3 _HDR, ref float3 _LDR ) => { _LDR =_HDR; } ); // 8-bits for diffuse otherwise unity doesn't like it... :'( // else temp.ConvertFrom(source, ImageUtility.PIXEL_FORMAT.RGBA16); System.IO.FileInfo targetMipTextureFileName = mipIndex > 0 ? new System.IO.FileInfo(System.IO.Path.Combine(fullTargetDirectory.FullName, texture.Name + "_mip" + mipIndex + ".png")) : targetTextureFileName; temp.Save(targetMipTextureFileName, ImageUtility.ImageFile.FILE_FORMAT.PNG); // System.IO.FileInfo targetMipTextureFileName = new System.IO.FileInfo( System.IO.Path.Combine( fullTargetDirectory.FullName, texture.Name + ".tif" ) ); // temp.Save( targetMipTextureFileName, ImageUtility.ImageFile.FILE_FORMAT.TIFF ); // Generate or read meta file string GUID = GenerateMeta(targetMipTextureFileName, checkBoxGenerateMeta.Checked, checkBoxOverwriteExistingMeta.Checked, sRGB, isNormalMap, isIOR, isArray); if (mipIndex == 0) { GUIDs[textureIndex] = GUID; allGUIDsValid &= GUID != null; } } //*/ } if (!checkBoxGenerateMat.Checked) { return; } if (!allGUIDsValid) { throw new Exception("Not all texture GUIDs are valid! Can't generate material file!"); } GenerateMaterial(_material, _targetDirectory, textureTypes, GUIDs); }
void BuildFont() { string charSet = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~éèêëôöàçÔÖÂÊÉœûüù"; m_fontRectangles = new Rectangle[charSet.Length]; for (int charIndex = 0; charIndex < charSet.Length; charIndex++) { char C = charSet[charIndex]; int index = (int)C; m_char2Index[index] = charIndex; } #if BUILD_FONTS using (Font F = new Font(this.Font.FontFamily, 36.0f)) { // Build small bitmap and write each character int width = 0; int maxheight = 0; using (Bitmap B = new Bitmap(70, 70, System.Drawing.Imaging.PixelFormat.Format32bppArgb)) { using (Graphics G = Graphics.FromImage(B)) { for (int i = 0; i < charSet.Length; i++) { string s = charSet.Substring(i, 1); // G.FillRectangle( Brushes.Black, 0, 0, B.Width, B.Height ); // G.DrawString( s, F, Brushes.White, new PointF( 0, 0 ) ); SizeF tempSize = G.MeasureString(s, F); m_fontRectangles[i] = new Rectangle(width, 0, (int)Mathf.Ceiling(tempSize.Width), (int)Mathf.Ceiling(tempSize.Height)); if (m_fontRectangles[i].Width > B.Width || m_fontRectangles[i].Height > B.Height) { throw new Exception("Fonts are too big, expand bitmap size or reduce font size!"); } width += m_fontRectangles[i].Width; maxheight = Math.Max(maxheight, m_fontRectangles[i].Height); } } } // Build the final bitmap using (Bitmap B = new Bitmap(width, maxheight, System.Drawing.Imaging.PixelFormat.Format32bppArgb)) { using (Graphics G = Graphics.FromImage(B)) { G.FillRectangle(Brushes.Black, 0, 0, B.Width, B.Height); for (int i = 0; i < charSet.Length; i++) { string s = charSet.Substring(i, 1); G.DrawString(s, F, Brushes.White, new PointF(m_fontRectangles[i].X, m_fontRectangles[i].Y)); } using (ImageUtility.ImageFile file = new ImageUtility.ImageFile(B, new ImageUtility.ColorProfile(ImageUtility.ColorProfile.STANDARD_PROFILE.sRGB))) { file.Save(new FileInfo("Atlas.png"), ImageUtility.ImageFile.FILE_FORMAT.PNG); } } } } // Write char sizes using (FileStream S = new FileInfo("Atlas.rect").Create()) using (BinaryWriter W = new BinaryWriter(S)) { for (int i = 0; i < m_fontRectangles.Length; i++) { W.Write(m_fontRectangles[i].X); W.Write(m_fontRectangles[i].Y); W.Write(m_fontRectangles[i].Width); W.Write(m_fontRectangles[i].Height); } } #endif // Load atlas & rectangles using (ImageUtility.ImageFile file = new ImageUtility.ImageFile(new FileInfo("Atlas.png"))) { ImageUtility.ImageFile file2 = new ImageUtility.ImageFile(file, ImageUtility.PIXEL_FORMAT.RGBA8); using (ImageUtility.ImagesMatrix M = new ImageUtility.ImagesMatrix(file2, ImageUtility.ImagesMatrix.IMAGE_TYPE.sRGB)) { m_tex_FontAtlas = new Texture2D(m_device, M, ImageUtility.COMPONENT_FORMAT.UNORM_sRGB); } } using (FileStream S = new FileInfo("Atlas.rect").OpenRead()) using (BinaryReader R = new BinaryReader(S)) { // Read both CPU and GPU versions float recW = 1.0f / m_tex_FontAtlas.Width; float recH = 1.0f / m_tex_FontAtlas.Height; using (PixelsBuffer content = new PixelsBuffer((uint)(16 * m_fontRectangles.Length))) { using (BinaryWriter W = content.OpenStreamWrite()) { for (int i = 0; i < m_fontRectangles.Length; i++) { m_fontRectangles[i].X = R.ReadInt32(); m_fontRectangles[i].Y = R.ReadInt32(); m_fontRectangles[i].Width = R.ReadInt32(); m_fontRectangles[i].Height = R.ReadInt32(); W.Write(recW * (float)m_fontRectangles[i].X); W.Write(recH * (float)m_fontRectangles[i].Y); W.Write(recW * (float)m_fontRectangles[i].Width); W.Write(recH * (float)m_fontRectangles[i].Height); } } m_tex_FontRectangle = new Texture2D(m_device, (uint)m_fontRectangles.Length, 1, 1, 1, ImageUtility.PIXEL_FORMAT.RGBA32F, ImageUtility.COMPONENT_FORMAT.AUTO, false, false, new PixelsBuffer[] { content }); } } }
private void MixResults( float3 _MixColor ) { if ( m_TextureTargets[0][0] == null ) return; // Nothing to mix yet... if ( !m_CS_Helper_Mix.Use() ) throw new Exception( "Can't mix translucency maps as mixer compute shader failed to compile!" ); ////////////////////////////////////////////////////////////////////////// // 1] Combine m_CB_Helper.m._Width = (uint) W; m_CB_Helper.m._Height = (uint) H; m_CB_Helper.m._Parms = _MixColor; m_CB_Helper.UpdateData(); m_TextureTargets[0][0].SetCS( 0 ); m_TextureTargets[1][0].SetCS( 1 ); m_TextureTargets[2][0].SetCS( 2 ); m_TextureTargetCombined.RemoveFromLastAssignedSlots(); m_TextureTargetCombined.SetCSUAV( 0 ); uint groupsCountX = (W + 15) >> 4; uint groupsCountY = (H + 15) >> 4; m_CS_Helper_Mix.Dispatch( groupsCountX, groupsCountY, 1 ); m_TextureTargetCombined.RemoveFromLastAssignedSlotUAV(); // So we can use it as input for next stage ////////////////////////////////////////////////////////////////////////// // 2] Copy target to staging for CPU readback and update the resulting bitmaps if ( m_imageResultCombined != null ) m_imageResultCombined.Dispose(); m_imageResultCombined = new ImageUtility.ImageFile( W, H, ImageUtility.ImageFile.PIXEL_FORMAT.RGBA8, m_sRGBProfile ); // Copy from GPU to CPU m_TextureTarget_CPU.CopyFrom( m_TextureTargetCombined ); PixelsBuffer Pixels = m_TextureTarget_CPU.Map( 0, 0 ); float4[] scanline = new float4[W]; float4 gammaRGB = float4.Zero; 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_imageResultCombined.WriteScanline( Y, scanline ); } Pixels.Dispose(); m_TextureTarget_CPU.UnMap( 0, 0 ); // Assign result imagePanelResult3.Image = m_imageResultCombined; }