Sketchfab - PBR / RGB Normalized Issues

(Richardkarlgregg) #1

Hey there, I've been using the SketchFab viewer API along with the awesome Sketchfab API Utility plugin to create a chair configuration tool.

The lighting mode is PBR and Materials are PBR Maps with the Base Colour set.

The colours are set using a HEX value, which in turn get converted into a Normalized RGB value by Sketchfab API Utility. This works in terms of changing the colour, however the returned colour seems to be quite off what it should be and ends up looking more washed out.

See attached for a comparison of a purple finish colour -

What it should be -

What gets applied -

I can see how the colour gets applied inside SketchfabAPIUtility.js via the setColor function.

This bit of code spilts the hex value into rgb and converts to the normalized value -

channelObjectRef.color[0] = parseInt(result[1], 16) / 255;
channelObjectRef.color[1] = parseInt(result[2], 16) / 255;
channelObjectRef.color[2] = parseInt(result[3], 16) / 255;

When I set the purple inside Sketchfab it's Normalised RGB value is -
[0.18116424424986022, 0.03954623527673285, 0.08228270712981482]

But SketchfabAPIUtility.js converts it to -
[0.4627450980392157, 0.2196078431372549, 0.3176470588235294]

The JS call -

$("#2187_8").on("click", function (event) {
sketchfabAPIUtility.setColor("seat", sketchfabAPIUtility.AlbedoPBR, "#763851");

Which is the washed out purple :frowning:

I'm struggling to work out what the issue is, not sure if I've missed a setting inside Sketchfab for the model or if SketchfabAPIUtility.js is converting the values in correctly.

Any help / advice would be appreciated :slight_smile:

Thank you in advanced!

  • Richard

(Stephomi) #2

Our internal materials representation only store colors in linear space, not in srgb .

var gamma = 2.4;

var linearToSrgb = function ( c ) {
    var v = 0.0;
    if ( c < 0.0031308 ) {
        if ( c > 0.0 )
            v = c * 12.92;
    } else {
        v = 1.055 * Math.pow( c, 1.0 / gamma ) - 0.055;
    return v;

var srgbToLinear = function ( c ) {
    var v = 0.0;
    if ( c < 0.04045 ) {
        if ( c >= 0.0 )
            v = c * ( 1.0 / 12.92 );
    } else {
        v = Math.pow( ( c + 0.055 ) * ( 1.0 / 1.055 ), gamma );
    return v;

So ideally, the @shaderbytes helpers could do the conversion here:

channelObjectRef.color[0] = srgbToLinear(parseInt(result[1], 16) / 255);
channelObjectRef.color[1] = srgbToLinear(parseInt(result[2], 16) / 255);
channelObjectRef.color[2] = srgbToLinear(parseInt(result[3], 16) / 255);

It's probably easier than giving a hex string in linear space that could loose some precision.

I know it sound tricky, but currently our material API is kind of rough.
Maybe in the future, we'll polish it and give easier-to-use end point (such as setColorSRGB vs setColorLinear).

(Richardkarlgregg) #3

ah that makes sense :slight_smile:

3D Max uses linear space for RGB values as well (I think).

Thank you so much for the quick response, I've been able to roughly translate that calculation into SketchfabAPIUtility and it works perfectly.

My JS isn't very clean so will leave it up to the SketchfabAPIUtility.js people to update their code (if they choose).

Pretty new to Sketchfab but I'm hooked already :wink:

  • Richard

(Shaderbytes) #4

Hi there

I actually discovered this issue with the color setting a while ago and @james pointed me to these same functions back then. I got side tracked though and when I returned to development on the Utility I totally forgot about this. Sorry about that. I have updated the code on github


(Richardkarlgregg) #5

Thank you :slight_smile:

SketchfabAPIUtility.js has made an already awesome API even more awesome!

(4535992) #6

Hi, late to the party, @richardkarlgregg is possible to see a page with your solution implemented?

Colors not importing correctly from Cinema 4D