static void SaveTestsRGB() { ImageUtility.ColorProfile Profile_sRGB = new ImageUtility.ColorProfile(ImageUtility.ColorProfile.STANDARD_PROFILE.sRGB); ImageUtility.ColorProfile Profile_Linear = new ImageUtility.ColorProfile(ImageUtility.ColorProfile.Chromaticities.sRGB, ImageUtility.ColorProfile.GAMMA_CURVE.STANDARD, 1.0f); ImageUtility.Bitmap Gray_sRGB = new ImageUtility.Bitmap(64, 64, Profile_sRGB); ImageUtility.Bitmap Gray_Linear = new ImageUtility.Bitmap(64, 64, Profile_Linear); ImageUtility.Bitmap Gradient_sRGB = new ImageUtility.Bitmap(128, 16, Profile_sRGB); ImageUtility.Bitmap Gradient_Linear = new ImageUtility.Bitmap(128, 16, Profile_Linear); for (int Y = 0; Y < Gray_sRGB.Height; Y++) { for (int X = 0; X < Gray_sRGB.Width; X++) { Gray_sRGB.ContentXYZ[X, Y] = Profile_Linear.RGB2XYZ(new ImageUtility.float4(0.5f, 0.5f, 0.5f, 1.0f)); Gray_Linear.ContentXYZ[X, Y] = Profile_Linear.RGB2XYZ(new ImageUtility.float4(0.5f, 0.5f, 0.5f, 1.0f)); } } int W = Gradient_sRGB.Width; for (int Y = 0; Y < Gradient_sRGB.Height; Y++) { for (int X = 0; X < Gradient_sRGB.Width; X++) { float C = (float)(X + 0.5f) / W; Gradient_sRGB.ContentXYZ[X, Y] = Profile_Linear.RGB2XYZ(new ImageUtility.float4(C, C, C, 1.0f)); Gradient_Linear.ContentXYZ[X, Y] = Profile_Linear.RGB2XYZ(new ImageUtility.float4(C, C, C, 1.0f)); } } Gray_sRGB.Save(new FileInfo("./Gray128_sRGB.png")); Gray_Linear.Save(new FileInfo("./Gray128_Linear.png")); Gradient_sRGB.Save(new FileInfo("./Gradient_sRGB.png")); Gradient_Linear.Save(new FileInfo("./Gradient_Linear.png")); }
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_TextureSource, 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); if (m_BitmapResult != null) { m_BitmapResult.Dispose(); } m_BitmapResult = null; m_BitmapResult = new ImageUtility.Bitmap(W, H, m_ProfileLinear); m_BitmapResult.HasAlpha = true; RendererManaged.PixelsBuffer Pixels = m_TextureTarget_CPU.Map(0, 0); using (System.IO.BinaryReader R = Pixels.OpenStreamRead()) for (int Y = 0; Y < H; Y++) { R.BaseStream.Position = Y * Pixels.RowPitch; for (int X = 0; X < W; X++) { float AO = R.ReadSingle(); ImageUtility.float4 Color = new ImageUtility.float4(AO, AO, AO, AO); Color = m_ProfileLinear.RGB2XYZ(Color); m_BitmapResult.ContentXYZ[X, Y] = Color; } } Pixels.Dispose(); m_TextureTarget_CPU.UnMap(0, 0); // Assign result viewportPanelResult.Image = m_BitmapResult; } catch (Exception _e) { MessageBox("An error occurred during generation!\r\n\r\nDetails: ", _e); } finally { panelParameters.Enabled = true; } }
/// <summary> /// Converts a 0xRRGGBB string into /// </summary> /// <param name="_hexRGB"></param> /// <returns></returns> public static float3 HexRGB2xyY(string _hexRGB) { if (_hexRGB.StartsWith("0x")) { _hexRGB = _hexRGB.Remove(0, 2); } uint V = uint.Parse(_hexRGB, System.Globalization.NumberStyles.HexNumber); byte R = (byte)(V >> 16); byte G = (byte)((V >> 8) & 0xFF); byte B = (byte)(V & 0xFF); float4 RGBA = new float4(R / 255.0f, G / 255.0f, B / 255.0f, 1.0f); float4 XYZ = new float4(); ms_profile.RGB2XYZ(RGBA, ref XYZ); float3 xyY = new float3(); ImageUtility.ColorProfile.XYZ2xyY(XYZ.xyz, ref xyY); return(xyY); }
private void Generate() { try { tabControlGenerators.Enabled = false; ////////////////////////////////////////////////////////////////////////// // 1] Apply bilateral filtering to the input texture as a pre-process ApplyBilateralFiltering(m_TextureSource, 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!"); } int h = Math.Max(1, MAX_LINES * 1024 / W); int CallsCount = (int)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_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_BitmapResult != null) { m_BitmapResult.Dispose(); } m_BitmapResult = null; m_BitmapResult = new ImageUtility.Bitmap(W, H, m_LinearProfile); m_BitmapResult.HasAlpha = true; RendererManaged.PixelsBuffer Pixels = m_TextureTarget_CPU.Map(0, 0); using (System.IO.BinaryReader R = Pixels.OpenStreamRead()) for (int Y = 0; Y < H; Y++) { R.BaseStream.Position = Y * Pixels.RowPitch; for (int X = 0; X < W; X++) { ImageUtility.float4 Color = new ImageUtility.float4(R.ReadSingle(), R.ReadSingle(), R.ReadSingle(), R.ReadSingle()); Color = m_LinearProfile.RGB2XYZ(Color); m_BitmapResult.ContentXYZ[X, Y] = Color; } } Pixels.Dispose(); m_TextureTarget_CPU.UnMap(0, 0); // Assign result viewportPanelResult.Image = m_BitmapResult; } catch (Exception _e) { MessageBox("An error occurred during generation!\r\n\r\nDetails: ", _e); } finally { tabControlGenerators.Enabled = true; } }
void TestChromaRanges() { ImageUtility.ColorProfile profile = new ImageUtility.ColorProfile(ImageUtility.ColorProfile.STANDARD_PROFILE.sRGB); float3 tempFloat3 = new float3(0, 0, 0); float4 tempFloat4 = new float4(0, 0, 0, 1); float Ygo, Cg, Co; ranges_t[] ranges = new ranges_t[4]; for (int lumaIndex = 0; lumaIndex < ranges.Length; lumaIndex++) { ranges_t range = new ranges_t(); ranges[lumaIndex] = range; float L = (1 + lumaIndex) / 255.0f; for (int R = 0; R < 256; R++) { for (int G = 0; G < 256; G++) { for (int B = 0; B < 256; B++) { tempFloat4.x = L * R; tempFloat4.y = L * G; tempFloat4.z = L * B; // Convert to YCoCg // Ygo = 0.25f * tempFloat4.x + 0.5f * tempFloat4.y + 0.25f * tempFloat4.z; // Cg = -0.25f * tempFloat4.x + 0.5f * tempFloat4.y - 0.25f * tempFloat4.z; // Co = 0.50f * tempFloat4.x + 0.0f * tempFloat4.y - 0.50f * tempFloat4.z; RGB2YCoCg(tempFloat4.x, tempFloat4.y, tempFloat4.z, out Ygo, out Co, out Cg); YCoCg2RGB(Ygo, Co, Cg, out tempFloat3.x, out tempFloat3.y, out tempFloat3.z); if (Math.Abs(tempFloat3.x - tempFloat4.x) > 1e-6) { throw new Exception("RHA!"); } if (Math.Abs(tempFloat3.y - tempFloat4.y) > 1e-6) { throw new Exception("RHA!"); } if (Math.Abs(tempFloat3.z - tempFloat4.z) > 1e-6) { throw new Exception("RHA!"); } // Convert to xyY float4 XYZ = float4.Zero; profile.RGB2XYZ(tempFloat4, ref XYZ); tempFloat3.x = XYZ.x; tempFloat3.y = XYZ.y; tempFloat3.z = XYZ.z; float3 xyY = float3.Zero; ImageUtility.ColorProfile.XYZ2xyY(tempFloat3, ref xyY); // Update ranges range.Ygo_min = Math.Min(range.Ygo_min, Ygo); range.Ygo_max = Math.Max(range.Ygo_max, Ygo); range.Cg_min = Math.Min(range.Cg_min, Cg); range.Cg_max = Math.Max(range.Cg_max, Cg); range.Co_min = Math.Min(range.Co_min, Co); range.Co_max = Math.Max(range.Co_max, Co); range.Y_min = Math.Min(range.Y_min, xyY.z); range.Y_max = Math.Max(range.Y_max, xyY.z); range.x_min = Math.Min(range.x_min, xyY.x); range.x_max = Math.Max(range.x_max, xyY.x); range.y_min = Math.Min(range.y_min, xyY.y); range.y_max = Math.Max(range.y_max, xyY.y); } } } } }
static void SaveTestsRGB() { ImageUtility.ColorProfile Profile_sRGB = new ImageUtility.ColorProfile( ImageUtility.ColorProfile.STANDARD_PROFILE.sRGB ); ImageUtility.ColorProfile Profile_Linear = new ImageUtility.ColorProfile( ImageUtility.ColorProfile.Chromaticities.sRGB, ImageUtility.ColorProfile.GAMMA_CURVE.STANDARD, 1.0f ); ImageUtility.Bitmap Gray_sRGB = new ImageUtility.Bitmap( 64, 64, Profile_sRGB ); ImageUtility.Bitmap Gray_Linear = new ImageUtility.Bitmap( 64, 64, Profile_Linear ); ImageUtility.Bitmap Gradient_sRGB = new ImageUtility.Bitmap( 128, 16, Profile_sRGB ); ImageUtility.Bitmap Gradient_Linear = new ImageUtility.Bitmap( 128, 16, Profile_Linear ); for ( int Y=0; Y < Gray_sRGB.Height; Y++ ) for ( int X=0; X < Gray_sRGB.Width; X++ ) { Gray_sRGB.ContentXYZ[X,Y] = Profile_Linear.RGB2XYZ( new ImageUtility.float4( 0.5f, 0.5f, 0.5f, 1.0f ) ); Gray_Linear.ContentXYZ[X,Y] = Profile_Linear.RGB2XYZ( new ImageUtility.float4( 0.5f, 0.5f, 0.5f, 1.0f ) ); } int W = Gradient_sRGB.Width; for ( int Y=0; Y < Gradient_sRGB.Height; Y++ ) for ( int X=0; X < Gradient_sRGB.Width; X++ ) { float C = (float) (X+0.5f) / W; Gradient_sRGB.ContentXYZ[X,Y] = Profile_Linear.RGB2XYZ( new ImageUtility.float4( C, C, C, 1.0f ) ); Gradient_Linear.ContentXYZ[X,Y] = Profile_Linear.RGB2XYZ( new ImageUtility.float4( C, C, C, 1.0f ) ); } Gray_sRGB.Save( new FileInfo( "./Gray128_sRGB.png" ) ); Gray_Linear.Save( new FileInfo( "./Gray128_Linear.png" ) ); Gradient_sRGB.Save( new FileInfo( "./Gradient_sRGB.png" ) ); Gradient_Linear.Save( new FileInfo( "./Gradient_Linear.png" ) ); }
void TestChromaRanges() { ImageUtility.ColorProfile profile = new ImageUtility.ColorProfile(ImageUtility.ColorProfile.STANDARD_PROFILE.sRGB ); ImageUtility.float3 tempFloat3 = new ImageUtility.float3( 0, 0, 0 ); ImageUtility.float4 tempFloat4 = new ImageUtility.float4( 0, 0, 0, 1 ); float Ygo, Cg, Co; ranges_t[] ranges = new ranges_t[4]; for ( int lumaIndex=0; lumaIndex < ranges.Length; lumaIndex++ ) { ranges_t range = new ranges_t(); ranges[lumaIndex] = range; float L = (1+lumaIndex) / 255.0f; for ( int R=0; R < 256; R++ ) { for ( int G=0; G < 256; G++ ) { for ( int B=0; B < 256; B++ ) { tempFloat4.x = L * R; tempFloat4.y = L * G; tempFloat4.z = L * B; // Convert to YCoCg // Ygo = 0.25f * tempFloat4.x + 0.5f * tempFloat4.y + 0.25f * tempFloat4.z; // Cg = -0.25f * tempFloat4.x + 0.5f * tempFloat4.y - 0.25f * tempFloat4.z; // Co = 0.50f * tempFloat4.x + 0.0f * tempFloat4.y - 0.50f * tempFloat4.z; RGB2YCoCg( tempFloat4.x, tempFloat4.y, tempFloat4.z, out Ygo, out Co, out Cg ); YCoCg2RGB( Ygo, Co, Cg, out tempFloat3.x, out tempFloat3.y, out tempFloat3.z ); if ( Math.Abs( tempFloat3.x - tempFloat4.x ) > 1e-6 ) throw new Exception( "RHA!" ); if ( Math.Abs( tempFloat3.y - tempFloat4.y ) > 1e-6 ) throw new Exception( "RHA!" ); if ( Math.Abs( tempFloat3.z - tempFloat4.z ) > 1e-6 ) throw new Exception( "RHA!" ); // Convert to xyY ImageUtility.float4 XYZ = profile.RGB2XYZ( tempFloat4 ); tempFloat3.x = XYZ.x; tempFloat3.y = XYZ.y; tempFloat3.z = XYZ.z; ImageUtility.float3 xyY = ImageUtility.ColorProfile.XYZ2xyY( tempFloat3 ); // Update ranges range.Ygo_min = Math.Min( range.Ygo_min, Ygo ); range.Ygo_max = Math.Max( range.Ygo_max, Ygo ); range.Cg_min = Math.Min( range.Cg_min, Cg ); range.Cg_max = Math.Max( range.Cg_max, Cg ); range.Co_min = Math.Min( range.Co_min, Co ); range.Co_max = Math.Max( range.Co_max, Co ); range.Y_min = Math.Min( range.Y_min, xyY.z ); range.Y_max = Math.Max( range.Y_max, xyY.z ); range.x_min = Math.Min( range.x_min, xyY.x ); range.x_max = Math.Max( range.x_max, xyY.x ); range.y_min = Math.Min( range.y_min, xyY.y ); range.y_max = Math.Max( range.y_max, xyY.y ); } } } } }