6
$\begingroup$

Currently looking at the blender API I haven't seen anything of all about the Hex input. This is frustrating me enough as it seems strange to me that there is no such input function (when Blender natively has it, where it is enough to simply copy and paste).

Now, the point of the situation is that all the scripts I tried, incorrectly convert Hex to RGB (Including some answers those present in other questions about blender.stackexchange).

Basically the conversion from Hex to RGB produces a Hex value different from the Input value, and this is not good, I need absolute precision on these Hex values

I see that it is gamma corrected, now, I don't know much about Hex, so I don't want to comment too much, but I just wish that what I get is the same thing I get by copying an Hex in the RGB node

The most beautiful thing would be to be able to directly input the Hex input value in the RGB node, that gives me exactly the result I want.

$\endgroup$
2
  • $\begingroup$ Possible duplicate of Properly convert Hex Color code to Blender RGB in python $\endgroup$ Nov 23, 2019 at 3:45
  • $\begingroup$ @RayMairlot Thanks but the answer to that page is wrong, please check the answer of that question as it is incorrect as it provides values different from those needed to get the correct rgb $\endgroup$
    – Noob Cat
    Nov 23, 2019 at 4:09

2 Answers 2

12
$\begingroup$

Hex values are interpreted in the sRGB color space, while Blender uses a linear RGB color space internally. The conversion functions can be found on the sRGB Wikipedia page. The hex channel values themselves (0-255) should be divided by 255 before application of the formulas. A pure Python implementation looks like this:

def srgb_to_linearrgb(c):
    if   c < 0:       return 0
    elif c < 0.04045: return c/12.92
    else:             return ((c+0.055)/1.055)**2.4

def hex_to_rgb(h,alpha=1):
    r = (h & 0xff0000) >> 16
    g = (h & 0x00ff00) >> 8
    b = (h & 0x0000ff)
    return tuple([srgb_to_linearrgb(c/0xff) for c in (r,g,b)] + [alpha])

and using it like so:

bpy.data.materials["Material"].node_tree.nodes["RGB"].outputs[0].default_value = \
    hex_to_rgb(0x123456)

seems to work correctly.

$\endgroup$
1
  • 1
    $\begingroup$ Thanks a lot this is precisely what I wanted to get, this is the only answer at the moment on blender.stackexchange which returns correct values, like copying pastes in the RGB node under the heading Hex $\endgroup$
    – Noob Cat
    Nov 23, 2019 at 4:20
0
$\begingroup$

Great script.

I also made a reverse script!

import bpy
def linearrgb_to_srgb(c):
    if c < 0:
        return 0
    elif c < 0.0031308:
        return 12.92 * c
    else:
        return 1.055 * (c ** (1/2.4)) - 0.055

def rgb_to_hex(r, g, b,a):
    r = int(linearrgb_to_srgb(r) * 255 + 0.5)
    g = int(linearrgb_to_srgb(g) * 255 + 0.5)
    b = int(linearrgb_to_srgb(b) * 255 + 0.5)
    return (r << 16) + (g << 8) + b


hex_color = rgb_to_hex(*bpy.context.object.material_slots[0].material.diffuse_color)
print(hex(hex_color))

enter image description here

enter image description here

enter image description here

Also created a script to output 8-bit RBG at the same time

import bpy
def linearrgb_to_srgb(c):
    if c < 0:
        return 0
    elif c < 0.0031308:
        return 12.92 * c
    else:
        return 1.055 * (c ** (1/2.4)) - 0.055

def rgb_to_rgb_ganma(r, g, b,a):
    r_value = int(linearrgb_to_srgb(r) * 255 + 0.5)
    g_value = int(linearrgb_to_srgb(g) * 255 + 0.5)
    b_value = int(linearrgb_to_srgb(b) * 255 + 0.5)
    r_normalized_value = int(linearrgb_to_srgb(r) * 255 + 0.5) / 255
    g_normalized_value = int(linearrgb_to_srgb(g) * 255 + 0.5) / 255
    b_normalized_value = int(linearrgb_to_srgb(b) * 255 + 0.5) / 255
    return (r_value,g_value,b_value), (r_normalized_value,g_normalized_value,b_normalized_value)


hex_color = rgb_to_rgb_ganma(*bpy.data.materials['Material_test'].node_tree.nodes["Principled BSDF"].inputs[0].default_value)
print('###0-0###mat name', bpy.context.object.material_slots[0].name)
print(hex_color)  

Results in Console

###0-0###mat name Material_test
((230, 31, 0), (0.9019607843137255, 0.12156862745098039, 0.0))

'Material_test' of the material name "'Material_test'". 'Principled BSDF' of the material name 'Material_test' has been changed with reference to the gamma value.

enter image description here

Try to enter the colors manually displayed by other external software. (0.9019607843137255, 0.12156862745098039, 0.0) input. In this software, the input ranges from 0 to 1.

enter image description here

It actually turned out to be the same color, but just to be sure, I'll check if the values are the same in the color picker. No problem.

(230, 31, 0) value.

I'll check Blender just to be sure.

enter image description here

We see that the value is (230, 31, 0) without any problem.

I'll check with UNITY as well.

enter image description here

Let's set the shedder to UNIT for easy color picker.

enter image description here

Of course, but it is definitely a value of (230, 31, 0). That is, the same as the color on Blender's color picker.

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .