# How to compute your Crew Color by algorithm.

## Recommended Posts

This post is meant as a open letter to anyone technically inclined within the GTAO community.
It details a way of computing crew color from a sampled "target" RGB value:

Hey guys, I've recently gained some insight as to what seem to be going on with the whole 'crew color must be dark to look bright inside GTA' deal.

Here's what happened:
I was doing some personal R&D developing my own PBR shaders in HLSL when I came across a similar phenomena to what we see with the crew color.

The visuals of GTA V suggest the game uses some early PBR'esque shaders that takes at least some of the now common 'PBR' concepts into account.
(PBR stands for 'Physically Based Rendering' and have become very popular in contemporary game development)

Now what happens in PBR shaders is your gamma corrected SRGB color values (the ones of the pure color you actually see on your display device)
needs to be dropped into a linear color space for the shader to perform the various calculations necessary for the final lighting of the pixel.

If you inspect the color value of a SRGB color that has been dropped to linear it'll look very similar to the darkened shades we
have to input as out crew color for the shade to turn out correct in-game.

So here's what to do (and what should have been done behind the scenes over at Rockstar Socialclub in any decently ran universe)

In a HLSL shader a RGB color is represented by a float3 value that means a value of float3(0.0,0.0,0.0) is black, float3(1.0,0.0,0.0) is red and so on.
the conversion is then as follows:

linearRGB = sRGB * (sRGB * (sRGB * 0.305306011 + 0.682171111) + 0.012522878)

and the inverse going from linear to sRGB is:

float3 S1 = sqrt(linRGB);
float3 S2 = sqrt(S1);
float3 S3 = sqrt(S2);
float3 sRGB = 0.662002687 * S1 + 0.684122060 * S2 - 0.323583601 * S3 - 0.0225411470 * linearRGB;

These long decimal 'magic numbers' are conversion values for fitting the sRGB 'gamma corrected color curve onto a linear one and vice versa.

I only program shaders and various in-engine scripting so I lack the know-how to write a simple stand-alone or web tool that does this.

But if you already know your stuff I imagine it must be super easy to take this and write us a tool that converts a sampled color into linear RGB for immediate use as a GTA hex.

Perhaps some talented coder in the community can pick up this ball and run with it?

Here a pastebin link to a simple .fx shader that does the conversion using the same code as above if useful to anyone (I use the directX shader in 3ds max to utilize this).
details on how to use it are described in the comments at the top of the file if you open it as a textfile: https://pastebin.com/j1823s5Z

Wont be taking any crew color requests, but please feel free to PM if you have other questions. Happy painting ya'll!

Here's a demo image of how this all works in practice.

TLDR: I've discovered the formula GTA likely use behind the scenes to convert the crew color to look different than from what we set it to.

Edited by tjakal
fat fingered a 'z' into the pastebin code so it didn't run
##### Share on other sites

Very interesting. I will try the formula.

##### Share on other sites

Great, now we just need someone to make a user-friendly tool out of this...

• 5
##### Share on other sites

Just tried it and you can easily implement that in a spreadsheet

Assume A1 is the sRGB (0-255) for red, B1 is the sRGB for green, C1 is the sRGB for blue

Set A2 =A1*((A1/255)*((A1/255)*0.305306011+0.682171111)+0.012522878)

Set B2 =B1*((B1/255)*((B1/255)*0.305306011+0.682171111)+0.012522878)

Set C2 =C1*((C1/255)*((C1/255)*0.305306011+0.682171111)+0.012522878)

This gives you the calculated crew color as sRGB

Here's the example from the OP, the crew color OP came up with using 3ds Max evaluates to 4,130,201

• 5
##### Share on other sites

Oh wow, I have been trying to create a program that changes the overall hue and brightness level of a color to what we would see in the game for a while, but it always gave different results depending on the shade or color. This looks certainly more reliable, I will give it a try.

Thanks tjakal!

##### Share on other sites

Seems to work pretty well.

I grabbed a Gulf Racing blue from this file:

sRGB: 182, 224, 247

Turned it into this hex with the formula: #77BEED00

Which resulted in this color (it does glow a bit in the dark):

I used Wolfram Alpha for the calculation:

Edited by SummerFreeze
• 6
##### Share on other sites

Next up is to determine the minimum/maximum color values for the required suffix to make the color work using the inspect element method. Also to figure out which color values don't require a suffix at all. Implement that all into a handy dandy tool, and @JR_Death @JoonasPRKL and others (sorry, they're the only 2 that come to mind right now) can stop getting all these color requests.

THIS IS AWESOME!

edit- just got to thinking. It may prove difficult to use this to replicate colors with pearl in them.

Edited by _Celldweller
• 1
##### Share on other sites

8 hours ago, tjakal said:

I'm seeing inconsistencies in some part of the spectrum suggesting that the 'RockstarRGB' curve is a bit different from the one computed above. It's def a linear/sRGB  conversion that takes place tho but the curve is shaped a bit differently.

I'm tinkering to see if I can make sense of the deviation and map it out flawlessly. I've made 30 trips to LSC updating the crewcolor, reloading the game.. staring at clouds...

• 6
##### Share on other sites

How do you determine the resulting in-game color?

##### Share on other sites

One issue I found so far is that orange (248,89,6) is turned into bright red (239,26,0)

• 2
##### Share on other sites

1 hour ago, SummerFreeze said:

How do you determine the resulting in-game color?

I take the same car with a flat roof into LSC custom center town, since it is a interior where the light is the same regardless the time of day or weather.
I then inspect the active crew color without pearl from the same angle.

I proceed to take a screenshot of the the car from this angle, apply a 'Gaussian blur' to a square selection of the roof to even out all shading and minimize errors from sampling different colored pixels from any reflections.
It's still not the 'true' ingame color since I can't tell how much light is on that surface but it gives me a consistent return value one can use to figure out just how the 'rockstarRGB' curve is shaped.

It took a while but the operation was a success, black lines in the image is the expected color, as you can see there is a fairly wide band  in the spectrum where my method and rockstar is in agreement, but they deviate a lot as we start going into very dark shades and at the extremely bright end (where nothing but nuclear neon kiddos pick their crayons, so that's not as big of a deal). I will try to make sense of what to do with this information but I'll have to sleep on it. I start to feel like duct-tape McGuywer who no longer grasps his own haxxori atm.

1 hour ago, metoxys said:

One issue I found so far is that orange (248,89,6) is turned into bright red (239,26,0)

Yeah I noticed the same thing doing an orange shade. Not sure what could cause that but I will look into it once I've figured out the stuff described above.

##### Share on other sites

The method you describe makes a lot of sense. I thought that maybe I could provide some conversions as well because I have a lot of cars with custom colors, but then I remembered that the same color can also look differently on different cars so it probably wouldn't be much use.

If you are able to determine an accurate formula though, I think a lot of people would appreciate it. I certainly would.

53 minutes ago, tjakal said:
2 hours ago, metoxys said:

One issue I found so far is that orange (248,89,6) is turned into bright red (239,26,0)

Yeah I noticed the same thing doing an orange shade. Not sure what could cause that but I will look into it once I've figured out the stuff described above.

That's just in the nature of the function as low values are lowered more than high values. I assume the same effect exists with other colors that contain both a low and a very high value, like lime green for example.

I have very little knowledge of shaders... is there maybe some preprocessing of colors involved in order to avoid this?

##### Share on other sites

You might want to do this in singleplayer and use a mod menu to change the pearlescent color to chrome (color ID 120) because it is a #000000 hex, meaning that you *truly* have no added pearlescent

##### Share on other sites

Think I got it working now but I have to clean up some messy code and test it out further to be sure. I'll post a update once I've have that done, got sidetracked by the bran new McDonalds today.

In the meantime here's what the new and improved sampler did with that orange.

• 6
##### Share on other sites

This is a really cool project tjakal! If it's any help, I have been trying to improve your formula, but I found that fine-tuning the color with my own eyes is still results in colors closer to what I am aiming for. If it's any help, here are a few examples that you could use a test whenever the formula is correct. Hopefully you can manage to find the right value to fine-tune your algorithm.

real life: #C5624F  (194,98,79)
my attempt: #602820 (96,40,32)

formula in first post : #891F14 (137,31,20)

Spoiler

Another one:

real life: #CB917B (203,145,123)

my attempt:  #6B3A2E (107,58,46)

formula in first post : #98432 (152,72,50)

Spoiler

• 2
##### Share on other sites

Here's the updated version of the shader: https://pastebin.com/9XMG14EL

The new version work different than the first method in that it now uses a stepped curve that closely follow the curve implied by the measurements described in my prev posts.

It also now treats the color as a HSV color (hue saturation value) instead of converting straight to linear RGB. It then corrects the 'value' of that color.
The reason is that this allows the hue to stay the same even if the return value isn't perfect (which it isn't because I don't know the exact values of rockstars curve).
So basically no more oranges turning into bright reds.

The upside is that it now works, the downside is that this uses a lot of stuff you prob can't put into stuff like wolfram or say an excel sheet.
Explanation of the relevant pieces of the code is in the comments of the shader.

So what kind of results can be expected as this currently stands? Here's some example images of the kind of colors this converter spits out in it's current form
It's by no means perfect, but the results it spits out are reasonably good and a very good starting point for perfecting a color manually.

I have some ideas for perfecting it further but at the core are some problems that can't really be overcome by a mere sampler the main ones are as follows:

A) The way many real world paints would scatter the light is just too penomenologically different from how Rockstars carpaint BRDF/shader will distribute the light.
To make certain paints look a bit more like their real world counterparts one have to employ psychovisual strategies rather than straight sampling
and say produce a desaturated color that reads more like the intended color when processed by rockstars carpaint shader.

B) Light conditions inside GTA online are way different than those of real world sunlight which is a lot less yellow.
Making a hue corection curve for the entire spectrum should be possible but may prove a lot of tedious work to set up.
Here's an eample of that last image that demonstrates just how yellow sunlight is in LS by running a photoshop auto-tone filter.

##### Share on other sites

Wow, that's really impressive. Great work!

I don't know about browser extensions but I'll take a look at your code. Maybe it can be run in a browser compiler?

##### Share on other sites

On 8/15/2019 at 9:14 PM, tjakal said:

got sidetracked by the bran new McDonalds today.

##### Share on other sites

I went and implemented it in a google doc.......

Just use the first worksheet and put in the RGB in the yellow-colored fields

I'd argue that the linear interpolation function here is a lot more elegant than that IF construct in the fx file

Edited by metoxys
##### Share on other sites

@tjakal we need to alert people in the kustom crew color request thread. This is such a timesaver. I've spent HOURS getting colors to appear correctly in game and even then, I'll go back and revisit them because I'm still not satisfied.

Edited by _Celldweller
• 2
##### Share on other sites

For those wanting to build their own excel version, here's my attempt to reduce everything to the fewest amount of cells possible for easy copypasting

A1 = your input color R value

B1 = your input color G value

C1 = your input color B value

A2 =ROUND(IF(ROUNDDOWN(F1)=0;1;IF(ROUNDDOWN(F1)=1;(1-(IF(MAX(A1;B1;C1)=0;0;(MAX(A1;B1;C1)-MIN(A1;B1;C1))/MAX(A1;B1;C1))+0.1)*(F1-ROUNDDOWN(F1)));IF(ROUNDDOWN(F1)=2;(1-(IF(MAX(A1;B1;C1)=0;0;(MAX(A1;B1;C1)-MIN(A1;B1;C1))/MAX(A1;B1;C1))+0.1));IF(ROUNDDOWN(F1)=3;(1-(IF(MAX(A1;B1;C1)=0;0;(MAX(A1;B1;C1)-MIN(A1;B1;C1))/MAX(A1;B1;C1))+0.1));IF(ROUNDDOWN(F1)=4;(1-(IF(MAX(A1;B1;C1)=0;0;(MAX(A1;B1;C1)-MIN(A1;B1;C1))/MAX(A1;B1;C1))+0.1)*(1-(F1-ROUNDDOWN(F1))));1)))))*G1*255;0)

B2 =ROUND(IF(ROUNDDOWN(F1)=0;(1-(IF(MAX(A1;B1;C1)=0;0;(MAX(A1;B1;C1)-MIN(A1;B1;C1))/MAX(A1;B1;C1))+0.1)*(1-(F1-ROUNDDOWN(F1))));IF(ROUNDDOWN(F1)=1;1;IF(ROUNDDOWN(F1)=2;1;IF(ROUNDDOWN(F1)=3;(1-(IF(MAX(A1;B1;C1)=0;0;(MAX(A1;B1;C1)-MIN(A1;B1;C1))/MAX(A1;B1;C1))+0.1)*(F1-ROUNDDOWN(F1)));IF(ROUNDDOWN(F1)=4;(1-(IF(MAX(A1;B1;C1)=0;0;(MAX(A1;B1;C1)-MIN(A1;B1;C1))/MAX(A1;B1;C1))+0.1));(1-(IF(MAX(A1;B1;C1)=0;0;(MAX(A1;B1;C1)-MIN(A1;B1;C1))/MAX(A1;B1;C1))+0.1)*(F1-ROUNDDOWN(F1))))))))*G1*255;0)

C2 =ROUND(IF(ROUNDDOWN(F1)=0;(1-(IF(MAX(A1;B1;C1)=0;0;(MAX(A1;B1;C1)-MIN(A1;B1;C1))/MAX(A1;B1;C1))+0.1));IF(ROUNDDOWN(F1)=1;(1-(IF(MAX(A1;B1;C1)=0;0;(MAX(A1;B1;C1)-MIN(A1;B1;C1))/MAX(A1;B1;C1))+0.1));IF(ROUNDDOWN(F1)=2;(1-(IF(MAX(A1;B1;C1)=0;0;(MAX(A1;B1;C1)-MIN(A1;B1;C1))/MAX(A1;B1;C1))+0.1)*(1-(F1-ROUNDDOWN(F1))));IF(ROUNDDOWN(F1)=3;1;IF(ROUNDDOWN(F1)=4;1;(1-(IF(MAX(A1;B1;C1)=0;0;(MAX(A1;B1;C1)-MIN(A1;B1;C1))/MAX(A1;B1;C1))+0.1)*(F1-ROUNDDOWN(F1))))))))*G1*255;0)

^ this is your output color as RGB

D2 ="#"&DEC2HEX(A2;2)&DEC2HEX(B2;2)&DEC2HEX(C2;2)

^ this is your output color as hex

F1 =IF(MAX(A1;B1;C1)=0;0;IF(A1=MAX(A1;B1;C1);(B1-C1)/(MAX(A1;B1;C1)-MIN(A1;B1;C1));IF(B1=MAX(A1;B1;C1);2+(C1-A1)/(MAX(A1;B1;C1)-MIN(A1;B1;C1));4+(A1-B1)/(MAX(A1;B1;C1)-MIN(A1;B1;C1)))))

F2 = 0

F3 = 0.231

F4 = 0.372

F5 = 0.58

F6 = 0.713

F7 = 0.78

F8 = 0.82

F9 = 0.847

F10 = 0.937

F11 = 0.945

F12 = 1

G1 =IFERROR(INDEX(G2:G12;MATCH((MAX(A1;B1;C1)/255);F2:F12;1))+((MAX(A1;B1;C1)/255)-INDEX(F2:F12;MATCH((MAX(A1;B1;C1)/255);F2:F12;1)))*(INDEX(G2:G12;MATCH((MAX(A1;B1;C1)/255);F2:F12;1)+1)-INDEX(G2:G12;MATCH((MAX(A1;B1;C1)/255);F2:F12;1)))/(INDEX(F2:F12;MATCH((MAX(A1;B1;C1)/255);F2:F12;1)+1)-INDEX(F2:F12;MATCH((MAX(A1;B1;C1)/255);F2:F12;1)));1)

G2 = 0.1

G3 = 0.2

G4 = 0.3

G5 = 0.4

G6 = 0.5

G7 = 0.6

G8 = 0.7

G9 = 0.8

G10 = 0.9

G11 = 1

Looks like this if you're doing it correctly:

Edited by metoxys
• 5
##### Share on other sites

This is getting really interesting, the new formula results in really nice close in-game shade to what the input is, but still it is just off a somewhat when it comes to less saturated colors

The fx code right now is a bit confusing to me, I am thankful for metoxys for converting it to excel, I wrote the original one in java, and if we get better results, I might try it again to make a simple converter jar with the final formula.

Edited by Hegedus.Roberto
• 2
##### Share on other sites

Definitely needs a hue adjustment to reduce the yellowness

• 2
##### Share on other sites

22 hours ago, tjakal said:

I think since GTA's yellow sun is something most people have to deal with, and is what is mostly applies for the ingame experience, the algorith should aim to get the color right with it, not without it, but that Is just my opinion

##### Share on other sites

By no means do I have much understanding of how these adjustments are being calculated, but it appears the adjustment is being made to the color values as a whole? I notice when entering new values in for red, my adjusted values for blue and/or green will change. Changing any of the 3 results in a different adjustment to one or both of the other 2. Shouldn't it be individual?

35, 66, 52 is "corrected" to 24, 56, 42. Now simply changing the red from 35 to 65 causes blue's corrected value to change from 42 to 39. Shouldn't blue stay and ONLY have red's corrected value change?

EDIT: Yep, I'm half awake and not thinking clearly. It makes sense that other values get changed in this scenario.

Perhaps the amount or method of adjustment needs to be reworked? The values should be reduced by a percentage to prevent adjustments going negative and this may also help the adjustments of certain hues like in the case of correcting some orange colors?

Edited by _Celldweller
##### Share on other sites

Ok, guys I have some improvements here to help combat that yellow sun: https://pastebin.com/RjPzy7BC

I added in a function that blends in a blue 'anti sun' filter into the output color and it seem to be working as intended and pushes my testcolors to look that more like they do in the reference during GTAO daylight.

13 hours ago, _Celldweller said:

Changing any of the 3 results in a different adjustment to one or both of the other 2. Shouldn't it be individual?

EDIT: Yep, I'm half awake and not thinking clearly. It makes sense that other values get changed in this scenario.

Yeah, all values changing if you tweak one channel is expected behavior.
The reason can be understood as that it retargets the total of the color to fit rockstars 'gamma correction curve' and every channel does not have the same contribution to the total value of a color (red 0.3, green 0.59, blue 0.11).

Not sure what's up with the de-saturated colors, could be they are just that more sensitive to the errors in my best estimates of the color curve and that it needs to be refined further.
But to properly answer what might be up with them I would have to conduct some further testing, it might take a while til I have time to spare for something like that tho.

##### Share on other sites

I was half asleep when I had my "epiphany" and quickly hammered out a message before giving it any further thought. I left it after I realized my mitsake just in case it might trigger a thought or at least amuse someone.

I hope you continue your efforts towards "perfecting" these correction calculations. You've inspired me to get back into attempting to recreate paints in gta.

##### Share on other sites

14 hours ago, tjakal said:

Ok, guys I have some improvements here to help combat that yellow sun: https://pastebin.com/RjPzy7BC

I added in a function that blends in a blue 'anti sun' filter into the output color and it seem to be working as intended and pushes my testcolors to look that more like they do in the reference during GTAO daylight.

That is a fantastic move, much simpler than what I was thinking could solve it! Looking forward to test it, hopefully metoxys can soon help with providing an excel formula for the new method too!

##### Share on other sites

Just my 2¢ here. I think you should consider this, an S curve on a graph. Percentage of reduction on the X axis and the range of color intensity (0 - 255) on the Y axis. For the percentage, it would likely be 0% at both ends. A 0 value would get 0% reduction as well as a 255 value. The highest reduction percentage (maybe 45%?) would likely fall in the middle and possibly over a range of color values. 125 - 130 perhaps.

Who knows, I could be way off. Just some ramblings.

Edit - Come to think of it, a bell curve would make much more sense. Derp.

Jackieeeeee! One more thing.

Not sure if you're aware, but the human eye is most perceptive to the color green. I think if you can focus on and perfect a correction adjustment across a wide range of greens, the same corrections will apply to all colors.

Edited by _Celldweller
##### Share on other sites

This topic looks very interesting. I've been puzzled by the game's color filters for some time now, glad to see all this data!

I mean, I'm a bit scared to dig in just yet from the looks of it, but will definitely check this out, thank you!

• 2

## Create an account

Register a new account

• ### 3 Users Currently Viewing 2 members, 0 Anonymous, 1 Guest

• Plocospermataceae
• SFCBCPB
×