HSL/RGB conversion
I'm looking to convert between HSL and RGB, 3 floats in the range 0.,1. This is going to be inside a patcher which I am going to have multiple copies of using [poly~], so I'd like to keep it as tight as possible.
I was a bit surprised that I couldn't find a built-in object to do this, but it seems like I have a few options:
1. Implement using [expr] and consume via [bpatcher]. Optionally use a [swatch] to do HSL to RGB and get the saturation from RGB.
2. Implement in Javascript in a [js] object
3. Convert to a 1x1x3 matrix and use [jit.rgb2hsl] / [jit.hsl2rgb]
#1 seems easiest, but I have a feeling #3 is more efficient. #2 just seems like a bad idea, if there are going to be a few dozen copies of it. (I'm still on Max 5 and the old JS for now.)
Thoughts?
I've been using a Jasch object, hsv2rgb to do this. Works fine for me, but I came upon your post because I was looking to see if there's a way to do it without the external. I was doing the conversion with swatch before, but it was slower - I presume because it has to update the swatch GUI interface.
Thinking about this a bit over the last couple of days, I landed on moving this to a color manager object and taking the logic out of the poly~'ed object entirely (that one would only field (color $1 $2 $3 $4) as a property message and passes it on to its jit.gl.mesh). In the color manager I will probably use approach #3. I'll post it when it's done.
I know this thread is old - I remember seeing it back when I was looking for a solution. So for anyone searching for a list/float version of RGB to HSL and/or HSL to RGB, here are some patches I built. They may not be pretty, but they are accurate.
The only standard objects in Max that output accurate values for HSL are the Gen objects - even if they are erroneously referred to as "hue, saturation and luminance" conversions. They are lightness, not luminance, but they are precise.
The Jitter objects [jit.hsl2rgb] and [jit.rgb2hsl] use char data (0-255) to handle degrees (0-360).. resulting in less than precise output. iirc, the same is true for [jit.colorspace]. If you need accurate Jitter, gen or gl.gen versions, let me know.
I've also written shaders that translate from RBG->HSL and HSL->RGB, as well as many other colorspaces. You can download them here:
@ Jesse, I am currently working on a pixel sonification project. Looking to convert RGB - HSL, may I ask.... How do you use those jxs files in max?
You can use them in a jit.gl.slab object via the @file attribute.
hi jesse,
this is probably a really beginner question, but i'm stumped. so, see the attached patcher below. jg.RGB2HSV.jxs seems to work fine, and now i want to iterate through each pixel, doing some examination and computation on each HSV pixel value.
however, when i just put the output of jit.gl.slab into jit.matrix, then iterate, i seem to get a bunch of byte values. i was expecting 3 floats. so this has me worried that i'm doing something wrong. could you either explain how to properly iterate over the output of your RGB2HSV converter, or perhaps post a small patch doing just that?
thanks. this is probably just a more general question on how to properly examine individual elements that have been converted from texture to matrix world.
omar
The argument to jit.matrix needs to be float32, not float.
thank you for looking! so minor, and made all the difference.
omar
@metamax Thanks for sharing the list/float conversion patches. Big time saver for me.
@meeble There are hsl2rgb objects in jit.gen and jit.pix.
@metamax thanks for your conversion patches, which are pretty much just what I need for something. I'm having some issues with rgb2hsl though. I'm getting my rgb values from a swatch object, and looking for hue and lightness values scaled from 0. to 1. (don't need saturation). However, whilst I'm getting the hue values I expect, lightness values only go from 0.5 to 1. as I move the swatch 'puck' between the middle and top of the object. The range between the bottom and middle of the object is all at 0.5 - ie the values seem to be clipped (not scaled) between 0.5 and 1. I've experimented with the 2nd and 3d outlets of the abstraction, and these both give the same behaviour. Probably missing something simple, but any ideas?
EDIT - I'll answer my own question and leave it here in case it's useful for anyone. My issue was caused by the alpha channel - I just had to knock that out from the list coming from [swatch] to get the behaviour I expected.
In case anyone is interested, here is a gen version of rgb2hsl and hsl2rgb:
I made it to work with a normalized hue value only (between 0. and 1. instead of 0. to 360.)
It is about 2 times faster than the version posted above by METAMAX, and it seems to 100% match the hsl to rgb conversion happening in [swatch].