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.

553 lines
23 KiB

  1. //========== Copyright (c) Valve Corporation, All rights reserved. ==========//
  2. // STATIC: "PAINTSTYLE" "0..9"
  3. // STATIC: "EXPONENTMODE" "0..1"
  4. // STATIC: "CHEAPMODE" "0..1"
  5. // STATIC: "PREVIEW" "0..1" [ps30]
  6. // STATIC: "PREVIEWPHONGALBEDOTINT" "0..1" [ps30]
  7. // STATIC: "PHONGALBEDOFACTORMODE" "0..1"
  8. // DYNAMIC: "NUM_LIGHTS" "0..4" [ps30]
  9. // SKIP: ( $PAINTSTYLE == 0 )
  10. // SKIP: ( ( $CHEAPMODE == 1 ) && !( ( $PAINTSTYLE == 3 ) || ( $PAINTSTYLE == 6 ) ) )
  11. // SKIP: ( ( $EXPONENTMODE == 1 ) && ( $CHEAPMODE == 1 ) )
  12. // SKIP: ( ( $NUM_LIGHTS != 0 ) && ( $PREVIEW == 0 ) )
  13. // SKIP: ( ( $PREVIEW == 0 ) && ( $PREVIEWPHONGALBEDOTINT == 1 ) )
  14. // SKIP: ( ( $PREVIEW == 1 ) && ( $EXPONENTMODE == 1 ) )
  15. #include "common_ps_fxc.h"
  16. #include "common_vertexlitgeneric_dx9.h"
  17. #include "shader_constant_register_map.h"
  18. // SAMPLERS
  19. sampler AOSampler : register( s0 );
  20. sampler ScratchesSampler : register( s1 );
  21. #if ( ( EXPONENTMODE == 1 ) || ( PAINTSTYLE == 4 ) || ( PAINTSTYLE == 5 ) || ( PAINTSTYLE == 6 ) || ( PAINTSTYLE == 8 ) || ( PAINTSTYLE == 9 ) || ( PREVIEW == 1 ) )
  22. sampler ExponentSampler : register( s2 );
  23. #endif
  24. #if ( EXPONENTMODE == 0 )
  25. sampler BaseSampler : register( s3 );
  26. sampler GrungeSampler : register( s5 );
  27. #if ( ( PAINTSTYLE == 3 ) || ( PAINTSTYLE == 6 ) )
  28. sampler NormalsSampler : register( s6 );
  29. sampler OSPosSampler : register( s7 );
  30. #endif
  31. #endif
  32. #if ( ( PAINTSTYLE == 2 ) || ( PAINTSTYLE == 5 ) || ( PAINTSTYLE == 7 ) || ( PAINTSTYLE == 8 ) || ( PAINTSTYLE == 9 ) || ( ( EXPONENTMODE == 0 ) && ( PAINTSTYLE == 3 ) || ( PAINTSTYLE == 6 ) ) )
  33. sampler PatternSampler : register( s8 );
  34. #endif
  35. sampler MasksSampler : register( s4 );
  36. // SHADER CONSTANTS
  37. const float4 g_cCamo0_camo3r : register( c0 );
  38. #define g_cCamo0 g_cCamo0_camo3r.rgb
  39. const float4 g_cCamo1_camo3g : register( c1 );
  40. #define g_cCamo1 g_cCamo1_camo3g.rgb
  41. const float4 g_cCamo2_camo3b : register( c2 );
  42. #define g_cCamo2 g_cCamo2_camo3b.rgb
  43. #define g_cCamo3 float3( g_cCamo0_camo3r.a, g_cCamo1_camo3g.a, g_cCamo2_camo3b.a )
  44. const float4 g_fvPhongSettings_wear : register( c3 );
  45. #define g_flPhongAlbedoFactor g_fvPhongSettings_wear.x
  46. #define g_flPaintExponent g_fvPhongSettings_wear.y
  47. #define g_flPaintPhongIntensity g_fvPhongSettings_wear.z
  48. #define g_flWearAmt g_fvPhongSettings_wear.w
  49. #if ( ( PAINTSTYLE == 3 ) || ( PAINTSTYLE == 6 ) )
  50. const float4 g_patternTexCoordTransform[2] : register( c10 ); // 10 & 11
  51. #endif
  52. #if ( PREVIEW == 1 )
  53. sampler NormalizeSampler : register( s9 );
  54. const float4 g_EyePos_unused : register( c12 );
  55. #define g_EyePos g_EyePos_unused.xyz
  56. //#define UNUSED g_EyePos_unused.w
  57. const float4 g_PreviewPhongFresnelRanges_unused : register( c13 );
  58. #define g_PreviewPhongFresnelRanges g_PreviewPhongFresnelRanges_unused.xyz
  59. //#define UNUSED g_PreviewPhongFresnelRanges_unused.w
  60. const float4 g_PreviewPhongBoosts: register( c14 );
  61. #define g_PreviewPhongAlbedoBoost g_PreviewPhongBoosts.x
  62. #define g_PreviewPhongBoost g_PreviewPhongBoosts.y
  63. #define g_PreviewPatternScale g_PreviewPhongBoosts.z
  64. //#define UNUSED g_PreviewPhongBoosts.w
  65. const float3 g_cAmbientCube[6] : register( PSREG_AMBIENT_CUBE ); // 4 through 9
  66. PixelShaderLightInfo cLightInfo[3] : register( PSREG_LIGHT_INFO_ARRAY ); // 20 through 25
  67. #endif
  68. #define g_flBlendYPow 7
  69. #define g_flBlendZPow 7
  70. #define g_flAnodizedBaseExponent 0.004f
  71. #define g_flAnodizedBasePhongIntensity 1.0
  72. #define g_cAnodizedBase float3( 0.05f, 0.05f, 0.05f )
  73. struct PS_INPUT
  74. {
  75. float4 vBaseUV_PatternUV : TEXCOORD0;
  76. float4 vWearUV_GrungeUV : TEXCOORD1;
  77. #if ( PREVIEW == 1 )
  78. float4 lightAtten : TEXCOORD2;
  79. float3 worldPos : TEXCOORD3;
  80. float3 vWorldNormal : TEXCOORD4;
  81. #endif
  82. };
  83. float4_color_return_type main( PS_INPUT i ) : COLOR
  84. {
  85. float4 cOut = float4( 0.0f, 0.0f, 0.0f, 1.0f );
  86. float4 fvAoSrc = tex2D( AOSampler, i.vBaseUV_PatternUV.xy );
  87. cOut = float4( i.vBaseUV_PatternUV.xy, 0, 1 );
  88. float flCavity = fvAoSrc.r;
  89. // part masks allow different parts of the gun to be treated with different colors or styles
  90. float4 fvMasks = tex2D( MasksSampler, i.vBaseUV_PatternUV.xy );
  91. float flPaintBlend = fvAoSrc.a;
  92. float flPaintWear = tex2D( ScratchesSampler, i.vWearUV_GrungeUV.xy ).g;
  93. #if ( PAINTSTYLE != 8 )
  94. flPaintBlend += flPaintWear * flCavity;
  95. flPaintBlend *= g_flWearAmt * 6.0f + 1.0f;
  96. #if ( ( PAINTSTYLE == 2 ) || ( PAINTSTYLE == 5 ) || ( PAINTSTYLE == 7 ) || ( PAINTSTYLE == 9 ) ) // Paint patterns and durability
  97. float4 fvPattern = tex2D( PatternSampler, i.vBaseUV_PatternUV.zw );
  98. float flCuttableArea = 1.0f;
  99. #if ( ( PAINTSTYLE == 2 ) || ( PAINTSTYLE == 5 ) )
  100. flCuttableArea = 1.0f - saturate( fvMasks.g + fvMasks.b );
  101. #endif
  102. // cut through
  103. flPaintBlend += smoothstep( 0.5f, 0.6f, fvPattern.a ) * smoothstep( 1.0f, 0.9f, fvPattern.a );
  104. #if ( PAINTSTYLE == 5 )
  105. // rescale the alpha to represent exponent in the range of 0-255 and let the cutout mask area fall off the top end
  106. fvPattern.a = saturate( fvPattern.a * 2.0f );
  107. #elif ( PAINTSTYLE == 9 )
  108. flPaintBlend *= max ( 1.0f - flCuttableArea, smoothstep( 0.0f, 0.5f, fvPattern.a ) );
  109. // rescale the alpha to represent exponent in the range of 0-255 and let the cutout mask area fall off the top end
  110. fvPattern.a = lerp( fvPattern.a, saturate( fvPattern.a * 2.0f ), fvMasks.r );
  111. // indestructible paint
  112. #else
  113. // indestructible paint
  114. flPaintBlend *= max ( 1.0f - flCuttableArea, smoothstep( 0.0f, 0.5f, fvPattern.a ) );
  115. #endif
  116. #endif
  117. #if ( ( ( EXPONENTMODE == 1 ) || ( PREVIEW == 1 ) ) && ( ( PAINTSTYLE == 4 ) || ( PAINTSTYLE == 5 ) || ( PAINTSTYLE == 6 ) ) )
  118. float flPaintExpBlend = smoothstep( 0.99f, 1.0f, flPaintBlend );
  119. #else
  120. float flPaintExpBlend = flPaintBlend;
  121. #endif
  122. #elif ( ( EXPONENTMODE == 1 ) || ( PREVIEW == 1 ) )
  123. float flPaintExpBlend = flPaintBlend;
  124. #endif
  125. #if ( ( PAINTSTYLE == 2 ) || ( PAINTSTYLE == 3 ) ) // paint wears off in layers
  126. float3 fvPaintEdges = float3( 1.0f, 1.0f, 1.0f );
  127. float3 spread = 0.06f * g_flWearAmt; // spread of partially worn paint increases as the gun becomes more worn
  128. spread.y *= 2.0f;
  129. spread.z *= 3.0f;
  130. fvPaintEdges.x = smoothstep ( 0.58f, 0.56f - spread.x, flPaintBlend );
  131. fvPaintEdges.y = smoothstep ( 0.56f - spread.x, 0.54f - spread.y, flPaintBlend );
  132. fvPaintEdges.z = smoothstep ( 0.54f - spread.y, 0.52f - spread.z, flPaintBlend );
  133. #endif
  134. #if ( ( PAINTSTYLE != 8 ) && ( PAINTSTYLE != 9 ) )
  135. flPaintBlend = smoothstep( 0.58f, 0.68f, flPaintBlend );
  136. #elif ( PAINTSTYLE == 9 )
  137. flPaintBlend = lerp( smoothstep( 0.58f, 0.68f, flPaintBlend ), flPaintBlend, fvMasks.r );
  138. #endif
  139. #if ( ( PAINTSTYLE == 4 ) || ( PAINTSTYLE == 5 ) || ( PAINTSTYLE == 6 ) ) // Anodized paint scratches through uncolored base coat
  140. float flPaintEdges = smoothstep ( 0.0f, 0.01f, flPaintBlend );
  141. #endif
  142. // ------------------------------------------------------------------------------------------------------
  143. // Exponent texture
  144. // ------------------------------------------------------------------------------------------------------
  145. #if ( ( EXPONENTMODE == 1 ) || ( PREVIEW == 1 ) )
  146. float4 cExp = tex2D( ExponentSampler, i.vBaseUV_PatternUV.xy );
  147. #if ( ( PREVIEW == 1 ) && ( PREVIEWPHONGALBEDOTINT == 0 ) )
  148. cExp.g = 0.0f;
  149. #endif
  150. float4 cPaintExp = cExp;
  151. #if ( ( PAINTSTYLE == 4 ) || ( PAINTSTYLE == 5 ) || ( PAINTSTYLE == 6 ) || ( PAINTSTYLE == 8 ) || ( PAINTSTYLE == 9 ) ) // Anodized/metallic
  152. #if ( PAINTSTYLE == 8 )
  153. flPaintBlend = 1.0f - step( flPaintExpBlend, 0.996f ) * fvMasks.r;
  154. #elif ( PAINTSTYLE == 9 )
  155. flPaintBlend = lerp( flPaintBlend, 1.0f - step( flPaintExpBlend, 0.996f ), fvMasks.r );
  156. #else
  157. flPaintBlend = saturate( 1.0f + flPaintExpBlend - fvMasks.r );
  158. #endif
  159. // exponent
  160. #if ( PAINTSTYLE == 5 )
  161. float flPatternExponentBlend = max( max( fvMasks.g, fvMasks.b ), flPaintBlend );
  162. cPaintExp.r = lerp( fvPattern.a, cExp.r, flPatternExponentBlend );
  163. #elif ( PAINTSTYLE == 9 )
  164. cPaintExp.r = lerp( g_flPaintExponent, fvPattern.a, fvMasks.r );
  165. cPaintExp.r = lerp( cPaintExp.r, cExp.r, flPaintBlend );
  166. #else
  167. cPaintExp.r = lerp( g_flPaintExponent, cExp.r, flPaintBlend );
  168. #endif
  169. // phongalbedo
  170. #if ( PAINTSTYLE == 9 )
  171. cPaintExp.g = saturate( fvMasks.r + flPaintBlend * cExp.g );
  172. #else
  173. cPaintExp.g = lerp ( 1.0f, cExp.g, flPaintBlend );
  174. #endif
  175. cPaintExp.a = 1.0;
  176. #else // Everything else not anodized
  177. cPaintExp = lerp ( float4( g_flPaintExponent, 0.0f, 0.0f, 1.0f ), cExp, flPaintBlend );
  178. cPaintExp.a = 1.0;
  179. #endif
  180. #if ( PREVIEW == 0 )
  181. cOut = cPaintExp;
  182. #endif
  183. #endif
  184. // ------------------------------------------------------------------------------------------------------
  185. // Diffuse texture
  186. // ------------------------------------------------------------------------------------------------------
  187. #if ( ( EXPONENTMODE == 0 ) || ( PREVIEW == 1 ) )
  188. float4 cBase = tex2D( BaseSampler, i.vBaseUV_PatternUV.xy );
  189. float3 cPaint = g_cCamo0;
  190. // ambient occlusion
  191. float flAo = fvAoSrc.g;
  192. // apply grunge to paint only in creases
  193. float4 cGrunge = tex2D( GrungeSampler, i.vWearUV_GrungeUV.zw );
  194. #if ( ( PAINTSTYLE == 8 ) || ( PAINTSTYLE == 9 ) )
  195. float flGrunge = cGrunge.r * cGrunge.g * cGrunge.b;
  196. #endif
  197. cGrunge = lerp( 1.0f, cGrunge, ( pow( ( 1.0f - flCavity ), 4.0f ) * 0.25f + 0.75f * g_flWearAmt ) );
  198. // ------------------------------------------------------------------------------------------------------
  199. // Solid style
  200. // ------------------------------------------------------------------------------------------------------
  201. #if ( PAINTSTYLE == 1 )
  202. // apply color in solid blocks using masking from the part kit MasksSampler
  203. cPaint = lerp( cPaint, g_cCamo1, fvMasks.r );
  204. cPaint = lerp( cPaint, g_cCamo2, fvMasks.g );
  205. cPaint = lerp( cPaint, g_cCamo3, fvMasks.b );
  206. #endif
  207. // ------------------------------------------------------------------------------------------------------
  208. // Hydrographic/anodized multicolored style
  209. // ------------------------------------------------------------------------------------------------------
  210. #if ( ( PAINTSTYLE == 2 ) || ( PAINTSTYLE == 5 ) )
  211. // create camo using pattern
  212. cPaint = lerp( lerp( lerp( g_cCamo0, g_cCamo1, fvPattern.r ), g_cCamo2, fvPattern.g ), g_cCamo3, fvPattern.b );
  213. // apply any masking from the last two masks from MasksSampler, allowing some areas to be solid color
  214. cPaint = lerp( cPaint, g_cCamo2, fvMasks.g );
  215. cPaint = lerp( cPaint, g_cCamo3, fvMasks.b );
  216. #endif
  217. // ------------------------------------------------------------------------------------------------------
  218. // Spraypaint/anodized airbrushed style
  219. // ------------------------------------------------------------------------------------------------------
  220. #if ( ( PAINTSTYLE == 3 ) || ( PAINTSTYLE == 6 ) )
  221. // apply spraypaint via box map based on mesh's object-space position as stored in the position pmap
  222. float4 fvNormalSrc = tex2D( NormalsSampler, i.vBaseUV_PatternUV.xy );
  223. float2 fvPosCoord = float2( i.vBaseUV_PatternUV.x, 1.0 - i.vBaseUV_PatternUV.y );
  224. float4 fvPos = float4( 0.0f, 0.0f, 0.0f, 0.0f );
  225. #if ( CHEAPMODE == 0 ) // if supersampling is not disabled
  226. //super sampling of position map
  227. float2 offsets[17] = { float2( -0.00107234f ,-0.00400203f ),
  228. float2( 0.00195312f, -0.00338291f ),
  229. float2( 0.00400203f, -0.00107234f ),
  230. float2( -0.000714896f, -0.00266802f ),
  231. float2( 0.000976565f, -0.00169146f ),
  232. float2( 0.00266802f, -0.000714896f ),
  233. float2( -0.00338291f, -0.00195312f ),
  234. float2( -0.00169146f, -0.000976565f ),
  235. float2( 0.0f, 0.0f ),
  236. float2( 0.00169146f, 0.000976565f ),
  237. float2( 0.00338291f, 0.00195312f ),
  238. float2( -0.00266802f, 0.000714896f ),
  239. float2( -0.000976565f, 0.00169146f ),
  240. float2( 0.000714896f, 0.00266802f ),
  241. float2( -0.00400203f, 0.00107234f ),
  242. float2( -0.00195312f, 0.00338291f ),
  243. float2( 0.00107234, 0.00400203 ) };
  244. for ( int k = 0; k < 17; k++ )
  245. {
  246. fvPos += tex2D( OSPosSampler, fvPosCoord + offsets[k] ) * 0.05882353;
  247. }
  248. #else
  249. fvPos = tex2D( OSPosSampler, fvPosCoord );
  250. #endif
  251. //extract integer HDR values out from the RGBA vtf
  252. //developer.valvesoftware.com/wiki/Valve_Texture_Format#HDR_compression
  253. fvPos.rgb = (fvPos.rgb * (fvPos.a * 16.0f) );
  254. float3 fvNormal = normalize( fvNormalSrc.xyz * 2.0f - 1.0f );
  255. // Project the mask in object-space x, y and z
  256. float2 flCoord;
  257. #if ( PREVIEW == 1 )
  258. // apply the preview pattern scale to only the scale portion of the pattern transform.
  259. float2x2 tempMatrix = { g_PreviewPatternScale, 0, 0, g_PreviewPatternScale };
  260. float2x2 tempMatrix2 = { g_patternTexCoordTransform[0].xy, g_patternTexCoordTransform[1].xy };
  261. tempMatrix = mul( tempMatrix, tempMatrix2 );
  262. flCoord.x = dot( fvPos.yz, tempMatrix[0] ) + g_patternTexCoordTransform[0].w;
  263. flCoord.y = dot( fvPos.yz, tempMatrix[1] ) + g_patternTexCoordTransform[1].w;
  264. float3 fvTexX = tex2D( PatternSampler, flCoord ).rgb;
  265. flCoord.x = dot( fvPos.xz, tempMatrix[0] ) + g_patternTexCoordTransform[0].w;
  266. flCoord.y = dot( fvPos.xz, tempMatrix[1] ) + g_patternTexCoordTransform[1].w;
  267. float3 fvTexY = tex2D( PatternSampler, flCoord ).rgb;
  268. flCoord.x = dot( fvPos.yx, tempMatrix[0] ) + g_patternTexCoordTransform[0].w;
  269. flCoord.y = dot( fvPos.yx, tempMatrix[1] ) + g_patternTexCoordTransform[1].w;
  270. float3 fvTexZ = tex2D( PatternSampler, flCoord ).rgb;
  271. #else
  272. flCoord.x = dot( fvPos.yz, g_patternTexCoordTransform[0].xy ) + g_patternTexCoordTransform[0].w;
  273. flCoord.y = dot( fvPos.yz, g_patternTexCoordTransform[1].xy ) + g_patternTexCoordTransform[1].w;
  274. float3 fvTexX = tex2D( PatternSampler, flCoord ).rgb;
  275. flCoord.x = dot( fvPos.xz, g_patternTexCoordTransform[0].xy ) + g_patternTexCoordTransform[0].w;
  276. flCoord.y = dot( fvPos.xz, g_patternTexCoordTransform[1].xy ) + g_patternTexCoordTransform[1].w;
  277. float3 fvTexY = tex2D( PatternSampler, flCoord ).rgb;
  278. flCoord.x = dot( fvPos.yx, g_patternTexCoordTransform[0].xy ) + g_patternTexCoordTransform[0].w;
  279. flCoord.y = dot( fvPos.yx, g_patternTexCoordTransform[1].xy ) + g_patternTexCoordTransform[1].w;
  280. float3 fvTexZ = tex2D( PatternSampler, flCoord ).rgb;
  281. #endif
  282. // smooth blend the three projections across the object-space surface normals
  283. float yBlend = abs( dot( fvNormal.xyz, float3( 0.0f, 1.0f, 0.0f ) ) );
  284. yBlend = pow( yBlend, g_flBlendYPow );
  285. float zBlend = abs( dot( fvNormal.xyz, float3( 0.0f, 0.0f, 1.0f ) ) );
  286. zBlend = pow( zBlend, g_flBlendZPow );
  287. float3 fvPatternMask = lerp( lerp( fvTexX, fvTexY, yBlend ), fvTexZ, zBlend );
  288. #if ( PAINTSTYLE == 3 )// paint wears off in layers
  289. fvPatternMask.xyz *= fvPaintEdges.xyz;
  290. #endif
  291. cPaint = lerp( lerp( lerp( g_cCamo0, g_cCamo1, fvPatternMask.r ), g_cCamo2, fvPatternMask.g ), g_cCamo3, fvPatternMask.b );
  292. #if ( PAINTSTYLE == 6 )
  293. // apply any masking from the last two masks from MasksSampler, allowing some areas to be solid color
  294. cPaint = lerp( cPaint, g_cCamo2, fvMasks.g );
  295. cPaint = lerp( cPaint, g_cCamo3, fvMasks.b );
  296. #endif
  297. #endif
  298. // ------------------------------------------------------------------------------------------------------
  299. // Anodized style
  300. // ------------------------------------------------------------------------------------------------------
  301. #if ( PAINTSTYLE == 4 )
  302. cPaint.rgb = g_cCamo0.rgb;
  303. #endif
  304. #if ( ( PAINTSTYLE == 4 ) || ( PAINTSTYLE == 5 ) || ( PAINTSTYLE == 6 ) )
  305. // chipped edges of anodized dye
  306. cPaint = lerp( cPaint, g_cAnodizedBase, flPaintEdges );
  307. cGrunge.rgb = lerp( cGrunge.rgb, float3( 1.0f, 1.0f, 1.0f ), flPaintEdges );
  308. // anodize only in areas specified by the masks texture
  309. flPaintBlend = saturate( 1.0f + flPaintBlend - fvMasks.r );
  310. #endif
  311. // ------------------------------------------------------------------------------------------------------
  312. // Custom painted style
  313. // ------------------------------------------------------------------------------------------------------
  314. #if ( PAINTSTYLE == 7 )
  315. cPaint = fvPattern.rgb;
  316. #endif
  317. // ------------------------------------------------------------------------------------------------------
  318. // Antiqued or Gunsmith style
  319. // ------------------------------------------------------------------------------------------------------
  320. #if ( PAINTSTYLE == 8 )
  321. float4 fvPattern = tex2D( PatternSampler, i.vBaseUV_PatternUV.zw );
  322. #endif
  323. #if ( ( PAINTSTYLE == 8 ) || ( PAINTSTYLE == 9 ) )
  324. float flPatinaBlend = flPaintWear * flAo * flCavity * flCavity;
  325. flPatinaBlend = smoothstep( 0.1f, 0.2f, flPatinaBlend * g_flWearAmt );
  326. float flOilRubBlend = saturate( flCavity * flAo - g_flWearAmt * 0.1f ) - flGrunge;
  327. flOilRubBlend = smoothstep( 0.0f, 0.15f, flOilRubBlend + 0.08f );
  328. float3 cPatina = lerp( g_cCamo1, g_cCamo2, g_flWearAmt );
  329. float3 cOilRubColor = lerp( g_cCamo1, g_cCamo3, pow( g_flWearAmt, 0.5 ) );
  330. cPatina = lerp( cOilRubColor, cPatina, flOilRubBlend ) * fvPattern.rgb;
  331. float3 vLumCoefficients = { 0.3, 0.59, 0.11 };
  332. float fPatternLum = dot( fvPattern.rgb, vLumCoefficients );
  333. float3 cScratches = g_cCamo0 * fPatternLum;
  334. cPatina = lerp( cPatina, cScratches, flPatinaBlend );
  335. #if ( PAINTSTYLE == 8 )
  336. cPaint = cPatina;
  337. flPaintBlend = 1.0f - fvMasks.r;
  338. #elif ( PAINTSTYLE == 9 )
  339. cPaint = lerp ( fvPattern.rgb, cPatina, fvMasks.r );
  340. flPaintBlend = flPaintBlend * ( 1.0f - fvMasks.r );
  341. #endif
  342. #endif
  343. // ------------------------------------------------------------------------------------------------------
  344. // All paints
  345. // ------------------------------------------------------------------------------------------------------
  346. float3 cModulation = fvAoSrc.b;
  347. cPaint.rgb *= cGrunge.rgb;
  348. // On very dark paints, increase the modulation slightly by adding
  349. float3 lumCoefficients = { 0.3, 0.59, 0.11 };
  350. float flModulationLum = dot( cPaint.rgb, lumCoefficients );
  351. flModulationLum = 1.0f - smoothstep( 0.08f, 0.15f, flModulationLum );
  352. #if ( ( PAINTSTYLE == 1 ) || ( PAINTSTYLE == 2 ) || ( PAINTSTYLE == 3 ) || ( PAINTSTYLE == 7 ) )
  353. flModulationLum *= 0.03f;
  354. cModulation = cModulation.rgb * ( cPaint.rgb + flModulationLum ) * 0.5f;
  355. #elif ( PAINTSTYLE == 9 )
  356. flModulationLum *= lerp( 0.03f, 0.005f, fvMasks.r );
  357. cModulation = cModulation.rgb * ( cPaint.rgb + flModulationLum ) * lerp( 0.5f, 2.0f, fvMasks.r );
  358. #else
  359. flModulationLum *= 0.005f;
  360. cModulation = cModulation.rgb * ( cPaint.rgb + flModulationLum ) * 2.0f;
  361. #endif
  362. cPaint = saturate( cPaint + cModulation );
  363. cPaint.rgb *= flAo;
  364. cOut.rgb = lerp( cPaint, cBase, flPaintBlend );
  365. // ------------------------------------------------------------------------------------------------------
  366. // Specular Intensity Mask
  367. // ------------------------------------------------------------------------------------------------------
  368. #if ( PAINTSTYLE == 9 )
  369. #if ( PHONGALBEDOFACTORMODE == 1 )
  370. float flSpecMask = lerp( g_flPaintPhongIntensity, 1.0f, fvMasks.r ) * flAo * cGrunge.a;
  371. #else
  372. float flSpecMask = lerp( g_flPaintPhongIntensity, g_flPhongAlbedoFactor, fvMasks.r ) * flAo * cGrunge.a;
  373. #endif
  374. #else
  375. float flSpecMask = g_flPaintPhongIntensity * flAo * cGrunge.a;
  376. #endif
  377. #if ( ( PAINTSTYLE == 4 ) || ( PAINTSTYLE == 5 ) || ( PAINTSTYLE == 6 ) || ( PAINTSTYLE == 8 ) || ( PAINTSTYLE == 9 ) )// anodized/metallic
  378. // phongalbedoboost must be increased in the material for the anodized look, so in areas that are
  379. // already using phongalbedo the specular intensity must be reduced in order to retain approximately
  380. // the same intensity as the originally authored texture
  381. float flInvPaintBlend = 1.0f - flPaintBlend;
  382. float4 cOrigExp = tex2D( ExponentSampler, i.vBaseUV_PatternUV.xy );
  383. #if ( ( PREVIEW == 1 ) && ( PREVIEWPHONGALBEDOTINT == 0 ) )
  384. cOrigExp.g = 0.0f;
  385. #endif
  386. #if ( PAINTSTYLE == 8 )
  387. flSpecMask *= lerp( flOilRubBlend * ( 1.0f - flPatinaBlend * g_flWearAmt ), 1.0f, flPatinaBlend );
  388. #elif ( PAINTSTYLE == 9 )
  389. float flPaintSpecBlend = smoothstep( 0.9f, 1.0f, flPaintBlend ) * fvMasks.r;
  390. flSpecMask *= lerp( smoothstep( 0.01f, 0.0f, flPaintBlend ), lerp( flOilRubBlend * ( 1.0f - flPatinaBlend * g_flWearAmt ), 1.0f, flPatinaBlend ), fvMasks.r );
  391. flSpecMask = lerp( flSpecMask, cBase.a, flPaintSpecBlend );
  392. flPaintSpecBlend = smoothstep( 0.9f, 1.0f, flPaintBlend ) * ( 1.0f - fvMasks.r );
  393. #else
  394. flSpecMask *= lerp( g_flPaintPhongIntensity, g_flAnodizedBasePhongIntensity, flPaintEdges );
  395. #endif
  396. float flPhongAlbedoBlend = flPaintBlend;
  397. float flAdjustedBase = 1.0f;
  398. #if ( PHONGALBEDOFACTORMODE == 1 )
  399. flAdjustedBase = lerp( 1.0, g_flPhongAlbedoFactor, cOrigExp.g * flPhongAlbedoBlend );
  400. cOut.a = lerp( flSpecMask, cBase.a * flAdjustedBase, flPaintBlend );
  401. #else
  402. cOut.a = lerp( flSpecMask * g_flPhongAlbedoFactor, cBase.a, flPhongAlbedoBlend );
  403. #endif
  404. #if ( PAINTSTYLE == 9 )
  405. cOut.a = lerp( flSpecMask, cBase.a * flAdjustedBase, flPaintSpecBlend );
  406. #endif
  407. #else // everything else
  408. float flPaintSpecBlend = smoothstep( 0.9f, 1.0f, flPaintBlend );
  409. flSpecMask *= smoothstep( 0.01f, 0.0f, flPaintBlend );
  410. cOut.a = lerp( flSpecMask, cBase.a, flPaintSpecBlend );
  411. #endif
  412. #endif
  413. #if ( PREVIEW == 1 )
  414. float3 diffuseLighting = float3( 0.0f, 0.0f, 0.0f );
  415. // TODO ENVMAP
  416. float3 envMapColor = float3( 0.0f, 0.0f, 0.0f );
  417. float3 vWorldPos = i.worldPos;
  418. float3 vEyeDir = normalize( g_EyePos - vWorldPos );
  419. float3 vWorldNormal = normalize ( i.vWorldNormal.xyz );
  420. float fFresnelRanges = Fresnel( vWorldNormal, vEyeDir, g_PreviewPhongFresnelRanges );
  421. float3 linearColor = PixelShaderDoLighting( vWorldPos, vWorldNormal,
  422. float3( 0.0f, 0.0f, 0.0f), false,
  423. true, i.lightAtten, g_cAmbientCube,
  424. NormalizeSampler, NUM_LIGHTS, cLightInfo, false,
  425. false, NULL, 1.0f );
  426. float3 specularLighting, rimLighting;
  427. PixelShaderDoSpecularLighting( vWorldPos, vWorldNormal, cPaintExp.r * 255.0f, vEyeDir,
  428. i.lightAtten, NUM_LIGHTS, cLightInfo, false, NULL, fFresnelRanges,
  429. false, 1.0f, 1.0f,
  430. specularLighting, rimLighting );
  431. #if ( ( PREVIEWPHONGALBEDOTINT == 1 ) || ( PAINTSTYLE == 4 ) || ( PAINTSTYLE == 5 ) || ( PAINTSTYLE == 6 ) || ( PAINTSTYLE == 8 ) || ( PAINTSTYLE == 9 ) )
  432. specularLighting *= lerp( (float3)g_PreviewPhongBoost, g_PreviewPhongAlbedoBoost * cOut.rgb, cPaintExp.g );
  433. #else
  434. specularLighting *= g_PreviewPhongBoost;
  435. #endif
  436. specularLighting *= cOut.a * fFresnelRanges; // specular mask
  437. cOut.rgb *= linearColor;
  438. cOut.rgb += specularLighting;
  439. #endif
  440. #if ( PREVIEW == 1 )
  441. return FinalOutput( cOut, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_LINEAR );
  442. #else
  443. return FinalOutput( cOut, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
  444. #endif
  445. }