Advertisement
tjakal

GTA online crew color converter 1.01

Aug 19th, 2019
1,517
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.92 KB | None | 0 0
  1. // tjakal's GTA online Crew Color converter. V1.01
  2. // Use: place this text into a textfile and give it a .fx ending.
  3. // Apply it as a directX shader in 3ds max or other software that renders .fx shaders.
  4. // sample the color you want and place it in the 'target color' colorpicker.
  5. // the color your object turns out is what you wanna use as your hex on socialclub. I use photshop to sample it.
  6.  
  7. // The relevant code for what it actually does starts at line 253 incase someone want to attempt building a stand-alone tool from this.
  8. // It's end is marked as well. The rest is just shader stuff.
  9.  
  10. string ParamID = "0x003"; //use DXSAS compiler
  11.  
  12. /************ Matrixes imported from application **************/
  13.  
  14. float4x4 WorldViewProjection : WorldViewProjection;
  15. float4x4 WorldInverseTranspose : WorldInverseTranspose;
  16. float4x4 ViewInverse : ViewInverse ;
  17. float4x4 World : World;
  18. float4x4 WorldViewProjectionInverse : WorldViewProjectionInverse;
  19.  
  20. /************* Interface Tweakables. ****************/
  21.  
  22.  
  23.  
  24. //color pickers
  25. float Val1
  26. <
  27. string UIType = "FloatSpinner";
  28. float UIMin = 0.0;
  29. float UIMax = 1.0;
  30. float UIStep = 0.01;
  31. string UIName = "V1: ";
  32. > = 1.0;
  33.  
  34. float Val2
  35. <
  36. string UIType = "FloatSpinner";
  37. float UIMin = 0.0;
  38. float UIMax = 1.0;
  39. float UIStep = 0.01;
  40. string UIName = "V2: ";
  41. > = 1.0;
  42.  
  43. float Val3
  44. <
  45. string UIType = "FloatSpinner";
  46. float UIMin = 0.0;
  47. float UIMax = 1.0;
  48. float UIStep = 0.01;
  49. string UIName = "V3: ";
  50. > = 1.0;
  51.  
  52. float Val4
  53. <
  54. string UIType = "FloatSpinner";
  55. float UIMin = 0.0;
  56. float UIMax = 1.0;
  57. float UIStep = 0.01;
  58. string UIName = "V4: ";
  59. > = 1.0;
  60.  
  61. float Val5
  62. <
  63. string UIType = "FloatSpinner";
  64. float UIMin = 0.0;
  65. float UIMax = 1.0;
  66. float UIStep = 0.01;
  67. string UIName = "V5: ";
  68. > = 1.0;
  69.  
  70. float Val6
  71. <
  72. string UIType = "FloatSpinner";
  73. float UIMin = 0.0;
  74. float UIMax = 1.0;
  75. float UIStep = 0.01;
  76. string UIName = "V6: ";
  77. > = 1.0;
  78.  
  79. float Val7
  80. <
  81. string UIType = "FloatSpinner";
  82. float UIMin = 0.0;
  83. float UIMax = 1.0;
  84. float UIStep = 0.01;
  85. string UIName = "V7: ";
  86. > = 1.0;
  87.  
  88. float Val8
  89. <
  90. string UIType = "FloatSpinner";
  91. float UIMin = 0.0;
  92. float UIMax = 1.0;
  93. float UIStep = 0.01;
  94. string UIName = "V8: ";
  95. > = 1.0;
  96.  
  97. float Val9
  98. <
  99. string UIType = "FloatSpinner";
  100. float UIMin = 0.0;
  101. float UIMax = 1.0;
  102. float UIStep = 0.01;
  103. string UIName = "V9: ";
  104. > = 1.0;
  105.  
  106. float Val10
  107. <
  108. string UIType = "FloatSpinner";
  109. float UIMin = 0.0;
  110. float UIMax = 1.0;
  111. float UIStep = 0.01;
  112. string UIName = "V10: ";
  113. > = 1.0;
  114.  
  115. float finalTweak
  116. <
  117. string UIType = "FloatSpinner";
  118. float UIMin = 0.0;
  119. float UIMax = 2.0;
  120. float UIStep = 0.01;
  121. string UIName = "Final Multiplier: ";
  122. > = 1.0;
  123.  
  124.  
  125.  
  126. texture diffuseMap : DiffuseMap
  127. <
  128. string name = "none.dds";
  129. string UIName = "Diffuse Texture";
  130.  
  131. >;
  132.  
  133.  
  134. float4 targetColor : TargetColor
  135. < string UIName = "The crew color I want: ";> = {0.25f, 0.25f, 0.25f, 1.0f};
  136.  
  137.  
  138.  
  139.  
  140.  
  141. /****************************************************/
  142. /********** CG SHADER FUNCTIONS *********************/
  143. /****************************************************/
  144.  
  145. sampler2D diffuseMapSampler = sampler_state
  146. {
  147. MaxAnisotropy = 16;
  148.  
  149. Texture = <diffuseMap>;
  150. MinFilter = Anisotropic;
  151. MagFilter = Linear;
  152. MipFilter = Anisotropic; //optimize to linear perhaps?
  153. ADDRESSU = WRAP;
  154. ADDRESSV = WRAP;
  155. };
  156.  
  157.  
  158. /*
  159. int uv : Texcoord
  160. <
  161. int Texcoord = 0;
  162. int MapChannel = 1;
  163. string UIType = "None";
  164. >;
  165. */
  166.  
  167. // input from application
  168. struct app2vertexShader
  169. {
  170. float4 position : POSITION;
  171. float2 uv : TEXCOORD0;
  172. float3 tangent : TANGENT;
  173. float3 binormal : BINORMAL;
  174. float3 normal : NORMAL;
  175. };
  176.  
  177. // output to fragment program
  178. struct vert2pixel
  179. {
  180. float4 position : POSITION;
  181. float2 uv : TEXCOORD0;
  182. float3 eyeVec : TEXCOORD1;
  183. float3 lightVec : TEXCOORD2;
  184. float3 worldNormal : TEXCOORD3;
  185. float3 worldTangent : TEXCOORD4;
  186. float3 worldBinormal : TEXCOORD5;
  187. float4 screenPos : TEXCOORD6;
  188. float3 posPos : TEXCOORD7;
  189. };
  190.  
  191. //************ Lights *******************************/
  192.  
  193. float4 light1Pos : POSITION
  194. <
  195. string UIName = "Light Position";
  196. string Object = "PointLight";
  197. string Space = "World";
  198. int refID = 0;
  199. > = {100.0f, 100.0f, 100.0f, 0.0f};
  200.  
  201.  
  202. float4 light1Color : LIGHTCOLOR
  203. <
  204. int LightRef = 0;
  205. > = { 1.0f, 1.0f, 1.0f, 0.0f };
  206.  
  207.  
  208. /****************************************************/
  209. /************* Vertex Shader. ***********************/
  210. /****************************************************/
  211.  
  212. vert2pixel vertexShader(app2vertexShader In, uniform float4 lightPosition)
  213. //vert2pixel vertexShader(app2vertexShader In)
  214. {
  215. vert2pixel Out;
  216. Out.worldNormal = mul(In.normal, WorldInverseTranspose).xyz;
  217. Out.worldTangent = mul(In.tangent, WorldInverseTranspose).xyz;
  218. Out.worldBinormal = mul(In.binormal, WorldInverseTranspose).xyz;
  219. float3 worldSpacePos = mul(In.position, World);
  220. Out.lightVec = lightPosition;
  221. Out.uv.xy = In.uv.xy;
  222.  
  223. Out.eyeVec = ViewInverse[3].xyz - worldSpacePos;
  224. Out.position = mul(In.position, WorldViewProjection);
  225. Out.screenPos = Out.position;
  226. Out.posPos = In.position.xyz;
  227.  
  228. return Out;
  229. }
  230.  
  231. /***************************************************/
  232. /************* Pixel Shader. ***********************/
  233. /***************************************************/
  234.  
  235.  
  236. float3 linRGB(float3 sRGB) //converts input sRGB to linear.
  237. {
  238. float3 lRGB = sRGB * (sRGB * (sRGB * 0.305306011 + 0.682171111) + 0.012522878);
  239. return lRGB;
  240. }
  241.  
  242. float3 sRGB(float3 linRGB) //converts linear RGB into sRGB.
  243. {
  244. float3 S1 = sqrt(linRGB);
  245. float3 S2 = sqrt(S1);
  246. float3 S3 = sqrt(S2);
  247. float3 sRGB = 0.662002687 * S1 + 0.684122060 * S2 - 0.323583601 * S3 - 0.0225411470 * linRGB;
  248.  
  249. return sRGB;
  250. }
  251.  
  252.  
  253. //**** This is the start of the relevant code. ****
  254.  
  255.  
  256. float rockstarLinear(float inputVal)
  257. {
  258.  
  259. float gammaMult;
  260. float interpolation;
  261.  
  262.  
  263.  
  264.  
  265. //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.
  266.  
  267. float V1 = 0.231;
  268. float V2 = 0.372;
  269. float V3 = 0.580;
  270. float V4 = 0.713;
  271. float V5 = 0.780;
  272. float V6 = 0.820;
  273. float V7 = 0.847;
  274. float V8 = 0.937;
  275. float V9 = 0.945;
  276. float V10 = 1.0;
  277.  
  278.  
  279.  
  280. //these are the linear values they map to, they should be a evenly spaced fraction of one. zero is implied.
  281. float L1 = 0.1;
  282. float L2 = 0.2;
  283. float L3 = 0.3;
  284. float L4 = 0.4;
  285. float L5 = 0.5;
  286. float L6 = 0.6;
  287. float L7 = 0.7;
  288. float L8 = 0.8;
  289. float L9 = 0.9;
  290. float L10 = 1.0;
  291.  
  292.  
  293.  
  294. // Using a not so elegant progression of linear interpolations we can smoothly follow
  295. // a stepped curve that closly follows the one rockstar uses for gamma correction on their vehicles.
  296. // Depending on how many vertices we have on this curve and how right we get their true values this should be very accurate.
  297.  
  298. //The lerp(A,B,C) function does a 'linear interpolation' going from 'A' towards 'B' by the percentage specified in 'C'
  299.  
  300. if(inputVal < V1)
  301. {
  302. interpolation = inputVal / V1;
  303. gammaMult = lerp(0.0,L1,interpolation);
  304. }
  305. else if(inputVal < V2)
  306. {
  307. interpolation = (inputVal - V1)/(V2 - V1);
  308. gammaMult = lerp(L1,L2,interpolation);
  309. }
  310. else if(inputVal < V3)
  311. {
  312. interpolation = (inputVal - V2)/(V3 - V2);
  313. gammaMult = lerp(L2,L3,interpolation);
  314. }
  315. else if(inputVal < V4)
  316. {
  317. interpolation = (inputVal - V3)/(V4 - V3);
  318. gammaMult = lerp(L3,L4,interpolation);
  319. }
  320. else if(inputVal < V5)
  321. {
  322. interpolation = (inputVal - V4)/(V5 - V4);
  323. gammaMult = lerp(L4,L5,interpolation);
  324. }
  325. else if(inputVal < V6)
  326. {
  327. interpolation = (inputVal - V5)/(V6 - V5);
  328. gammaMult = lerp(L5,L6,interpolation);
  329. }
  330. else if(inputVal < V7)
  331. {
  332. interpolation = (inputVal - V6)/(V7 - V6);
  333. gammaMult = lerp(L6,L7,interpolation);
  334. }
  335. else if(inputVal < V8)
  336. {
  337. interpolation = (inputVal - V7)/(V8 - V7);
  338. gammaMult = lerp(L7,L8,interpolation);
  339. }
  340. else if(inputVal < V9)
  341. {
  342. interpolation = (inputVal - V8)/(V9 - V8);
  343. gammaMult = lerp(L8,L9,interpolation);
  344. }
  345. else
  346. {
  347. interpolation = (inputVal - V9)/(V10 - V9);
  348. gammaMult = lerp(L9,L10,interpolation);
  349. }
  350.  
  351.  
  352. float retVal = gammaMult;
  353.  
  354. return retVal;
  355. }
  356.  
  357. float intensity(float3 inputColor)
  358. {
  359. float inten = (inputColor.r*0.3)+(inputColor.g*0.59)+(inputColor.b*0.11);
  360. return inten;
  361. }
  362.  
  363.  
  364.  
  365. //A function for converting RGB back into Hue-Saturation-Value.
  366. float3 RGB2HSV(float3 inRGB)
  367. {
  368. // the min, max functions selects the largest or the smallest value compared.
  369. float minChan = min(inRGB.r,min(inRGB.g ,inRGB.b ));
  370. float maxChan = max(inRGB.r,max(inRGB.g ,inRGB.b ));
  371.  
  372. float hue = 0.0;
  373. float saturation = 0.0;
  374. float value = maxChan;
  375.  
  376.  
  377. float delta = maxChan - minChan;
  378. if(maxChan != 0.0)
  379. {
  380. saturation = delta / maxChan;
  381. }
  382. else
  383. {
  384. //it's black.
  385. return float3(0,0,0);
  386. }
  387.  
  388. // deciding the hue
  389. if (inRGB.r == value )
  390. {
  391. hue = (inRGB.g - inRGB.b) / delta;
  392. }
  393. else if (inRGB.g == value)
  394. {
  395. hue = 2 + (inRGB.b - inRGB.r) / delta;
  396. }
  397. else // blue is value, don't need if (inRGB.b == value)
  398. {
  399. hue = 4 + (inRGB.r - inRGB.g) / delta;
  400. }
  401.  
  402. return float3(hue,saturation,value);
  403. }
  404.  
  405. float3 HSV2RGB(float3 inHSV) //A function for converting HSV back to RGB.
  406. {
  407. float3 RGB = inHSV.z;
  408.  
  409. float hue = inHSV.x;
  410. float saturation = inHSV.y;
  411. float value = inHSV.z;
  412.  
  413. float i = floor(hue);
  414. float f = hue - i;
  415.  
  416. float p = (1.0 - saturation);
  417. float q = (1.0 - saturation * f);
  418. float t = (1.0 - saturation * (1 - f));
  419.  
  420. if (i == 0) { RGB = float3(1, t, p); }
  421. else if (i == 1) { RGB = float3(q, 1, p); }
  422. else if (i == 2) { RGB = float3(p, 1, t); }
  423. else if (i == 3) { RGB = float3(p, q, 1); }
  424. else if (i == 4) { RGB = float3(t, p, 1); }
  425. else { RGB = float3(1, p, q); }
  426.  
  427. RGB *= value;
  428.  
  429. return RGB;
  430. }
  431.  
  432. // This is a highly accurate function for blending colors that work by interpolating them across a vectorized colorspace.
  433. // this more fancy color blending is necessary to ensure that a color transitions thru the correct shades before arriving at the target.
  434. // 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.
  435. float3 blendColor(float3 colorA, float3 colorB, float mixVal)
  436. {
  437. float baseMagnitude = sqrt(pow(colorA.r,2)+pow(colorA.g,2)+pow(colorA.b,2));
  438. float blendMagnitude = sqrt(pow(colorB.r,2)+pow(colorB.g,2)+pow(colorB.b,2));
  439.  
  440. 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).
  441. float magnitudeLerp = lerp(baseMagnitude,blendMagnitude,mixVal);
  442.  
  443. return colorLerp*magnitudeLerp;
  444. }
  445.  
  446.  
  447. float4 pixelShader (vert2pixel In,uniform float4 lightColor) : COLOR
  448. {
  449. //float3 diffuseVal = tex2D(diffuseMapSampler, In.uv).xyz; //cited out, this line is used for shader testing purposes.
  450.  
  451. float3 HSVcolor = RGB2HSV(targetColor); // converting the target color to Hue Saturation Value instead of RGB.
  452.  
  453. float inten = rockstarLinear(HSVcolor.z); // determine what linear value the value of our desired color maps to.
  454.  
  455. HSVcolor.z = inten;
  456. HSVcolor.y += 0.1; //saturate by 10% since this seem to be the avarage of a universal loss of saturation inside the game.
  457.  
  458.  
  459. float3 RGBcolor = HSV2RGB(HSVcolor); // converting back to RGB to give us our corrected crew color value.
  460.  
  461. //The following attempts to correct for the overly yellow sunlight within GTA V.
  462. 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.
  463. 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
  464.  
  465.  
  466. //******* This is the end of the relevant part *********
  467. //(This is just applying it within the shader)
  468.  
  469. float4 C;
  470. C.rgb = RGBcolor;
  471.  
  472. C.a = 1.0;
  473. return C;
  474. }
  475.  
  476.  
  477. /************* Teqniques. ****************************/
  478.  
  479.  
  480. technique alphaTest
  481. {
  482. pass one
  483. {
  484. VertexShader = compile vs_3_0 vertexShader(light1Pos);
  485. ZEnable = true;
  486. ZWriteEnable = true;
  487. CullMode = none;
  488. AlphaTestEnable = false;
  489. AlphaFunc = less;
  490. AlphaRef = 0x00000001;
  491. AlphaBlendEnable = true;
  492. SrcBlendAlpha = one;
  493. DestBlendAlpha = one;
  494. StencilEnable = True;
  495. PixelShader = compile ps_3_0 pixelShader(light1Color);
  496. }
  497. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement