Search Unity

Making a Colour Picker

Discussion in 'Scripting' started by AlucardJay, Jul 17, 2013.

  1. AlucardJay

    AlucardJay

    Joined:
    May 28, 2012
    Posts:
    328
    I am making the elements of the colour picker as vertex coloured procedural meshes. : http://answers.unity3d.com/questions/494329/vertex-colours-not-blending-across-triangle-face.html

    $13194-vertcoloursnotblending.jpg

    But now after searching, there doesn't seem to be a way of reading the colour of a pixel at the mouse position on the screen, just how to read the colour from a pixel in a texture.

    Is there a way to get the colour on the screen at the mouse position? The only way I can see to go forward now is to generate a 2D texture with what the camera can see, and go from there, but I really don't want to do that (generating a new texture every time the main colour wheel gets changed)
     
  2. Patico

    Patico

    Joined:
    May 21, 2013
    Posts:
    886
    I think, you can use Physics.Raycast to detect mouse click on the object and use hitpoint to get a texture color....
     
  3. AlucardJay

    AlucardJay

    Joined:
    May 28, 2012
    Posts:
    328
    My problem is currently there is no texture, just a material with a vertex colour shader. The colours are set on the vertices of the mesh. To use GetColor I would have to generate a texture. Is it possible to read the colour of a pixel on the screen?
     
  4. BPPHarv

    BPPHarv

    Joined:
    Jun 9, 2012
    Posts:
    318
    I'm quite curious about this as well. I assume you're talking about using RaycastHit.textureCoord to do a GetPixels on the base texture? Would GetPixels return a valid color result if his vertex colored mesh didn't actually have a texture?

    All I could think of were render textures or Lerping between the vert color values for the triangle referenced using the RaycastHit.triangleIndex but didn't think I knew enough about the required calculation to offer any solid advice.
     
    Last edited: Jul 17, 2013
  5. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    Do it in maths
    You can use EditorGUIUtility.HSVToRGB to get hsv into rgb during edit mode

     
  6. BPPHarv

    BPPHarv

    Joined:
    Jun 9, 2012
    Posts:
    318
    See, now that's handy!
     
  7. Cascho01

    Cascho01

    Joined:
    Mar 19, 2010
    Posts:
    1,347
    I once had developed a photoshop-like colorpicker.
    The rainbow on the left is a texture painted in Photoshop.
    The squared field is a very accurate texture calculated on the fly with a nested for-loop.
    Physics.Raycast to get the color:

    $Colorpicker.jpg

    Maybe I can put it into the store.
     
    Last edited: Jul 17, 2013
  8. AlucardJay

    AlucardJay

    Joined:
    May 28, 2012
    Posts:
    328
  9. hawx

    hawx

    Joined:
    Sep 29, 2012
    Posts:
    95
    Pretty neat colour picker!
     
  10. AlucardJay

    AlucardJay

    Joined:
    May 28, 2012
    Posts:
    328
    Thanks, I'm happy the result exceeded the concept too! I only just fixed the shader and vert winding on the quad, hope you saw that build. I'm still thinking adding more verts to the square to give the colours a smoother transition across the Quad.

    I liked hpjohns answer so much I rewrote the colour assignment on the ring, so the whole thing is numbers (yay for math!), no texture or GetPixel used =]
     
  11. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    Lookin good, but whats in the top right box doesn't quite appear to be the same shade as selected in all cases, try a dark blue, middle of the box
     
  12. hawx

    hawx

    Joined:
    Sep 29, 2012
    Posts:
    95
    I'm interested to know what the code behind this looks like .I'm not a very skilled programmer but I'm learning, would you be able to post a snippet of your code?
     
  13. AlucardJay

    AlucardJay

    Joined:
    May 28, 2012
    Posts:
    328
    hpjohn : yes, I had a problem with the colours not blending evenly across a quad. When I changed it to a plane the colour blend seems a lot better.

    Here is the new plane build : http://www.alucardj.net16.net/unityquestions2013/ColourPickerPlane.html

    Using a Quad :

    $13239-vertcoloursnotblending3.jpg

    Using a plane :

    $13244-vertcoloursnotblending4.jpg

    this is the question I asked on UA about the vertex colours not being blended evenly across the face of the triangle : http://answers.unity3d.com/questions/494329/vertex-colours-not-blending-across-triangle-face.html

    hawx : I'm really not sure what you are interested in the most to give more detail.

    The biggest part of this is the 'Colour Calculator', a helper script that converts colours between RGB and HSV values.

    Once that was made, everything could work from the H value of the colour. The directional vector from the center of the ring to the pointer as an angle using Quaternion.FromToRotation. (please note all this script was just for testing, I positioned everything at zero and used screen center. In practice, these would be local positions relative to the objects).

    Code (csharp):
    1.  
    2. function GetH()
    3. {
    4.     if ( Input.GetMouseButtonDown(0) )
    5.     {
    6.        
    7.     }
    8.     else if ( Input.GetMouseButton(0) )
    9.     {
    10.         mousePos = Input.mousePosition;
    11.        
    12.         var halfWidth : float = Screen.width * 0.5;
    13.         var halfHeight : float = Screen.height * 0.5;
    14.        
    15.         // get the directional vector of the mouse to the screen center
    16.         //var dir : Vector3 = mousePos - Vector3( halfWidth, halfHeight, 0 );
    17.         var dir : Vector3 = Vector3( mousePos.x, mousePos.y, 0 ) - Vector3( halfWidth, halfHeight, 0 ); // for inverting screen Y if needed
    18.        
    19.         // calculate a rotation for H based on the current mousePosition and up from the center of the screen
    20.         var rot : Quaternion = Quaternion.FromToRotation( Vector3.up, dir.normalized );
    21.        
    22.         Debug.Log( rot.eulerAngles.z );
    23.         //svPointer.renderer.material.color = colourCalc.HSVtoRGB( rot.eulerAngles.z, 1, 1 );
    24.        
    25.         // get a value for H betweeen 0 and 360
    26.         hAngle = rot.eulerAngles.z;
    27.        
    28.         // call function on shade object to change colour
    29.         // convert and return a RGB colour from HSV values
    30.         //hColour = colourCalc.HSVtoRGB( hAngle, 1, 1 ); // S = 1 (no white); V = 1 (no black);
    31.         //colourPickerShade.SetColour( hColour ); // using colour
    32.         // or just use the H value
    33.         colourPickerShade.SetColour( hAngle ); // using H value
    34.        
    35.         // set pointer position
    36.         hPointer.position = dir.normalized * 4.5;
    37.     }
    38.     else if ( Input.GetMouseButtonUp(0) )
    39.     {
    40.         myState = PickerState.Idle;
    41.     }
    42. }
    43.  
    ... and to set the shade. ( Again, some really bad hard-coded numbers. These are just because I knew my object was 5x5 with center 2.5x2.5 )

    Code (csharp):
    1.  
    2. function SetMaterialColour()
    3. {
    4.     s = ( svPointer.position.x + 2.5 ) / 5.0; // get a value for S betweeen 0 and 1
    5.     v = ( svPointer.position.y + 2.5 ) / 5.0; // get a value for V betweeen 0 and 1
    6.     colourOutputObject.material.color = colourCalc.HSVtoRGB( hAngle, s, v ); // convert to RGB colour, and apply to colourOutputObject
    7. }
    8.  
    ... and here is the colour calculator. It is just my translation from this link : http://www.cs.rit.edu/~ncs/color/t_convert.html
    Once I realized the star variables were the returned values, it all fell into place ! This should probably be a static class or something that can be universally readable.

    Code (csharp):
    1.  
    2. //------------------------------//
    3. //  ColourCalculator.js         //
    4. //  Written by Alucard Jay      //
    5. //  7/17/2013                   //
    6. //------------------------------//
    7. //  source :
    8. //  http://www.cs.rit.edu/~ncs/color/t_convert.html
    9. /*
    10. RGB to HSV  HSV to RGB
    11.  
    12. The Hue/Saturation/Value model was created by A. R. Smith in 1978.
    13. It is based on such intuitive color characteristics as tint, shade and tone (or family, purety and intensity).
    14. The coordinate system is cylindrical, and the colors are defined inside a hexcone.
    15. The hue value H runs from 0 to 360º.
    16. The saturation S is the degree of strength or purity and is from 0 to 1.
    17. Purity is how much white is added to the color, so S=1 makes the purest color (no white).
    18. Brightness V also ranges from 0 to 1, where 0 is the black.
    19. */
    20. // ----
    21.  
    22. #pragma strict
    23.  
    24.  
    25. // ----
    26.  
    27.  
    28. function HSVtoRGB( h : float, s : float, v : float ) : Color
    29. {
    30.     var calcColour : Color = new Color( 1, 1, 1, 1 );
    31.    
    32.     var i : int = 0;
    33.    
    34.     var f : float = 0.0;
    35.     var p : float = 0.0;
    36.     var q : float = 0.0;
    37.     var t : float = 0.0;
    38.    
    39.     // achromatic (grey)
    40.     if ( s == 0 )
    41.     {
    42.         calcColour.r = v;
    43.         calcColour.g = v;
    44.         calcColour.b = v;
    45.        
    46.         return calcColour;
    47.     }
    48.    
    49.     //
    50.     h /= 60.0;
    51.     i = Mathf.FloorToInt( h );
    52.     f = h - i;
    53.     p = v * ( 1.0 - s );
    54.     q = v * ( 1.0 - ( s * f ) );
    55.     t = v * ( 1.0 - ( s * ( 1.0 - f ) ) );
    56.  
    57.     //
    58.     switch( i )
    59.     {
    60.         case 0 :
    61.             calcColour.r = v;
    62.             calcColour.g = t;
    63.             calcColour.b = p;
    64.         break;
    65.        
    66.         case 1 :
    67.             calcColour.r = q;
    68.             calcColour.g = v;
    69.             calcColour.b = p;
    70.         break;
    71.        
    72.         case 2 :
    73.             calcColour.r = p;
    74.             calcColour.g = v;
    75.             calcColour.b = t;
    76.         break;
    77.        
    78.         case 3 :
    79.             calcColour.r = p;
    80.             calcColour.g = q;
    81.             calcColour.b = v;
    82.         break;
    83.        
    84.         case 4 :
    85.             calcColour.r = t;
    86.             calcColour.g = p;
    87.             calcColour.b = v;
    88.         break;
    89.        
    90.         default :
    91.             calcColour.r = v;
    92.             calcColour.g = p;
    93.             calcColour.b = q;
    94.         break;
    95.     }
    96.    
    97.     //
    98.     return calcColour;
    99. }
    100.  
    101.  
    102. // ----
    103.  
    104.  
    105. function RGBtoHSV( r : float, g : float, b : float ) : Vector3
    106. {
    107.     var calcColour : Vector3 = new Vector3( 0, 1, 0 ); // H, S, V
    108.    
    109.     var min : float = 0.0;
    110.     var max : float = 0.0;
    111.     var delta : float = 0.0;
    112.    
    113.     //
    114.     min = Mathf.Min( r, g, b );
    115.     max = Mathf.Max( r, g, b );
    116.     calcColour.z = max; // V
    117.    
    118.     delta = max - min;
    119.    
    120.     if ( max != 0 )
    121.     {
    122.         calcColour.y = delta / max; // S
    123.     }
    124.     else
    125.     {
    126.         // r = g = b = 0
    127.         calcColour.y = 0; // S
    128.         calcColour.x = -1; // H
    129.        
    130.         return calcColour;
    131.     }
    132.    
    133.     //
    134.     if ( r == max )
    135.     {
    136.         calcColour.x = ( g - b ) / delta; // H
    137.     }
    138.     else if ( g == max )
    139.     {
    140.         calcColour.x = 2.0 + ( ( b - r ) / delta ); // H
    141.     }
    142.     else
    143.     {
    144.         calcColour.x = 4.0 + ( ( r - g ) / delta ); // H
    145.     }
    146.    
    147.     //
    148.     calcColour.x *= 60.0; // H
    149.    
    150.     if ( calcColour.x < 0 )
    151.     {
    152.         calcColour.x += 360.0;
    153.     }
    154.    
    155.    
    156.     //
    157.     return calcColour;
    158. }
    159.  
    160.  
    161. // ----
    162.  
    163.  
    164. function RGBtoHSV( theColour : Color ) : Vector3
    165. {
    166.     var r : float = theColour.r;
    167.     var g : float = theColour.g;
    168.     var b : float = theColour.b;
    169.    
    170.     var calcColour : Vector3 = new Vector3( 0, 1, 0 ); // H, S, V
    171.    
    172.     var min : float = 0.0;
    173.     var max : float = 0.0;
    174.     var delta : float = 0.0;
    175.    
    176.     //
    177.     min = Mathf.Min( r, g, b );
    178.     max = Mathf.Max( r, g, b );
    179.     calcColour.z = max; // V
    180.    
    181.     delta = max - min;
    182.    
    183.     if ( max != 0 )
    184.     {
    185.         calcColour.y = delta / max; // S
    186.     }
    187.     else
    188.     {
    189.         // r = g = b = 0
    190.         calcColour.y = 0; // S
    191.         calcColour.x = -1; // H
    192.        
    193.         return calcColour;
    194.     }
    195.    
    196.     //
    197.     if ( r == max )
    198.     {
    199.         calcColour.x = ( g - b ) / delta; // H
    200.     }
    201.     else if ( g == max )
    202.     {
    203.         calcColour.x = 2.0 + ( ( b - r ) / delta ); // H
    204.     }
    205.     else
    206.     {
    207.         calcColour.x = 4.0 + ( ( r - g ) / delta ); // H
    208.     }
    209.    
    210.     //
    211.     calcColour.x *= 60.0; // H
    212.    
    213.     if ( calcColour.x < 0 )
    214.     {
    215.         calcColour.x += 360.0;
    216.     }
    217.    
    218.    
    219.     //
    220.     return calcColour;
    221. }
    222.  
    223.  
    224. // ----
    225.  
    226.  
     
    Last edited: Jul 18, 2013
  14. hawx

    hawx

    Joined:
    Sep 29, 2012
    Posts:
    95
    Thanks alucardj , just wanted to know how it worked. :)
     
  15. dorpeleg

    dorpeleg

    Joined:
    Aug 20, 2011
    Posts:
    250
    Wow, would love to see a package for easy importing :)

    btw, alucardj I sent you a pm on a different matter which I hope you can help me with, thanks!