Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // tjakal's GTA online Crew Color converter. V1.01
- // Use: place this text into a textfile and give it a .fx ending.
- // Apply it as a directX shader in 3ds max or other software that renders .fx shaders.
- // sample the color you want and place it in the 'target color' colorpicker.
- // the color your object turns out is what you wanna use as your hex on socialclub. I use photshop to sample it.
- // The relevant code for what it actually does starts at line 253 incase someone want to attempt building a stand-alone tool from this.
- // It's end is marked as well. The rest is just shader stuff.
- string ParamID = "0x003"; //use DXSAS compiler
- /************ Matrixes imported from application **************/
- float4x4 WorldViewProjection : WorldViewProjection;
- float4x4 WorldInverseTranspose : WorldInverseTranspose;
- float4x4 ViewInverse : ViewInverse ;
- float4x4 World : World;
- float4x4 WorldViewProjectionInverse : WorldViewProjectionInverse;
- /************* Interface Tweakables. ****************/
- //color pickers
- float Val1
- <
- string UIType = "FloatSpinner";
- float UIMin = 0.0;
- float UIMax = 1.0;
- float UIStep = 0.01;
- string UIName = "V1: ";
- > = 1.0;
- float Val2
- <
- string UIType = "FloatSpinner";
- float UIMin = 0.0;
- float UIMax = 1.0;
- float UIStep = 0.01;
- string UIName = "V2: ";
- > = 1.0;
- float Val3
- <
- string UIType = "FloatSpinner";
- float UIMin = 0.0;
- float UIMax = 1.0;
- float UIStep = 0.01;
- string UIName = "V3: ";
- > = 1.0;
- float Val4
- <
- string UIType = "FloatSpinner";
- float UIMin = 0.0;
- float UIMax = 1.0;
- float UIStep = 0.01;
- string UIName = "V4: ";
- > = 1.0;
- float Val5
- <
- string UIType = "FloatSpinner";
- float UIMin = 0.0;
- float UIMax = 1.0;
- float UIStep = 0.01;
- string UIName = "V5: ";
- > = 1.0;
- float Val6
- <
- string UIType = "FloatSpinner";
- float UIMin = 0.0;
- float UIMax = 1.0;
- float UIStep = 0.01;
- string UIName = "V6: ";
- > = 1.0;
- float Val7
- <
- string UIType = "FloatSpinner";
- float UIMin = 0.0;
- float UIMax = 1.0;
- float UIStep = 0.01;
- string UIName = "V7: ";
- > = 1.0;
- float Val8
- <
- string UIType = "FloatSpinner";
- float UIMin = 0.0;
- float UIMax = 1.0;
- float UIStep = 0.01;
- string UIName = "V8: ";
- > = 1.0;
- float Val9
- <
- string UIType = "FloatSpinner";
- float UIMin = 0.0;
- float UIMax = 1.0;
- float UIStep = 0.01;
- string UIName = "V9: ";
- > = 1.0;
- float Val10
- <
- string UIType = "FloatSpinner";
- float UIMin = 0.0;
- float UIMax = 1.0;
- float UIStep = 0.01;
- string UIName = "V10: ";
- > = 1.0;
- float finalTweak
- <
- string UIType = "FloatSpinner";
- float UIMin = 0.0;
- float UIMax = 2.0;
- float UIStep = 0.01;
- string UIName = "Final Multiplier: ";
- > = 1.0;
- texture diffuseMap : DiffuseMap
- <
- string name = "none.dds";
- string UIName = "Diffuse Texture";
- >;
- float4 targetColor : TargetColor
- < string UIName = "The crew color I want: ";> = {0.25f, 0.25f, 0.25f, 1.0f};
- /****************************************************/
- /********** CG SHADER FUNCTIONS *********************/
- /****************************************************/
- sampler2D diffuseMapSampler = sampler_state
- {
- MaxAnisotropy = 16;
- Texture = <diffuseMap>;
- MinFilter = Anisotropic;
- MagFilter = Linear;
- MipFilter = Anisotropic; //optimize to linear perhaps?
- ADDRESSU = WRAP;
- ADDRESSV = WRAP;
- };
- /*
- int uv : Texcoord
- <
- int Texcoord = 0;
- int MapChannel = 1;
- string UIType = "None";
- >;
- */
- // input from application
- struct app2vertexShader
- {
- float4 position : POSITION;
- float2 uv : TEXCOORD0;
- float3 tangent : TANGENT;
- float3 binormal : BINORMAL;
- float3 normal : NORMAL;
- };
- // output to fragment program
- struct vert2pixel
- {
- float4 position : POSITION;
- float2 uv : TEXCOORD0;
- float3 eyeVec : TEXCOORD1;
- float3 lightVec : TEXCOORD2;
- float3 worldNormal : TEXCOORD3;
- float3 worldTangent : TEXCOORD4;
- float3 worldBinormal : TEXCOORD5;
- float4 screenPos : TEXCOORD6;
- float3 posPos : TEXCOORD7;
- };
- //************ Lights *******************************/
- float4 light1Pos : POSITION
- <
- string UIName = "Light Position";
- string Object = "PointLight";
- string Space = "World";
- int refID = 0;
- > = {100.0f, 100.0f, 100.0f, 0.0f};
- float4 light1Color : LIGHTCOLOR
- <
- int LightRef = 0;
- > = { 1.0f, 1.0f, 1.0f, 0.0f };
- /****************************************************/
- /************* Vertex Shader. ***********************/
- /****************************************************/
- vert2pixel vertexShader(app2vertexShader In, uniform float4 lightPosition)
- //vert2pixel vertexShader(app2vertexShader In)
- {
- vert2pixel Out;
- Out.worldNormal = mul(In.normal, WorldInverseTranspose).xyz;
- Out.worldTangent = mul(In.tangent, WorldInverseTranspose).xyz;
- Out.worldBinormal = mul(In.binormal, WorldInverseTranspose).xyz;
- float3 worldSpacePos = mul(In.position, World);
- Out.lightVec = lightPosition;
- Out.uv.xy = In.uv.xy;
- Out.eyeVec = ViewInverse[3].xyz - worldSpacePos;
- Out.position = mul(In.position, WorldViewProjection);
- Out.screenPos = Out.position;
- Out.posPos = In.position.xyz;
- return Out;
- }
- /***************************************************/
- /************* Pixel Shader. ***********************/
- /***************************************************/
- float3 linRGB(float3 sRGB) //converts input sRGB to linear.
- {
- float3 lRGB = sRGB * (sRGB * (sRGB * 0.305306011 + 0.682171111) + 0.012522878);
- return lRGB;
- }
- float3 sRGB(float3 linRGB) //converts linear RGB into sRGB.
- {
- 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 * linRGB;
- return sRGB;
- }
- //**** This is the start of the relevant code. ****
- float rockstarLinear(float inputVal)
- {
- float gammaMult;
- float interpolation;
- //these are the weights for the curve vertices, their values are derived from testing colors with known values inside LSC and compare their onscreen value to the input.
- float V1 = 0.231;
- float V2 = 0.372;
- float V3 = 0.580;
- float V4 = 0.713;
- float V5 = 0.780;
- float V6 = 0.820;
- float V7 = 0.847;
- float V8 = 0.937;
- float V9 = 0.945;
- float V10 = 1.0;
- //these are the linear values they map to, they should be a evenly spaced fraction of one. zero is implied.
- float L1 = 0.1;
- float L2 = 0.2;
- float L3 = 0.3;
- float L4 = 0.4;
- float L5 = 0.5;
- float L6 = 0.6;
- float L7 = 0.7;
- float L8 = 0.8;
- float L9 = 0.9;
- float L10 = 1.0;
- // Using a not so elegant progression of linear interpolations we can smoothly follow
- // a stepped curve that closly follows the one rockstar uses for gamma correction on their vehicles.
- // Depending on how many vertices we have on this curve and how right we get their true values this should be very accurate.
- //The lerp(A,B,C) function does a 'linear interpolation' going from 'A' towards 'B' by the percentage specified in 'C'
- if(inputVal < V1)
- {
- interpolation = inputVal / V1;
- gammaMult = lerp(0.0,L1,interpolation);
- }
- else if(inputVal < V2)
- {
- interpolation = (inputVal - V1)/(V2 - V1);
- gammaMult = lerp(L1,L2,interpolation);
- }
- else if(inputVal < V3)
- {
- interpolation = (inputVal - V2)/(V3 - V2);
- gammaMult = lerp(L2,L3,interpolation);
- }
- else if(inputVal < V4)
- {
- interpolation = (inputVal - V3)/(V4 - V3);
- gammaMult = lerp(L3,L4,interpolation);
- }
- else if(inputVal < V5)
- {
- interpolation = (inputVal - V4)/(V5 - V4);
- gammaMult = lerp(L4,L5,interpolation);
- }
- else if(inputVal < V6)
- {
- interpolation = (inputVal - V5)/(V6 - V5);
- gammaMult = lerp(L5,L6,interpolation);
- }
- else if(inputVal < V7)
- {
- interpolation = (inputVal - V6)/(V7 - V6);
- gammaMult = lerp(L6,L7,interpolation);
- }
- else if(inputVal < V8)
- {
- interpolation = (inputVal - V7)/(V8 - V7);
- gammaMult = lerp(L7,L8,interpolation);
- }
- else if(inputVal < V9)
- {
- interpolation = (inputVal - V8)/(V9 - V8);
- gammaMult = lerp(L8,L9,interpolation);
- }
- else
- {
- interpolation = (inputVal - V9)/(V10 - V9);
- gammaMult = lerp(L9,L10,interpolation);
- }
- float retVal = gammaMult;
- return retVal;
- }
- float intensity(float3 inputColor)
- {
- float inten = (inputColor.r*0.3)+(inputColor.g*0.59)+(inputColor.b*0.11);
- return inten;
- }
- //A function for converting RGB back into Hue-Saturation-Value.
- float3 RGB2HSV(float3 inRGB)
- {
- // the min, max functions selects the largest or the smallest value compared.
- float minChan = min(inRGB.r,min(inRGB.g ,inRGB.b ));
- float maxChan = max(inRGB.r,max(inRGB.g ,inRGB.b ));
- float hue = 0.0;
- float saturation = 0.0;
- float value = maxChan;
- float delta = maxChan - minChan;
- if(maxChan != 0.0)
- {
- saturation = delta / maxChan;
- }
- else
- {
- //it's black.
- return float3(0,0,0);
- }
- // deciding the hue
- if (inRGB.r == value )
- {
- hue = (inRGB.g - inRGB.b) / delta;
- }
- else if (inRGB.g == value)
- {
- hue = 2 + (inRGB.b - inRGB.r) / delta;
- }
- else // blue is value, don't need if (inRGB.b == value)
- {
- hue = 4 + (inRGB.r - inRGB.g) / delta;
- }
- return float3(hue,saturation,value);
- }
- float3 HSV2RGB(float3 inHSV) //A function for converting HSV back to RGB.
- {
- float3 RGB = inHSV.z;
- float hue = inHSV.x;
- float saturation = inHSV.y;
- float value = inHSV.z;
- float i = floor(hue);
- float f = hue - i;
- float p = (1.0 - saturation);
- float q = (1.0 - saturation * f);
- float t = (1.0 - saturation * (1 - f));
- if (i == 0) { RGB = float3(1, t, p); }
- else if (i == 1) { RGB = float3(q, 1, p); }
- else if (i == 2) { RGB = float3(p, 1, t); }
- else if (i == 3) { RGB = float3(p, q, 1); }
- else if (i == 4) { RGB = float3(t, p, 1); }
- else { RGB = float3(1, p, q); }
- RGB *= value;
- return RGB;
- }
- // This is a highly accurate function for blending colors that work by interpolating them across a vectorized colorspace.
- // this more fancy color blending is necessary to ensure that a color transitions thru the correct shades before arriving at the target.
- // For example a red will turn into a pure yellow midway towards a green instead of getting desaturated in the middle like a gradient in say photoshop would.
- float3 blendColor(float3 colorA, float3 colorB, float mixVal)
- {
- float baseMagnitude = sqrt(pow(colorA.r,2)+pow(colorA.g,2)+pow(colorA.b,2));
- float blendMagnitude = sqrt(pow(colorB.r,2)+pow(colorB.g,2)+pow(colorB.b,2));
- float3 colorLerp = normalize(lerp(colorA.rgb,colorB,mixVal)); //normalize() gives the 'normalized vector', it ensures that the XYZ direction of the vector adds up to unit lenght (a magnitude of 1).
- float magnitudeLerp = lerp(baseMagnitude,blendMagnitude,mixVal);
- return colorLerp*magnitudeLerp;
- }
- float4 pixelShader (vert2pixel In,uniform float4 lightColor) : COLOR
- {
- //float3 diffuseVal = tex2D(diffuseMapSampler, In.uv).xyz; //cited out, this line is used for shader testing purposes.
- float3 HSVcolor = RGB2HSV(targetColor); // converting the target color to Hue Saturation Value instead of RGB.
- float inten = rockstarLinear(HSVcolor.z); // determine what linear value the value of our desired color maps to.
- HSVcolor.z = inten;
- HSVcolor.y += 0.1; //saturate by 10% since this seem to be the avarage of a universal loss of saturation inside the game.
- float3 RGBcolor = HSV2RGB(HSVcolor); // converting back to RGB to give us our corrected crew color value.
- //The following attempts to correct for the overly yellow sunlight within GTA V.
- float3 antiSun = float3(0,0,1); // lacking exact color value for sunlight in GTA I assume it is yellow and therefore chose the inverse, a pure blue, as antisun color.
- RGBcolor = blendColor(RGBcolor, antiSun, 0.08); // I estimate that 8% is about the correct figure based on what I can see from my testing and eyeballing colors in photoshop
- //******* This is the end of the relevant part *********
- //(This is just applying it within the shader)
- float4 C;
- C.rgb = RGBcolor;
- C.a = 1.0;
- return C;
- }
- /************* Teqniques. ****************************/
- technique alphaTest
- {
- pass one
- {
- VertexShader = compile vs_3_0 vertexShader(light1Pos);
- ZEnable = true;
- ZWriteEnable = true;
- CullMode = none;
- AlphaTestEnable = false;
- AlphaFunc = less;
- AlphaRef = 0x00000001;
- AlphaBlendEnable = true;
- SrcBlendAlpha = one;
- DestBlendAlpha = one;
- StencilEnable = True;
- PixelShader = compile ps_3_0 pixelShader(light1Color);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement