Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

713 lines
31 KiB

  1. //========== Copyright (c) Valve Corporation, All rights reserved. ==========//
  2. // Use samplers 9+
  3. // Use constanst registers 29+
  4. #ifndef USEPATTERN
  5. #define USEPATTERN 0
  6. #endif
  7. #ifndef GENERATEBASETEXTURE
  8. #define GENERATEBASETEXTURE 0
  9. #endif
  10. #ifndef GENERATENORMAL
  11. #define GENERATENORMAL 0
  12. #endif
  13. #ifndef GENERATEMASKS1
  14. #define GENERATEMASKS1 0
  15. #endif
  16. #ifndef BASEALPHAPHONGMASK
  17. #define BASEALPHAPHONGMASK 0
  18. #endif
  19. #ifndef BASEALPHAENVMASK
  20. #define BASEALPHAENVMASK 0
  21. #endif
  22. #ifndef BUMPALPHAENVMASK
  23. #define BUMPALPHAENVMASK 0
  24. #endif
  25. #ifndef CHEAPFILTERING
  26. #define CHEAPFILTERING 0
  27. #endif
  28. #if ( GENERATENORMAL && ( ( BASEALPHAPHONGMASK == 1 ) && ( BUMPALPHAENVMASK == 1 ) || ( BASEALPHAPHONGMASK == 0 ) ) )
  29. #define NORMALALPHAUSED 1
  30. #else
  31. #define NORMALALPHAUSED 0
  32. #endif
  33. sampler MaterialMaskSampler : register( s9 );
  34. sampler AOSampler : register( s10 );
  35. sampler3D GrungeSampler : register( s11 );
  36. sampler3D DetailSampler : register( s12 );
  37. sampler3D DetailNormalSampler : register( s13 );
  38. #if ( USEPATTERN > 0 )
  39. sampler PatternSampler : register( s14 );
  40. #endif
  41. sampler NoiseSampler : register( s15 );
  42. const float4 g_vDetailScale : register( c108 );
  43. const float4 g_vDetailSpecBoost : register( c32 );
  44. const float4 g_vDamageDetailSpecBoost : register( c100 );
  45. const float4 g_vDetailEnvBoost : register( c34 );
  46. const float4 g_vDamageDetailEnvBoost : register( c35 );
  47. const float4 g_vDetailPhongAlbedoTint : register( c36 );
  48. const float4 g_vDetailWarpIndex : register( c37 );
  49. const float4 g_vDetailMetalness : register( c38 );
  50. const float4 g_vDetailNormalDepth : register( c39 );
  51. const float4 g_vDamageNormalEdgeDepth : register( c40 );
  52. const float4 g_vDamageLevels0_1 : register( c41 );
  53. #define g_vDamageLevels0 g_vDamageLevels0_1.xy
  54. #define g_vDamageLevels1 g_vDamageLevels0_1.zw
  55. const float4 g_vDamageLevels2_3 : register( c42 );
  56. #define g_vDamageLevels2 g_vDamageLevels2_3.xy
  57. #define g_vDamageLevels3 g_vDamageLevels2_3.zw
  58. const float4 g_vPatternTexcoordTransform[2] : register( c43 ); // c43 & c44
  59. const int4 g_vPatternColorIndices : register( c45 );
  60. const float4 g_vWearProgress_PatternParams : register( c46 );
  61. #define g_fWearProgress g_vWearProgress_PatternParams.x
  62. #define g_fPatternDetailInfluence g_vWearProgress_PatternParams.y
  63. #define g_nPatternReplaceIndex int( g_vWearProgress_PatternParams.z )
  64. #define g_fTexelSize g_vWearProgress_PatternParams.w
  65. const float4 g_paletteColor0_paletteColor3r : register( c47 );
  66. #define g_cPaletteColor0 g_paletteColor0_paletteColor3r.rgb
  67. const float4 g_paletteColor1_paletteColor3g : register( c48 );
  68. #define g_cPaletteColor1 g_paletteColor1_paletteColor3g.rgb
  69. const float4 g_paletteColor2_paletteColor3b : register( c49 );
  70. #define g_cPaletteColor2 g_paletteColor2_paletteColor3b.rgb
  71. #define g_cPaletteColor3 float3( g_paletteColor0_paletteColor3r.w, g_paletteColor1_paletteColor3g.w, g_paletteColor2_paletteColor3b.w )
  72. const float4 g_paletteColor4_paletteColor7r : register( c50 );
  73. #define g_cPaletteColor4 g_paletteColor4_paletteColor7r.rgb
  74. const float4 g_paletteColor5_paletteColor7g : register( c51 );
  75. #define g_cPaletteColor5 g_paletteColor5_paletteColor7g.rgb
  76. const float4 g_paletteColor6_paletteColor7b : register( c52 );
  77. #define g_cPaletteColor6 g_paletteColor6_paletteColor7b.rgb
  78. #define g_cPaletteColor7 float3( g_paletteColor4_paletteColor7r.w, g_paletteColor5_paletteColor7g.w, g_paletteColor6_paletteColor7b.w )
  79. const float4 g_vGrungeTexcoordTransform[2] : register( c53 ); // c53 & c54
  80. const float4 g_vWearBleaching : register( c55 );
  81. const float4 g_vWearDetailPhongBoost : register( c56 );
  82. const float4 g_vWearDetailEnvBoost : register( c57 );
  83. const float4 g_vDamageEdgePhongBoost : register( c58 );
  84. const float4 g_vDamageEdgeEnvBoost : register( c59 );
  85. const float4 g_vCurvatureWearBoost : register( c60 );
  86. const float4 g_vCurvatureWearPower : register( c61 );
  87. const float4 g_vDamageDetailSaturation : register( c62 );
  88. const float4 g_vDamageBleaching : register( c63 );
  89. const float4 g_vDetailGrungeFactor : register( c90 ); //64
  90. const float4 g_vPatternParams : register( c91 ); //65
  91. #define g_fPatternPhongFactor g_vPatternParams.x
  92. #define g_fPatternPaintThickness g_vPatternParams.y
  93. #define g_fFlipFixup g_vPatternParams.z
  94. //#define UNUSED g_vPatternParams.zw
  95. const float4 g_vDamageBrightness : register( c92 ); //66
  96. const float4 g_vGrungeMax : register( c93 ); //67
  97. const float4 g_vGrimeSaturation : register( c94 ); //70
  98. const float4 g_vGrimeBrightness : register( c95 ); //72
  99. const float4 g_vGrungeTexcoordRotation[2] : register( c96 );
  100. const float4 g_vPatternTexcoordRotation[2] : register( c98 );
  101. #define g_lum float3( 0.299, 0.587, 0.114 )
  102. #define g_unitVec float3( 0.577f, 0.577f, 0.577f )
  103. // todo: convert to param
  104. #define g_sampleSliceZ float4( 0.0f, 0.375f, 0.625f, 1.0f )
  105. float3 colorize( float3 cVal, float3 cColor, float fBrightness, float fSaturation )
  106. {
  107. if ( fSaturation > 0 )
  108. {
  109. float fLocalSaturation = fSaturation;
  110. float3 cRetVal = normalize(cColor * dot(cColor, g_lum));
  111. fLocalSaturation *= pow(abs(dot(cRetVal - g_unitVec, g_unitVec)), 0.2f);
  112. fLocalSaturation = saturate(fLocalSaturation);
  113. float3 cDiff = normalize(cRetVal - float3(0.577f, 0.577f, 0.577f));
  114. cRetVal = saturate(cDiff * 2.0f + 1.0f);
  115. float3 temp = cRetVal * g_lum;
  116. float fSaturatedBrightness = fBrightness / (temp.r + temp.g + temp.b);
  117. cRetVal = lerp(cVal, cRetVal * fSaturatedBrightness, fLocalSaturation);
  118. return cRetVal;
  119. }
  120. else
  121. {
  122. return lerp( cVal, dot( cVal, g_lum ), -fSaturation );
  123. }
  124. }
  125. float fourWayLerp( float4 fvVal, float3 fvMask )
  126. {
  127. float fVal = lerp( fvVal.x, fvVal.y, fvMask.r );
  128. fVal = lerp( fVal, fvVal.z, fvMask.g );
  129. fVal = lerp( fVal, fvVal.w, fvMask.b );
  130. return fVal;
  131. }
  132. float2 fourWayLerp( float2 fvVal[4], float3 fvMask )
  133. {
  134. float2 fvRetVal = lerp( fvVal[0], fvVal[1], fvMask.r );
  135. fvRetVal = lerp( fvRetVal, fvVal[2], fvMask.g );
  136. fvRetVal = lerp( fvRetVal, fvVal[3], fvMask.b );
  137. return fvRetVal;
  138. }
  139. float3 fourWayLerp( float3 fvVal[4], float3 fvMask )
  140. {
  141. float3 fvRetVal = lerp( fvVal[0], fvVal[1], fvMask.r );
  142. fvRetVal = lerp( fvRetVal, fvVal[2], fvMask.g );
  143. fvRetVal = lerp( fvRetVal, fvVal[3], fvMask.b );
  144. return fvRetVal;
  145. }
  146. float4 fourWayLerp( float4 fvVal[4], float3 fvMask )
  147. {
  148. float4 fvRetVal = lerp( fvVal[0], fvVal[1], fvMask.r );
  149. fvRetVal = lerp( fvRetVal, fvVal[2], fvMask.g );
  150. fvRetVal = lerp( fvRetVal, fvVal[3], fvMask.b );
  151. return fvRetVal;
  152. }
  153. void customizeCharacter( const float2 vTexcoord, inout float4 vBaseTextureSample, inout float4 vNormalSample, inout float4 vMasks1Params )
  154. {
  155. //GENERATEBASETEXTURE
  156. //GENERATENORMAL
  157. //GENERATEMASKS1
  158. #if ( ( GENERATEBASETEXTURE == 0 ) && ( GENERATENORMAL == 0 ) && ( GENERATEMASKS1 == 0 ) )
  159. return;
  160. #endif
  161. float4 vMaterialMaskSample = tex2D( MaterialMaskSampler, vTexcoord );
  162. #if ( ( GENERATEBASETEXTURE == 1 ) || ( GENERATENORMAL == 1 ) )
  163. #if ( CHEAPFILTERING == 0 )
  164. float4 fvSampleOffset[9] = { float4( 0.0f, 0.0f, 0.319727891, 0.0f ),
  165. float4( -1.0f, -1.0f, 0.051020408, 0.075f ),
  166. float4( -1.0f, 0.0f, 0.119047619, 0.175f ),
  167. float4( -1.0f, 1.0f, 0.051020408, 0.075f ),
  168. float4( 0.0f, -1.0f, 0.119047619, 0.175f ),
  169. float4( 0.0f, 1.0f, 0.119047619, 0.175f ),
  170. float4( 1.0f, -1.0f, 0.051020408, 0.075f ),
  171. float4( 1.0f, 0.0f, 0.119047619, 0.175f ),
  172. float4( 1.0f, 1.0f, 0.051020408, 0.075f ) };
  173. #endif
  174. float4 vAOSample = tex2D( AOSampler, vTexcoord );
  175. float fAO = vAOSample.g;
  176. float fWear = vAOSample.b;
  177. float fCurvatureWearPower = fourWayLerp( g_vCurvatureWearPower, vMaterialMaskSample.rgb );
  178. float fCurvature = pow( vAOSample.r, fCurvatureWearPower );
  179. float fDurability = vAOSample.a;
  180. // Grunge
  181. float2 fvGrungeTexcoord = float2( dot( vTexcoord, g_vGrungeTexcoordTransform[0].xy ) + g_vGrungeTexcoordTransform[0].w,
  182. dot( vTexcoord, g_vGrungeTexcoordTransform[1].xy ) + g_vGrungeTexcoordTransform[1].w );
  183. float4 vGrungeSamples[4] = { tex3D( GrungeSampler, float3( fvGrungeTexcoord, g_sampleSliceZ.x ) ),
  184. tex3D( GrungeSampler, float3( fvGrungeTexcoord, g_sampleSliceZ.y ) ),
  185. tex3D( GrungeSampler, float3( fvGrungeTexcoord, g_sampleSliceZ.z ) ),
  186. tex3D( GrungeSampler, float3( fvGrungeTexcoord, g_sampleSliceZ.w ) ) };
  187. float4 cGrunge = fourWayLerp( vGrungeSamples, vMaterialMaskSample.rgb );
  188. // Damage
  189. float2 fvDamageLevelArray[4] = { g_vDamageLevels0, g_vDamageLevels1, g_vDamageLevels2, g_vDamageLevels3 };
  190. float2 fvDamageLevels = fourWayLerp( fvDamageLevelArray, vMaterialMaskSample.rgb );
  191. float fWearInfluence = fCurvature * fDurability;
  192. // Detail
  193. float4 vDetailSamples[4] = { tex3D( DetailSampler, float3( vTexcoord * g_vDetailScale.x, g_sampleSliceZ.x ) ),
  194. tex3D( DetailSampler, float3( vTexcoord * g_vDetailScale.y, g_sampleSliceZ.y ) ),
  195. tex3D( DetailSampler, float3( vTexcoord * g_vDetailScale.z, g_sampleSliceZ.z ) ),
  196. tex3D( DetailSampler, float3( vTexcoord * g_vDetailScale.w, g_sampleSliceZ.w ) ) };
  197. float4 fvFinalDetails = fourWayLerp( vDetailSamples, vMaterialMaskSample.rgb );
  198. float fCurvatureWearBoost = fourWayLerp( g_vCurvatureWearBoost, vMaterialMaskSample.rgb );
  199. float fDamageAmount = fWearInfluence * cGrunge.a;
  200. fDamageAmount = saturate( fDamageAmount + fCurvatureWearBoost * fCurvature );
  201. float fWearAmount = fDamageAmount;
  202. fDamageAmount *= g_fWearProgress;
  203. fWearAmount *= g_fWearProgress * 4.0f;
  204. fDamageAmount = smoothstep( fvDamageLevels.x, fvDamageLevels.y, fDamageAmount );
  205. // wear is a halo around the damage
  206. fWearAmount = smoothstep( fvDamageLevels.x, fvDamageLevels.y, fWearAmount );
  207. fWearAmount = saturate( fWearAmount ) * ( 1.0f - fDamageAmount ) * fvFinalDetails.b;
  208. float fDamageAndWearAmount = saturate( fDamageAmount + fWearAmount );
  209. float fDetail = lerp( fvFinalDetails.g, fvFinalDetails.r, fDamageAndWearAmount );
  210. #endif
  211. #if ( ( GENERATEBASETEXTURE == 1 ) || ( GENERATENORMAL == 1 ) )
  212. float4 cPattern = float4( 0.0f, 0.0f, 0.0f, 1.0f );
  213. float4 cSubColor = float4( 0.0f, 0.0f, 0.0f, 1.0f );
  214. float3 cvPaletteColorsOrig[8] = { g_cPaletteColor0, g_cPaletteColor1, g_cPaletteColor2, g_cPaletteColor3, g_cPaletteColor4, g_cPaletteColor5, g_cPaletteColor6, g_cPaletteColor7 };
  215. #if ( USEPATTERN > 0 )
  216. float2 vPatternTexcoord = float2( dot( vTexcoord, g_vPatternTexcoordTransform[0].xy ) + g_vPatternTexcoordTransform[0].w,
  217. dot( vTexcoord, g_vPatternTexcoordTransform[1].xy ) + g_vPatternTexcoordTransform[1].w );
  218. vPatternTexcoord += ( fDetail * 2.0f - 1.0f ) * g_fTexelSize * g_fPatternDetailInfluence;
  219. vPatternTexcoord.x *= ( vTexcoord.x < 0 ) ? -1.0 : 1.0;
  220. float4 vPatternSample = tex2D( PatternSampler, vPatternTexcoord );
  221. #if ( ( USEPATTERN == 1 ) || ( USEPATTERN == 3 ) )
  222. float3 cvPatternPalette[4] = { cvPaletteColorsOrig[ g_vPatternColorIndices[ 0 ] ],
  223. cvPaletteColorsOrig[ g_vPatternColorIndices[ 1 ] ],
  224. cvPaletteColorsOrig[ g_vPatternColorIndices[ 2 ] ],
  225. cvPaletteColorsOrig[ g_vPatternColorIndices[ 3 ] ] };
  226. cPattern.rgb = fourWayLerp( cvPatternPalette, vPatternSample.rgb );
  227. #else
  228. cPattern.rgb = vPatternSample.rgb;
  229. #endif
  230. cPattern.a = lerp( 1.0f, ( vPatternSample.a - 0.5f ) * 2.0f * g_fPatternPhongFactor + 1.0f, g_fPatternPhongFactor );
  231. #endif
  232. float4 cvPaletteColors[8];
  233. #endif
  234. #if ( GENERATEBASETEXTURE == 1 )
  235. cvPaletteColors[0] = float4( g_cPaletteColor0, 1.0f );
  236. cvPaletteColors[1] = float4( g_cPaletteColor1, 1.0f );
  237. cvPaletteColors[2] = float4( g_cPaletteColor2, 1.0f );
  238. cvPaletteColors[3] = float4( g_cPaletteColor3, 1.0f );
  239. cvPaletteColors[4] = float4( g_cPaletteColor4, 1.0f );
  240. cvPaletteColors[5] = float4( g_cPaletteColor5, 1.0f );
  241. cvPaletteColors[6] = float4( g_cPaletteColor6, 1.0f );
  242. cvPaletteColors[7] = float4( g_cPaletteColor7, 1.0f );
  243. #if ( USEPATTERN > 2 )
  244. cvPaletteColors[0] = lerp( cPattern, float4( g_cPaletteColor0, cPattern.a ), fDamageAmount );
  245. cvPaletteColors[1] = lerp( cPattern, float4( g_cPaletteColor1, cPattern.a ), fDamageAmount );
  246. cvPaletteColors[2] = lerp( cPattern, float4( g_cPaletteColor2, cPattern.a ), fDamageAmount );
  247. cvPaletteColors[3] = lerp( cPattern, float4( g_cPaletteColor3, cPattern.a ), fDamageAmount );
  248. cvPaletteColors[4] = lerp( cPattern, float4( g_cPaletteColor4, cPattern.a ), fDamageAmount );
  249. cvPaletteColors[5] = lerp( cPattern, float4( g_cPaletteColor5, cPattern.a ), fDamageAmount );
  250. cvPaletteColors[6] = lerp( cPattern, float4( g_cPaletteColor6, cPattern.a ), fDamageAmount );
  251. cvPaletteColors[7] = lerp( cPattern, float4( g_cPaletteColor7, cPattern.a ), fDamageAmount );
  252. #else
  253. cvPaletteColors[0] = lerp( cPattern, float4( g_cPaletteColor0, 1.0f ), saturate( fDamageAmount + ( g_nPatternReplaceIndex != 0 ) ) );
  254. cvPaletteColors[1] = lerp( cPattern, float4( g_cPaletteColor1, 1.0f ), saturate( fDamageAmount + ( g_nPatternReplaceIndex != 1 ) ) );
  255. cvPaletteColors[2] = lerp( cPattern, float4( g_cPaletteColor2, 1.0f ), saturate( fDamageAmount + ( g_nPatternReplaceIndex != 2 ) ) );
  256. cvPaletteColors[3] = lerp( cPattern, float4( g_cPaletteColor3, 1.0f ), saturate( fDamageAmount + ( g_nPatternReplaceIndex != 3 ) ) );
  257. cvPaletteColors[4] = lerp( cPattern, float4( g_cPaletteColor4, 1.0f ), saturate( fDamageAmount + ( g_nPatternReplaceIndex != 4 ) ) );
  258. cvPaletteColors[5] = lerp( cPattern, float4( g_cPaletteColor5, 1.0f ), saturate( fDamageAmount + ( g_nPatternReplaceIndex != 5 ) ) );
  259. cvPaletteColors[6] = lerp( cPattern, float4( g_cPaletteColor6, 1.0f ), saturate( fDamageAmount + ( g_nPatternReplaceIndex != 6 ) ) );
  260. cvPaletteColors[7] = lerp( cPattern, float4( g_cPaletteColor7, 1.0f ), saturate( fDamageAmount + ( g_nPatternReplaceIndex != 7 ) ) );
  261. #endif
  262. #endif
  263. #if ( ( GENERATEBASETEXTURE == 0 ) && ( GENERATENORMAL == 1 ) )
  264. cvPaletteColors[0] = float4( 1.0f, 1.0f, 1.0f, 1.0f );
  265. cvPaletteColors[1] = float4( 1.0f, 1.0f, 1.0f, 1.0f );
  266. cvPaletteColors[2] = float4(1.0f, 1.0f, 1.0f, 1.0f);
  267. cvPaletteColors[3] = float4(1.0f, 1.0f, 1.0f, 1.0f);
  268. cvPaletteColors[4] = float4(1.0f, 1.0f, 1.0f, 1.0f);
  269. cvPaletteColors[5] = float4(1.0f, 1.0f, 1.0f, 1.0f);
  270. cvPaletteColors[6] = float4(1.0f, 1.0f, 1.0f, 1.0f);
  271. cvPaletteColors[7] = float4(1.0f, 1.0f, 1.0f, 1.0f);
  272. #if ( USEPATTERN > 2 )
  273. cvPaletteColors[0].a = cPattern.a;
  274. cvPaletteColors[1].a = cPattern.a;
  275. cvPaletteColors[2].a = cPattern.a;
  276. cvPaletteColors[3].a = cPattern.a;
  277. cvPaletteColors[4].a = cPattern.a;
  278. cvPaletteColors[5].a = cPattern.a;
  279. cvPaletteColors[6].a = cPattern.a;
  280. cvPaletteColors[7].a = cPattern.a;
  281. #else
  282. cvPaletteColors[0].a = lerp( cPattern.a, 1.0f, saturate( fDamageAmount + ( g_nPatternReplaceIndex != 0 ) ) );
  283. cvPaletteColors[1].a = lerp( cPattern.a, 1.0f, saturate( fDamageAmount + ( g_nPatternReplaceIndex != 1 ) ) );
  284. cvPaletteColors[2].a = lerp( cPattern.a, 1.0f, saturate( fDamageAmount + ( g_nPatternReplaceIndex != 2 ) ) );
  285. cvPaletteColors[3].a = lerp( cPattern.a, 1.0f, saturate( fDamageAmount + ( g_nPatternReplaceIndex != 3 ) ) );
  286. cvPaletteColors[4].a = lerp( cPattern.a, 1.0f, saturate( fDamageAmount + ( g_nPatternReplaceIndex != 4 ) ) );
  287. cvPaletteColors[5].a = lerp( cPattern.a, 1.0f, saturate( fDamageAmount + ( g_nPatternReplaceIndex != 5 ) ) );
  288. cvPaletteColors[6].a = lerp( cPattern.a, 1.0f, saturate( fDamageAmount + ( g_nPatternReplaceIndex != 6 ) ) );
  289. cvPaletteColors[7].a = lerp( cPattern.a, 1.0f, saturate( fDamageAmount + ( g_nPatternReplaceIndex != 7 ) ) );
  290. #endif
  291. #endif
  292. #if ( ( GENERATEBASETEXTURE == 1 ) || ( GENERATENORMAL == 1 ) )
  293. //switching to float4[2] to save on temp registers
  294. //float fvSubColorMask[7] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
  295. float4 fvSubColorMask[2] = { float4( 0, 0, 0, 0 ), float4( 0, 0, 0, 0 ) };
  296. #if ( CHEAPFILTERING == 0 )
  297. for ( int i = 0; i < 9; i++ )
  298. {
  299. float fSubColorMask = tex2D( MaterialMaskSampler, vTexcoord + fvSampleOffset[i].xy * g_fTexelSize ).a;
  300. for ( int j = 0; j < 2; j++ )
  301. for ( int k = 0; k < 4; k++ )
  302. {
  303. if ( ( j * 4 + k ) == ( floor( fSubColorMask * 8 ) - 1 ) )
  304. fvSubColorMask[j][k] += fvSampleOffset[i].z;
  305. }
  306. }
  307. // fill in under the blurred mask
  308. for ( i = 0; i < 2; i++ )
  309. for ( int j = 0; j < 4; j++ )
  310. for ( int k = 0; k <= i; k++ )
  311. {
  312. int maxl = ( i == k ) ? j : 4;
  313. for ( int l = 0; l < maxl; l++ )
  314. fvSubColorMask[k][l] = saturate( fvSubColorMask[k][l] + ( fvSubColorMask[k][l] > 0 ) * ( fvSubColorMask[i][j] > 0 ) );
  315. }
  316. #else
  317. float fSubColorMask = tex2D( MaterialMaskSampler, vTexcoord ).a;
  318. for ( int i = 0; i < 2; i++ )
  319. for ( int j = 0; j < 4; j++ )
  320. {
  321. fvSubColorMask[i][j] = ( ( i * 4 + j ) == ( floor( fSubColorMask * 8 ) - 1 ) );
  322. }
  323. #endif
  324. #endif
  325. #if ( GENERATEBASETEXTURE == 1)
  326. cSubColor = lerp( cvPaletteColors[0], cvPaletteColors[1], fvSubColorMask[0][0] );
  327. cSubColor = lerp( cSubColor, cvPaletteColors[2], fvSubColorMask[0][1] );
  328. cSubColor = lerp( cSubColor, cvPaletteColors[3], fvSubColorMask[0][2] );
  329. cSubColor = lerp( cSubColor, cvPaletteColors[4], fvSubColorMask[0][3] );
  330. cSubColor = lerp( cSubColor, cvPaletteColors[5], fvSubColorMask[1][0] );
  331. cSubColor = lerp( cSubColor, cvPaletteColors[6], fvSubColorMask[1][1] );
  332. cSubColor = lerp( cSubColor, cvPaletteColors[7], fvSubColorMask[1][2] );
  333. #endif
  334. #if ( ( GENERATEBASETEXTURE == 1 ) || ( GENERATENORMAL == 1 ) )
  335. float fPatternMask = ( 1.0f - fDamageAmount );
  336. #if ( USEPATTERN == 1 )
  337. if ( g_nPatternReplaceIndex == 0 )
  338. {
  339. fPatternMask *= 1.0f - fvSubColorMask[0][0];
  340. fPatternMask *= 1.0f - fvSubColorMask[0][1];
  341. fPatternMask *= 1.0f - fvSubColorMask[0][2];
  342. fPatternMask *= 1.0f - fvSubColorMask[0][3];
  343. fPatternMask *= 1.0f - fvSubColorMask[1][0];
  344. fPatternMask *= 1.0f - fvSubColorMask[1][1];
  345. fPatternMask *= 1.0f - fvSubColorMask[1][2];
  346. }
  347. else
  348. {
  349. fPatternMask *= fvSubColorMask[ g_nPatternReplaceIndex > 4 ][ g_nPatternReplaceIndex > 4 ? g_nPatternReplaceIndex - 5 : g_nPatternReplaceIndex - 1 ];
  350. }
  351. #endif
  352. float fPaintThickness = 0.0f;
  353. #if ( ( USEPATTERN == 1 ) || ( USEPATTERN == 3 ) )
  354. fPaintThickness = ( vPatternSample.r + vPatternSample.g + vPatternSample.b ) * g_fPatternPaintThickness;
  355. if ( g_fPatternPaintThickness > 0 )
  356. {
  357. float4 vPatternShadowSample = tex2Dbias( PatternSampler, float4( vPatternTexcoord, 0.0f, 0.5f + 0.1f * g_fPatternPaintThickness ) );
  358. float fPaintShadowPower = g_fPatternPaintThickness;
  359. float fPaintShadow = lerp( pow( 1.0f - vPatternShadowSample.r, fPaintShadowPower ), 1.0f, vPatternSample.r );
  360. fPaintShadow *= lerp( pow( 1.0f - vPatternShadowSample.g, fPaintShadowPower ), 1.0f, vPatternSample.g );
  361. fPaintShadow *= lerp( pow( 1.0f - vPatternShadowSample.b, fPaintShadowPower ), 1.0f, vPatternSample.b );
  362. fAO *= lerp( 1.0f, fPaintShadow, fPatternMask );
  363. }
  364. fPatternMask *= saturate( fPaintThickness );
  365. fvFinalDetails.rgb = lerp( fvFinalDetails.rgb, float3( 0.5f, 0.5f, 0.0f ), saturate( fPaintThickness ) * fPatternMask );
  366. fDetail = lerp( fDetail, 1.0f, saturate( fPaintThickness ) * fPatternMask );
  367. #endif
  368. #endif
  369. #if ( GENERATEBASETEXTURE == 1 )
  370. float3 cFinalColor = cSubColor.rgb;
  371. float fDamageDetailSaturation = fourWayLerp( g_vDamageDetailSaturation, vMaterialMaskSample.rgb );
  372. float fSubColorLum = dot( g_lum, cSubColor.rgb );
  373. // Apply Curvature
  374. float fDetailCurvatureClean = ( 1.0f - abs( ddx( fvFinalDetails.g * fCurvature ) ) ) * ( 1.0f - abs( ddy( fvFinalDetails.g * fCurvature ) ) );
  375. fDetailCurvatureClean *= saturate( abs( ddx( fvFinalDetails.g * fCurvature ) ) + abs( ddy ( fvFinalDetails.g * fCurvature ) ) );
  376. float fDetailCurvatureDamaged = ( 1.0f - abs( ddx( fvFinalDetails.r * fCurvature ) ) ) * ( 1.0f - abs( ddy( fvFinalDetails.r * fCurvature ) ) );
  377. fDetailCurvatureDamaged *= saturate( abs( ddx( fvFinalDetails.r * fCurvature ) ) + abs( ddy ( fvFinalDetails.r * fCurvature ) ) );
  378. float fDetailCurvature = lerp( fDetailCurvatureClean, fDetailCurvatureDamaged, fDamageAmount );
  379. fDetailCurvature *= 1.0f - saturate( abs( ddx( vMaterialMaskSample.r + vMaterialMaskSample.g + vMaterialMaskSample.b ) ) );
  380. fDetailCurvature *= 1.0f - saturate( abs( ddy( vMaterialMaskSample.r + vMaterialMaskSample.g + vMaterialMaskSample.b ) ) );
  381. // use a little curvature to exaggerate form
  382. cFinalColor = lerp( cFinalColor, cFinalColor * fCurvature * 2.0f, 0.5f );
  383. // lighten sharp edges a little to highlight them
  384. cFinalColor = lerp( cFinalColor, cFinalColor + cFinalColor * fDetailCurvature, 0.5f );
  385. // Bleaching
  386. float fWearBleaching = fourWayLerp( g_vWearBleaching, vMaterialMaskSample.rgb );
  387. float fDamageBleaching = fourWayLerp( g_vDamageBleaching, vMaterialMaskSample.rgb );
  388. // Grime
  389. float fGrimeBrightnessAdjustment = fourWayLerp( g_vGrimeBrightness, vMaterialMaskSample.rgb );
  390. float fGrimeBrightness = dot( cGrunge.rgb, g_lum );
  391. float fGrimeDetailSaturation = fourWayLerp( g_vGrimeSaturation, vMaterialMaskSample.rgb );
  392. float3 cGrime = colorize( cGrunge.rgb, cGrunge.rgb, fGrimeBrightness, fGrimeDetailSaturation );
  393. cGrime *= ( 1.0f + fGrimeBrightnessAdjustment );
  394. float fBleaching = lerp( g_fWearProgress * fWear * fWearBleaching, fDamageBleaching, fDamageAndWearAmount );
  395. // Add some grunge even to pristine materials
  396. float fDetailGrungeFactor = fourWayLerp( g_vDetailGrungeFactor, vMaterialMaskSample.rgb );
  397. fDetailGrungeFactor = fDetailGrungeFactor * ( 1.0f + g_fWearProgress * fDetailGrungeFactor );
  398. // Desaturate grunge somewhat at low opacities
  399. float3 fColorVariation = lerp( cFinalColor, dot( cFinalColor, g_lum ), saturate( 1.0f - fDetailGrungeFactor ) );
  400. float3 cColorVariation = lerp( cFinalColor, cFinalColor * cGrunge.rgb * 4.0f, fDetailGrungeFactor * ( 1.0f - fDamageAndWearAmount ) );
  401. cFinalColor = lerp( cColorVariation, cGrime * fDetail, fBleaching );
  402. float fBrightnessAdjustment = fourWayLerp( g_vDamageBrightness, vMaterialMaskSample.rgb );
  403. float fBrightness = dot( cFinalColor, g_lum );
  404. float3 cFinalSaturation = colorize( cFinalColor, cSubColor.rgb, fBrightness, fDamageDetailSaturation );
  405. cFinalColor = lerp( cFinalColor, cFinalSaturation * ( 1.0f + fBrightnessAdjustment ), fDamageAndWearAmount );
  406. // Grunge
  407. float fGrungeAmount = smoothstep( 0.45f, 0.75f, ( 1.0f - vAOSample.r * vAOSample.g * vAOSample.g ) * g_fWearProgress ) * ( 1.0f - fSubColorLum * 0.5f );
  408. float fGrungeMax = fourWayLerp( g_vGrungeMax, vMaterialMaskSample.rgb );
  409. fGrungeAmount *= fGrungeMax;
  410. cFinalColor = lerp( cFinalColor, cGrunge.rgb * cFinalColor, fGrungeAmount );
  411. // AO
  412. cFinalColor = lerp( cFinalColor * cFinalColor * fAO, cFinalColor, fAO );
  413. cFinalColor = lerp( cFinalColor * cFinalColor * fDetail * 2.0f, cFinalColor, fDetail );
  414. fBrightness = dot( cFinalColor, g_lum );
  415. float3 cMottleColor1 = float3( 0.6f, 1.0f, 0.0f );
  416. float3 cMottleColor2 = float3( 0.2f, 0.6f, 1.0f );
  417. if ( ( cFinalColor.r > cFinalColor.g ) && ( cFinalColor.r > cFinalColor.b ) )
  418. {
  419. cMottleColor1 += cFinalColor.brg;
  420. cMottleColor2 += cFinalColor.bgr;
  421. }
  422. else if ( ( cFinalColor.g > cFinalColor.r ) && ( cFinalColor.g > cFinalColor.b ) )
  423. {
  424. cMottleColor1 += cFinalColor.brg;
  425. cMottleColor2 += cFinalColor.gbr;
  426. }
  427. float fSaturation = pow( ( 1.0f - fSubColorLum ), 3.5f ) * 0.3f;
  428. fSaturation += length( cFinalColor - fBrightness.xxx ) * 0.15f + 0.05f;
  429. float3 fvMottle = tex2D( NoiseSampler, vTexcoord * 2.0f ).rgb;
  430. float fAOMottle = pow( vAOSample.g, 8.0f );
  431. fvMottle.r = saturate( fAOMottle * fvMottle.r );
  432. fvMottle.b = saturate( fvMottle.b * ( 0.5f + fAOMottle * 0.5f ) );
  433. cFinalColor = lerp( lerp( colorize( cFinalColor, cMottleColor2, fBrightness, fSaturation ),
  434. colorize( cFinalColor, cMottleColor1, fBrightness, fSaturation ), fvMottle.r ),
  435. cFinalColor, fvMottle.b );
  436. cFinalColor = saturate( cFinalColor );
  437. vBaseTextureSample.rgb = cFinalColor;
  438. #endif
  439. #if ( ( GENERATENORMAL == 1 ) || ( ( GENERATEBASETEXTURE == 1 ) && ( ( BASEALPHAPHONGMASK == 1) || ( BASEALPHAENVMASK == 1 ) ) ) )
  440. float fDamageNormalEdgeDepth = fourWayLerp( g_vDamageNormalEdgeDepth, vMaterialMaskSample.rgb );
  441. float2 fvDamageEdgeNormal = float2( 0.0f, 0.0f );
  442. float2 fPaintModifier = 1.0f;
  443. #if ( ( USEPATTERN == 1 ) || ( USEPATTERN == 3 ) )
  444. fPaintModifier = 1.0f + fPatternMask * g_fPatternPaintThickness;
  445. #endif
  446. float fDamageEdgeMask = 0.0f;
  447. for ( int o = 0; o < 2; o++ )
  448. {
  449. for ( int n = 0; n < 2; n++ )
  450. {
  451. float4 fvGrungeSamples = 0;
  452. float2 fvSampleOffset = float2( o * 2 - 1, n * 2 - 1 );
  453. float fGrungeSample = 0;
  454. float2 vSampleTexcoord = fvGrungeTexcoord + fvSampleOffset.xy * g_fTexelSize * fDamageNormalEdgeDepth * fPaintModifier;
  455. fvGrungeSamples.x = tex3D( GrungeSampler, float3( vSampleTexcoord, g_sampleSliceZ.x ) ).a;
  456. fvGrungeSamples.y = tex3D( GrungeSampler, float3( vSampleTexcoord, g_sampleSliceZ.y ) ).a;
  457. fvGrungeSamples.z = tex3D( GrungeSampler, float3( vSampleTexcoord, g_sampleSliceZ.z ) ).a;
  458. fvGrungeSamples.w = tex3D( GrungeSampler, float3( vSampleTexcoord, g_sampleSliceZ.w ) ).a;
  459. fGrungeSample = fourWayLerp( fvGrungeSamples, vMaterialMaskSample.rgb );
  460. fGrungeSample *= fWearInfluence;
  461. fGrungeSample = saturate( fGrungeSample + fCurvatureWearBoost * fCurvature );
  462. fGrungeSample *= g_fWearProgress;
  463. fGrungeSample = smoothstep( fvDamageLevels.x, fvDamageLevels.y, fGrungeSample );
  464. fvDamageEdgeNormal.xy -= ( fDamageAmount - fGrungeSample ) * fvSampleOffset;
  465. fDamageEdgeMask += abs( fDamageAmount - fGrungeSample );
  466. }
  467. }
  468. fDamageEdgeMask = fDamageEdgeMask * 0.25f;
  469. #endif
  470. #if ( GENERATENORMAL == 1 )
  471. fvDamageEdgeNormal = float2( dot( fvDamageEdgeNormal, g_vGrungeTexcoordRotation[0].xy ),
  472. dot( fvDamageEdgeNormal, g_vGrungeTexcoordRotation[1].xy ) );
  473. float3 fvFinalNormal = vNormalSample * 2.0f - 1.0f;
  474. // Detail normals
  475. float4 vNormalSamples[4] = { tex3D( DetailNormalSampler, float3( vTexcoord.xy * g_vDetailScale.x, g_sampleSliceZ.x ) ),
  476. tex3D( DetailNormalSampler, float3( vTexcoord.xy * g_vDetailScale.y, g_sampleSliceZ.y ) ),
  477. tex3D( DetailNormalSampler, float3( vTexcoord.xy * g_vDetailScale.z, g_sampleSliceZ.z ) ),
  478. tex3D( DetailNormalSampler, float3( vTexcoord.xy * g_vDetailScale.w, g_sampleSliceZ.w ) ) };
  479. float4 fvDetailNormal = fourWayLerp( vNormalSamples, vMaterialMaskSample.rgb );
  480. float2 fvDetailNormalDamage = fvDetailNormal.zw * 2.0f - 1.0f;
  481. float2 fvDetailNormalClean = fvDetailNormal.xy * 2.0f - 1.0f;
  482. float fDetailNormalDepth = fourWayLerp( g_vDetailNormalDepth, vMaterialMaskSample.rgb );
  483. fvDetailNormal.xy = lerp( fvDetailNormalClean, fvDetailNormalDamage, fDamageAmount );
  484. fvDetailNormal.xy *= fDetailNormalDepth;
  485. float2 fvPaintEdgeNormal = float2( 0.0f, 0.0f );
  486. #if ( ( USEPATTERN == 1 ) || ( USEPATTERN == 3 ) )
  487. for ( int m = 0; m < 2; m++ )
  488. {
  489. for ( int n = 0; n < 2; n++ )
  490. {
  491. float2 fvSampleOffset = float2( m * 2 - 1, n * 2 - 1 );
  492. float3 fvPaintSample = tex2D( PatternSampler, vPatternTexcoord + fvSampleOffset.xy * g_fTexelSize * g_fPatternPaintThickness * 2.0f ).rgb;
  493. float fPaintSample = ( fvPaintSample.r + fvPaintSample.g + fvPaintSample.b );// * ( 1.0f - fDamageAmount );
  494. fvPaintEdgeNormal += ( fPaintThickness - fPaintSample ) * fvSampleOffset;
  495. }
  496. }
  497. fvPaintEdgeNormal = float2( dot( fvPaintEdgeNormal, g_vPatternTexcoordRotation[0].xy ),
  498. dot( fvPaintEdgeNormal, g_vPatternTexcoordRotation[1].xy ) );
  499. fvPaintEdgeNormal.x *= g_fFlipFixup;
  500. if ( vTexcoord.x < 0 )
  501. {
  502. fvPaintEdgeNormal.x *= -1;
  503. }
  504. fvDetailNormal.xy = lerp( fvDetailNormal.xy, float2( 0, 0 ), min( pow( saturate( fPatternMask * g_fPatternPaintThickness ), 0.5f ), 0.9f ) );
  505. fvPaintEdgeNormal *= fPatternMask * g_fPatternPaintThickness;
  506. fDamageNormalEdgeDepth += fPatternMask * g_fPatternPaintThickness;
  507. #endif
  508. // Detail normal edges
  509. fvDamageEdgeNormal.xy *= fDamageNormalEdgeDepth /** ( 1.0f - fDamageAmount * fDamageAmount )*/;
  510. float2 fvEdgeNormals = lerp( fvPaintEdgeNormal.xy, fvDamageEdgeNormal.xy, fDamageAmount );
  511. vNormalSample.xyz = fvFinalNormal.xyz;
  512. vNormalSample.xy += fvDetailNormal;
  513. vNormalSample.xy += fvEdgeNormals;
  514. vNormalSample.xyz = normalize( vNormalSample.xyz ) * 0.5f + 0.5f;
  515. #endif
  516. #if ( ( ( GENERATEBASETEXTURE == 1 ) && ( ( BASEALPHAPHONGMASK == 1 ) || ( BASEALPHAENVMASK == 1 ) ) ) || ( ( GENERATENORMAL == 1 ) && ( ( BASEALPHAPHONGMASK == 0 ) || ( BUMPALPHAENVMASK == 1 ) ) ) )
  517. float fDetailGrungePhongFactor = fourWayLerp( g_vDetailGrungeFactor, vMaterialMaskSample.rgb );
  518. fDetailGrungePhongFactor = saturate( g_fWearProgress + fDetailGrungePhongFactor );
  519. fDetailGrungePhongFactor = lerp( 1.0f, dot( cGrunge.rgb, g_lum ), fDetailGrungePhongFactor );
  520. #endif
  521. #if ( ( ( GENERATEBASETEXTURE == 1 ) && ( BASEALPHAPHONGMASK == 1 ) ) || ( ( GENERATENORMAL == 1 ) && ( BASEALPHAPHONGMASK == 0 ) ) )
  522. float fWearDetailPhongBoost = fourWayLerp( g_vWearDetailPhongBoost, vMaterialMaskSample.rgb );
  523. float fDamageEdgePhongBoost = fourWayLerp( g_vDamageEdgePhongBoost, vMaterialMaskSample.rgb );
  524. float fDetailSpec = fourWayLerp( g_vDetailSpecBoost, vMaterialMaskSample.rgb ) * fvFinalDetails.a;
  525. float fDamageDetailSpec = fourWayLerp( g_vDamageDetailSpecBoost, vMaterialMaskSample.rgb ) * fvFinalDetails.r;
  526. fDetailSpec = lerp( fDetailSpec, fDamageDetailSpec, fDamageAmount );
  527. fDetailSpec *= fDetailGrungePhongFactor;
  528. fDetailSpec = lerp( fDetailSpec, fDetailSpec * fWearDetailPhongBoost, fWearAmount );
  529. fDetailSpec = lerp( fDetailSpec, fDetailSpec * fDamageEdgePhongBoost, fDamageEdgeMask );
  530. fDetailSpec *= cSubColor.a;
  531. fDetailSpec = saturate( fDetailSpec );
  532. #if ( ( GENERATEBASETEXTURE == 1) && ( BASEALPHAPHONGMASK == 1 ) )
  533. vBaseTextureSample.a = fAO * fAO * fDetailSpec;
  534. #else
  535. vNormalSample.a = fAO * fAO * fDetailSpec;
  536. #endif
  537. #endif
  538. #if ( ( ( GENERATEBASETEXTURE == 1 ) && ( BASEALPHAENVMASK == 1) && ( BASEALPHAPHONGMASK == 0 ) ) || ( ( GENERATENORMAL == 1 ) && ( BASEALPHAPHONGMASK == 1 ) && ( BUMPALPHAENVMASK == 1 ) ) )
  539. float fWearDetailEnvBoost = fourWayLerp( g_vWearDetailEnvBoost, vMaterialMaskSample.rgb );
  540. float fDamageEdgeEnvBoost = fourWayLerp( g_vDamageEdgeEnvBoost, vMaterialMaskSample.rgb );
  541. fWearDetailEnvBoost = abs( fWearDetailEnvBoost ) * ( fWearDetailEnvBoost < 0 ? 1.0f - fWear * fvFinalDetails.b : fWear * fvFinalDetails.b );
  542. float fDetailEnv = fourWayLerp( g_vDetailEnvBoost, vMaterialMaskSample.rgb ) * fvFinalDetails.a;
  543. float fDamageDetailEnv = fourWayLerp( g_vDamageDetailEnvBoost, vMaterialMaskSample.rgb ) * fvFinalDetails.r;
  544. fDetailEnv = lerp( fDetailEnv, fDamageDetailEnv, fDamageAmount );
  545. fDetailEnv *= fDetailGrungePhongFactor;
  546. fDetailEnv = lerp( fDetailEnv, fDetailEnv * fWearDetailEnvBoost, fWearAmount );
  547. fDetailEnv = lerp( fDetailEnv, fDetailEnv * fDamageEdgeEnvBoost, fDamageEdgeMask );
  548. fDetailEnv *= cSubColor.a;
  549. fDetailEnv = saturate( fDetailEnv );
  550. #if ( ( GENERATEBASETEXTURE == 1) && ( BASEALPHAENVMASK == 1) )
  551. vBaseTextureSample.a = fAO * fAO * fDetailEnv;
  552. #else
  553. vNormalSample.a = fAO * fAO * fDetailEnv;
  554. #endif
  555. #endif
  556. #if ( GENERATEMASKS1 == 1 )
  557. //Phong Albedo Tint
  558. float fPhongAlbedoTint = fourWayLerp( g_vDetailPhongAlbedoTint, vMaterialMaskSample.rgb );
  559. // Material ID
  560. float fWarpIndex = fourWayLerp( g_vDetailWarpIndex, vMaterialMaskSample.rgb );
  561. // Metalness
  562. float fMetalness = fourWayLerp( g_vDetailMetalness, vMaterialMaskSample.rgb );
  563. // Masks 1
  564. vMasks1Params.gba = float3( fPhongAlbedoTint, fMetalness, fWarpIndex );
  565. #endif
  566. }