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.

993 lines
36 KiB

  1. //===================== Copyright (c) Valve Corporation. All Rights Reserved. ======================
  2. // SKIP: $NORMALMAPALPHAENVMAPMASK && $BASEALPHAENVMAPMASK
  3. // SKIP: $NORMALMAPALPHAENVMAPMASK && $ENVMAPMASK
  4. // SKIP: $BASEALPHAENVMAPMASK && $ENVMAPMASK
  5. // SKIP: $BASEALPHAENVMAPMASK && $SELFILLUM
  6. // SKIP: !$FASTPATH && $FASTPATHENVMAPCONTRAST
  7. // SKIP: !$FASTPATH && $FASTPATHENVMAPTINT
  8. // SKIP: !$BUMPMAP && $BUMPMAP2
  9. // SKIP: $BASEALPHAENVMAPMASK && ( $BUMPMAP && !$ENVMAPANISOTROPY )
  10. // SKIP: $SEAMLESS && ( $DETAIL_BLEND_MODE != 12 )
  11. // SKIP: $BUMPMASK && ( $SEAMLESS || ( $DETAILTEXTURE != 12 ) || $SELFILLUM || $BASETEXTURE2 )
  12. // SKIP: $ENVMAPANISOTROPY && !$ENVMAP && ( $BUMPMAP != 1 )
  13. // SKIP: $ENVMAPANISOTROPY && $NORMALMAPALPHAENVMAPMASK
  14. // SKIP: !$BUMPMAP && $ADDBUMPMAPS
  15. // SKIP: !$BUMPMAP2 && $ADDBUMPMAPS
  16. // SKIP: $BUMPMASK && $ADDBUMPMAPS
  17. // SKIP: $ADDBUMPMAPS && ( $DETAIL_BLEND_MODE != 12 ) [ps20]
  18. // SKIP: ( $DETAIL == 2 ) && !$BASETEXTURE2
  19. // 360 compiler craps out on some combo in this family. Content doesn't use blendmode 10 anyway
  20. // SKIP: $FASTPATH && $PIXELFOGTYPE && $BASETEXTURE2 && $CUBEMAP && ($DETAIL_BLEND_MODE == 10 ) [CONSOLE]
  21. // Turning off 32bit lightmaps on Portal 2 to save shader perf. --Thorsten
  22. //#define USE_32BIT_LIGHTMAPS_ON_360 //uncomment to use 32bit lightmaps, be sure to keep this in sync with the same #define in materialsystem/cmatlightmaps.cpp
  23. #if defined( SHADER_MODEL_PS_2_0 )
  24. //#error ps2.0 support removed for this shader
  25. #endif
  26. // NOTE: This has to be before inclusion of common_lightmappedgeneric_fxc.h to get the vertex format right!
  27. #if ( DETAIL_BLEND_MODE == 12 )
  28. #define DETAILTEXTURE 0
  29. #else
  30. #if ( DETAIL2 == 1)
  31. #define DETAILTEXTURE 2
  32. #else
  33. #define DETAILTEXTURE 1
  34. #endif
  35. #endif
  36. #include "common_ps_fxc.h"
  37. #include "common_flashlight_fxc.h"
  38. #define PIXELSHADER
  39. #include "common_lightmappedgeneric_fxc.h"
  40. #if SEAMLESS
  41. #define USE_FAST_PATH 1
  42. #else
  43. #define USE_FAST_PATH FASTPATH
  44. #endif
  45. const float4 g_EnvmapTint : register( c0 );
  46. #if ( USE_FAST_PATH == 1 || LIGHTING_PREVIEW == 1 )
  47. #if FASTPATHENVMAPCONTRAST == 0
  48. static const float3 g_EnvmapContrast = { 0.0f, 0.0f, 0.0f };
  49. #else
  50. static const float3 g_EnvmapContrast = { 1.0f, 1.0f, 1.0f };
  51. #endif
  52. static const float3 g_EnvmapSaturation = { 1.0f, 1.0f, 1.0f };
  53. static const float g_FresnelReflection = 1.0f;
  54. static const float g_OneMinusFresnelReflection = 0.0f;
  55. static const float4 g_SelfIllumTint = { 1.0f, 1.0f, 1.0f, 1.0f };
  56. #else // ( USE_FAST_PATH == 0 )
  57. const float3 g_EnvmapContrast : register( c2 );
  58. const float3 g_EnvmapSaturation : register( c3 );
  59. const float4 g_FresnelReflectionReg : register( c4 );
  60. #define g_FresnelReflection g_FresnelReflectionReg.a
  61. #define g_OneMinusFresnelReflection g_FresnelReflectionReg.b
  62. const float4 g_SelfIllumTint : register( c7 );
  63. #endif
  64. const float4 g_DetailTint_and_BlendFactor : register( c8 );
  65. #define g_DetailTint (g_DetailTint_and_BlendFactor.rgb)
  66. #define g_DetailBlendFactor (g_DetailTint_and_BlendFactor.w)
  67. #if ADDBUMPMAPS == 1
  68. #define g_vAddBumpMapScale1 g_DetailTint_and_BlendFactor.r;
  69. #define g_vAddBumpMapScale2 g_DetailTint_and_BlendFactor.g;
  70. #endif
  71. const float4 g_Detail2Tint_and_BlendFactor : register(c9);
  72. #define g_Detail2Tint (g_Detail2Tint_and_BlendFactor.rgb)
  73. #define g_Detail2BlendFactor (g_Detail2Tint_and_BlendFactor.w)
  74. const float3 g_EyePos : register( c10 );
  75. const float4 g_FogParams : register( c11 );
  76. const float4 g_TintValuesTimesLightmapScale : register( c12 );
  77. #define g_flAlpha2 g_TintValuesTimesLightmapScale.w
  78. const float4 g_FlashlightAttenuationFactors : register( c13 );
  79. const float3 g_FlashlightPos : register( c14 );
  80. const float4x4 g_FlashlightWorldToTexture : register( c15 ); // through c18
  81. const float4 g_ShadowTweaks : register( c19 );
  82. #if !defined( SHADER_MODEL_PS_2_0 ) && ( FLASHLIGHT == 0 )
  83. #define g_cAmbientColor cFlashlightScreenScale.rgb
  84. //const float3 g_cAmbientColor : register( c31 );
  85. #endif
  86. #if ( ( CUBEMAP == 2 ) || ( ENVMAPANISOTROPY ) )
  87. const float4 g_envMapParams : register( c20 );
  88. #endif
  89. #if ( CUBEMAP == 2 )
  90. #define g_DiffuseCubemapScale g_envMapParams.y
  91. #define g_fvDiffuseCubemapMin float3( g_envMapParams.z, g_envMapParams.z, g_envMapParams.z )
  92. #define g_fvDiffuseCubemapMax float3( g_envMapParams.w, g_envMapParams.w, g_envMapParams.w )
  93. #endif
  94. #if ( ENVMAPANISOTROPY )
  95. #define g_EnvmapAnisotropyScale g_envMapParams.x
  96. #endif
  97. #if defined( SHADER_MODEL_PS_3_0 )
  98. const float3 g_TintValuesWithoutLightmapScale : register( c21 );
  99. #else
  100. const float4 g_vCSMLightColor : register(c21);
  101. #endif
  102. #if ( PHONG )
  103. const float4 g_Phong_Exp_and_BaseTint : register( c22 );
  104. #define g_PhongExp g_Phong_Exp_and_BaseTint.x
  105. #define g_PhongTint g_Phong_Exp_and_BaseTint.y
  106. #define g_PhongExp2 g_Phong_Exp_and_BaseTint.z
  107. #define g_PhongTint2 g_Phong_Exp_and_BaseTint.w
  108. const float4 g_PhongMask_Contrast_and_Brightness : register( c23 );
  109. #define g_PhongMaskContrast g_PhongMask_Contrast_and_Brightness.x
  110. #define g_PhongMaskBrightness g_PhongMask_Contrast_and_Brightness.y
  111. #define g_PhongMaskContrast2 g_PhongMask_Contrast_and_Brightness.z
  112. #define g_PhongMaskBrightness2 g_PhongMask_Contrast_and_Brightness.w
  113. const float4 g_PhongAmount : register( c24 );
  114. const float4 g_PhongAmount2 : register( c25 );
  115. #endif
  116. #if ( ENVMAPMASK ) && defined( SHADER_MODEL_PS_3_0 )
  117. const float4 g_EnvmapMaskTexCoordTransform[2] : register( c35 );
  118. const float4 g_EnvmapMaskTexCoordTransform2[2] : register( c37 );
  119. #endif
  120. sampler BaseTextureSampler : register( s0 );
  121. sampler LightmapSampler : register( s1 );
  122. samplerCUBE EnvmapSampler : register( s2 );
  123. #if FANCY_BLENDING
  124. sampler BlendModulationSampler : register( s3 );
  125. #if ( CASCADED_SHADOW_MAPPING ) && defined( SHADER_MODEL_PS_3_0 ) && ( BUMPMAP > 0 )
  126. const float4 g_vDropShadowParams : register( c26 );
  127. #define g_fDropShadowScale g_vDropShadowParams.x
  128. #define g_fDropShadowOpacity g_vDropShadowParams.y
  129. #define g_fDropShadowHighlightScale g_vDropShadowParams.z
  130. #define g_fDropShadowDepthExaggeration g_vDropShadowParams.w
  131. #endif
  132. #endif
  133. #if ( BASETEXTURE2 ) && defined( SHADER_MODEL_PS_3_0 )
  134. const float4 g_vTintLayer1 : register( c33 );
  135. const float4 g_vTintLayer2 : register( c34 );
  136. #endif
  137. #if ( FANCY_BLENDING >= 2 ) && defined( SHADER_MODEL_PS_3_0 )
  138. const float4 g_vBlendParams : register( c46 );
  139. #define g_flBlendSoftness g_vBlendParams.x
  140. #define g_flLayerBorderStrength g_vBlendParams.y
  141. #define g_flLayerBorderOffset g_vBlendParams.z
  142. #define g_flLayerBorderSoftness g_vBlendParams.w
  143. const float4 g_vLayerBorderTint : register( c47 );
  144. const float4 g_vEdgeBlendParams : register( c48 );
  145. #define g_flLayerNormalEdgePunchInSign g_vEdgeBlendParams.x
  146. #define g_flLayerNormalEdgeStrength g_vEdgeBlendParams.y
  147. #define g_flLayerNormalEdgeOffset g_vEdgeBlendParams.z
  148. #define g_flLayerNormalEdgeSoftness g_vEdgeBlendParams.w
  149. #endif
  150. #if ( DETAILTEXTURE != 0 )
  151. sampler DetailSampler : register( s12 );
  152. #if ( DETAILTEXTURE == 2 )
  153. sampler DetailSampler2 : register( s9 );
  154. #endif
  155. #endif
  156. sampler BumpmapSampler : register( s4 );
  157. #if (BUMPMAP == 1) && defined( _PS3 )
  158. // Causes the Cg compiler to automatically produce _bx2 modifier on the texture load instead of producing a MAD to range expand the vector, saving one instruction.
  159. #pragma texsign BumpmapSampler
  160. #pragma texformat BumpmapSampler RGBA8
  161. #endif
  162. #if BUMPMAP2 == 1
  163. sampler BumpmapSampler2 : register( s5 );
  164. #endif
  165. #if ( ENVMAPMASK ) && defined( SHADER_MODEL_PS_3_0 )
  166. sampler EnvmapMaskSampler : register( s6 );
  167. #if ( BASETEXTURE2 )
  168. sampler EnvmapMaskSampler2 : register( s10 );
  169. #endif
  170. #endif
  171. sampler BaseTextureSampler2 : register( s7 );
  172. #if BUMPMASK == 1
  173. sampler BumpMaskSampler : register( s8 );
  174. #if NORMALMASK_DECODE_MODE == NORM_DECODE_ATI2N_ALPHA
  175. sampler AlphaMaskSampler : register( s11 ); // alpha
  176. #else
  177. #define AlphaMaskSampler BumpMaskSampler
  178. #endif
  179. #endif
  180. #if ( defined( _X360 ) || defined( _PS3 ) ) && FLASHLIGHT
  181. sampler FlashlightSampler : register( s13 );
  182. sampler ShadowDepthSampler : register( s14 );
  183. sampler RandRotSampler : register( s15 );
  184. #if defined(_PS3)
  185. // Needed for optimal shadow filter code generation on PS3.
  186. #pragma texformat ShadowDepthSampler DEPTH_COMPONENT24
  187. #endif
  188. #endif
  189. #ifdef PHONG_DEBUG
  190. #undef PHONG_DEBUG
  191. #endif
  192. #define PHONG_DEBUG 0
  193. //const float g_flTime : register( c24 );
  194. float Luminance( float3 cColor )
  195. {
  196. // Formula for calculating luminance based on NTSC standard
  197. return dot( cColor.rgb, float3( 0.2125, 0.7154, 0.0721 ) );
  198. }
  199. //-----------------------------------------------------------------------------------------------------------------------------
  200. #if ( CASCADED_SHADOW_MAPPING ) && !defined( _X360 ) && !defined( _PS3 ) && !defined( SHADER_MODEL_PS_2_B )
  201. const bool g_bCSMEnabled : register(b0);
  202. #undef CASCADE_SIZE
  203. #define CASCADE_SIZE 1
  204. #endif
  205. #if ( CASCADE_SIZE > 0 )
  206. #undef CASCADE_SIZE
  207. #define CASCADE_SIZE 3
  208. #endif
  209. #if ( ( CASCADED_SHADOW_MAPPING ) && ( CASCADE_SIZE > 0 ) )
  210. sampler CSMDepthAtlasSampler : register( s15 );
  211. #if defined(_PS3)
  212. // Needed for optimal shadow filter code generation on PS3.
  213. #pragma texformat CSMDepthAtlasSampler DEPTH_COMPONENT24
  214. #endif
  215. #if defined( SHADER_MODEL_PS_2_B )
  216. #define CSM_LIGHTMAPPEDGENERIC
  217. #endif
  218. #include "csm_common_fxc.h"
  219. #include "csm_blending_fxc.h"
  220. #endif
  221. //-----------------------------------------------------------------------------------------------------------------------------
  222. #if defined( _X360 )
  223. // The compiler runs out of temp registers in certain combos, increase the maximum for now
  224. #if ( BASETEXTURE2 && (BUMPMAP == 2) && CUBEMAP && NORMALMAPALPHAENVMAPMASK && DIFFUSEBUMPMAP && FLASHLIGHT && SHADER_SRGB_READ )
  225. [maxtempreg(44)]
  226. #elif ( SHADER_SRGB_READ == 1 )
  227. [maxtempreg(41)]
  228. #else
  229. [maxtempreg(36)]
  230. #endif
  231. #endif
  232. #if LIGHTING_PREVIEW == 2
  233. LPREVIEW_PS_OUT main( PS_INPUT i )
  234. #else
  235. float4_color_return_type main( PS_INPUT i ) : COLOR
  236. #endif
  237. {
  238. bool bBaseTexture2 = BASETEXTURE2 ? true : false;
  239. bool bDetailTexture = ( DETAILTEXTURE != 0 ) ? true : false;
  240. bool bDetailTexture2 = ( DETAILTEXTURE == 2 ) ? true : false;
  241. bool bBumpmap = BUMPMAP ? true : false;
  242. bool bDiffuseBumpmap = DIFFUSEBUMPMAP ? true : false;
  243. bool bEnvmapMask = ENVMAPMASK ? true : false;
  244. bool bBaseAlphaEnvmapMask = BASEALPHAENVMAPMASK ? true : false;
  245. bool bSelfIllum = SELFILLUM ? true : false;
  246. bool bNormalMapAlphaEnvmapMask = NORMALMAPALPHAENVMAPMASK ? true : false;
  247. HALF4 baseColor = 0.0h;
  248. HALF4 baseColor2 = 0.0h;
  249. HALF4 vNormal = HALF4( 0, 0, 1, 1 );
  250. float3 baseTexCoords = float3( 0, 0, 0 );
  251. float3 baseTexCoords2 = float3( 0, 0, 0 );
  252. float3 worldPos = i.worldPos_projPosZ.xyz;
  253. HALF3x3 tangenttranspose = HALF3x3( HALF3(i.tangentSpaceTranspose0_vertexBlendX.xyz), HALF3(i.tangentSpaceTranspose1_bumpTexCoord2u.xyz), HALF3(i.tangentSpaceTranspose2_bumpTexCoord2v.xyz) );
  254. float3 worldVertToEyeVector = g_EyePos - worldPos;
  255. #if SEAMLESS
  256. baseTexCoords = i.SeamlessTexCoord.xyz;
  257. baseTexCoords2 = i.SeamlessTexCoord.xyz;
  258. #else
  259. baseTexCoords.xy = i.BASETEXCOORD;
  260. baseTexCoords2.xy = i.BASETEXCOORD2;
  261. #endif
  262. float3 coords = baseTexCoords;
  263. float3 coords2 = baseTexCoords2;
  264. float2 detailTexCoord = 0.0f;
  265. float2 detailTexCoord2 = 0.0f;
  266. float2 bumpmapTexCoord = 0.0f;
  267. float2 bumpmapTexCoord2 = 0.0f;
  268. #if ( DETAILTEXTURE != 0 )
  269. detailTexCoord = i.DETAILCOORD;
  270. #if ( DETAILTEXTURE == 2 ) && defined( SHADER_MODEL_PS_3_0 )
  271. detailTexCoord2 = i.DETAILCOORD2;
  272. #endif
  273. #endif
  274. #if BUMPMAP
  275. bumpmapTexCoord = i.BUMPCOORD;
  276. bumpmapTexCoord2 = float2( i.BUMPCOORD2U, i.BUMPCOORD2V );
  277. #endif
  278. GetBaseTextureAndNormal( BaseTextureSampler, BaseTextureSampler2, BumpmapSampler,
  279. bBaseTexture2, bBumpmap || bNormalMapAlphaEnvmapMask,
  280. coords, coords2, bumpmapTexCoord,
  281. (HALF3)i.vertexColor.rgb, baseColor, baseColor2, vNormal );
  282. #if ( ENVMAPANISOTROPY )
  283. HALF anisotropyFactor = g_EnvmapAnisotropyScale;
  284. #endif
  285. #if BUMPMAP == 1 // not ssbump
  286. vNormal.xyz = vNormal.xyz * 2.0h - 1.0h; // make signed if we're not ssbump
  287. HALF3 vThisReallyIsANormal = vNormal.xyz;
  288. #if ( ENVMAPANISOTROPY )
  289. anisotropyFactor *= (HALF)vNormal.a;
  290. #endif
  291. #endif
  292. HALF4 lightmapColor1 = HALF4( 1.0, 1.0, 1.0, 1.0 );
  293. HALF4 lightmapColor2 = HALF4( 1.0, 1.0, 1.0, 1.0 );
  294. HALF4 lightmapColor3 = HALF4( 1.0, 1.0, 1.0, 1.0 );
  295. #if LIGHTING_PREVIEW == 0
  296. if ( bBumpmap && bDiffuseBumpmap )
  297. {
  298. float2 bumpCoord1;
  299. float2 bumpCoord2;
  300. float2 bumpCoord3;
  301. ComputeBumpedLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3_bumpTexCoord.xy,
  302. bumpCoord1, bumpCoord2, bumpCoord3 );
  303. lightmapColor1 = LightMapSample( LightmapSampler, bumpCoord1 );
  304. lightmapColor2 = LightMapSample( LightmapSampler, bumpCoord2 );
  305. lightmapColor3 = LightMapSample( LightmapSampler, bumpCoord3 );
  306. }
  307. else
  308. {
  309. float2 bumpCoord1 = ComputeLightmapCoordinates( i.lightmapTexCoord1And2, i.lightmapTexCoord3_bumpTexCoord.xy );
  310. lightmapColor1 = LightMapSample( LightmapSampler, bumpCoord1 );
  311. }
  312. #endif
  313. HALF4 detailColor = HALF4( 1.0f, 1.0f, 1.0f, 1.0f );
  314. HALF4 detailColor2 = HALF4( 1.0f, 1.0f, 1.0f, 1.0f );
  315. #if ( DETAILTEXTURE != 0 )
  316. #if SHADER_MODEL_PS_2_0 || ADDBUMPMAPS == 1
  317. detailColor = h4tex2D( DetailSampler, detailTexCoord );
  318. #else
  319. detailColor = HALF4( g_DetailTint, 1.0h ) * h4tex2D( DetailSampler, detailTexCoord );
  320. #endif
  321. #if ( DETAILTEXTURE == 2 )
  322. detailColor2 = HALF4( g_Detail2Tint, 1.0h ) * h4tex2D( DetailSampler2, detailTexCoord2 );
  323. #endif
  324. #endif
  325. HALF blendedAlpha = baseColor.a;
  326. HALF blendfactor = i.tangentSpaceTranspose0_vertexBlendX.w;
  327. #if ( BASETEXTURE2 ) && defined( SHADER_MODEL_PS_3_0 )
  328. baseColor.rgb *= g_vTintLayer1.rgb;
  329. baseColor2.rgb *= g_vTintLayer2.rgb;
  330. #endif
  331. #if ( PHONG )
  332. // save off basecolor for phong mask generation before it potentially gets overwritten with a blend of basecolor and basecolor2
  333. HALF4 baseColor1 = baseColor;
  334. #endif
  335. HALF4 vBlendModulateTexel = HALF4( 0.0f, 0.0f, 0.0f, 0.0f );
  336. float flBlendModulateFactor = 0.0f;
  337. if ( bBaseTexture2 )
  338. {
  339. #if (SELFILLUM == 0) && (PIXELFOGTYPE != PIXEL_FOG_TYPE_HEIGHT) && (FANCY_BLENDING == 1) && (SEAMLESS == 0)
  340. vBlendModulateTexel = h4tex2D( BlendModulationSampler, i.BLENDMODULATECOORD );
  341. HALF minb=max(0, vBlendModulateTexel.g - vBlendModulateTexel.r );
  342. HALF maxb=min(1, vBlendModulateTexel.g + vBlendModulateTexel.r );
  343. blendfactor=smoothstep(minb,maxb,blendfactor);
  344. #if ( CASCADED_SHADOW_MAPPING == 1 ) && ( BUMPMAP > 0 ) && defined( SHADER_MODEL_PS_3_0 )// drop shadows on blend textures
  345. if ( g_fDropShadowOpacity > 0.0f )
  346. {
  347. float3 vWorldLightDir = normalize( g_vCSMLightDir );
  348. float3x3 worldToTangentSpace = transpose( tangenttranspose );
  349. HALF2 vShadowOffset = float2( 0, 0 );
  350. vShadowOffset.x = dot( vWorldLightDir, worldToTangentSpace[0] );
  351. vShadowOffset.y = dot( vWorldLightDir, worldToTangentSpace[1] );
  352. HALF NdotL = dot( vWorldLightDir, tangenttranspose[2] );
  353. HALF HNdotL = NdotL * 0.5f + 0.5f;
  354. HALF fShadowOffset = ( vBlendModulateTexel.g - pow( vBlendModulateTexel.g, g_fDropShadowDepthExaggeration ) * g_fDropShadowDepthExaggeration ) * g_fDropShadowScale;
  355. HALF fHighlightOffset = -vBlendModulateTexel.g * g_fDropShadowHighlightScale;
  356. fShadowOffset = lerp( fShadowOffset, fHighlightOffset, blendfactor );
  357. vShadowOffset = vShadowOffset * fShadowOffset * NdotL;
  358. HALF4 vShadowSample = h4tex2D( BlendModulationSampler, i.BLENDMODULATECOORD + vShadowOffset );
  359. minb=max(0.0039, vShadowSample.g - vShadowSample.r );
  360. maxb=min(1, vShadowSample.g + vShadowSample.r );
  361. HALF dropshadow=smoothstep( maxb, minb, i.tangentSpaceTranspose0_vertexBlendX.w );
  362. baseColor.rgb *= lerp( 1.0f, max( dropshadow, 1.0f - g_fDropShadowOpacity ), smoothstep( 0.1f, 0.5f, HNdotL ) );
  363. HALF highlight=smoothstep(maxb,minb,i.tangentSpaceTranspose0_vertexBlendX.w) * g_fDropShadowOpacity;
  364. baseColor2.rgb += baseColor2.rgb * highlight * HNdotL;
  365. }
  366. #endif
  367. #elif (FANCY_BLENDING >= 2) && (SELFILLUM == 0) && (PIXELFOGTYPE != PIXEL_FOG_TYPE_HEIGHT) && (SEAMLESS == 0) && defined( SHADER_MODEL_PS_3_0 )
  368. vBlendModulateTexel = h4tex2D( BlendModulationSampler, i.BLENDMODULATECOORD );
  369. flBlendModulateFactor = vBlendModulateTexel.g;
  370. #if ( FANCY_BLENDING == 3 )
  371. {
  372. flBlendModulateFactor = vBlendModulateTexel.a;
  373. }
  374. #endif
  375. HALF minb = max( 0, flBlendModulateFactor - g_flBlendSoftness );
  376. HALF maxb = min( 1, flBlendModulateFactor + g_flBlendSoftness );
  377. float flBlendfactor = smoothstep( minb, maxb, blendfactor );
  378. HALF minborder = max( 0, flBlendModulateFactor - g_flLayerBorderSoftness );
  379. HALF maxborder = min( 1, flBlendModulateFactor + g_flLayerBorderSoftness );
  380. float flBorderWeight = smoothstep( minborder, maxborder, saturate( blendfactor - g_flLayerBorderOffset ) );
  381. float flBorderStrength = ( 1.0 - abs( flBorderWeight * 2.0 - 1.0 ) ) * g_flLayerBorderStrength;
  382. baseColor.rgb *= lerp( float3( 1.0, 1.0, 1.0 ), g_vLayerBorderTint.rgb, flBorderStrength );
  383. blendfactor = flBlendfactor;
  384. #endif
  385. baseColor.rgb = lerp( baseColor.rgb, baseColor2.rgb, blendfactor );
  386. blendedAlpha = lerp( baseColor.a, baseColor2.a, blendfactor );
  387. }
  388. HALF3 specularFactor = 1.0h;
  389. HALF4 vNormalMask = HALF4(0, 0, 1, 1);
  390. if ( bBumpmap )
  391. {
  392. #if ( BUMPMAP2 == 1 )
  393. {
  394. float2 b2TexCoord = bumpmapTexCoord2;
  395. HALF4 vNormal2;
  396. #if ( BUMPMAP == 2 )
  397. {
  398. vNormal2 = h4tex2D( BumpmapSampler2, b2TexCoord );
  399. }
  400. #else
  401. {
  402. HALF4 normalTexel = h4tex2D( BumpmapSampler2, b2TexCoord );
  403. vNormal2 = HALF4( normalTexel.xyz * 2.0h - 1.0h, normalTexel.a );
  404. }
  405. #endif
  406. #if ( BUMPMASK == 1 )
  407. HALF3 vNormal1 = DecompressNormal( BumpmapSampler, i.BUMPCOORD, NORMALMASK_DECODE_MODE, AlphaMapSampler );
  408. vNormal.xyz = normalize( vNormal1.xyz + vNormal2.xyz );
  409. // Third normal map...same coords as base
  410. normalTexel = h4tex2D( BumpMaskSampler, i.BASETEXCOORD );
  411. vNormalMask = HALF4( normalTexel.xyz * 2.0h - 1.0h, normalTexel.a );
  412. vNormal.xyz = lerp( vNormalMask.xyz, vNormal.xyz, vNormalMask.a ); // Mask out normals from vNormal
  413. specularFactor = vNormalMask.a;
  414. #else // BUMPMASK == 0
  415. #if ADDBUMPMAPS == 1
  416. vNormal.xy *= g_vAddBumpMapScale1;
  417. vNormal2.xy *= g_vAddBumpMapScale2;
  418. vNormal.xyz = normalize( vNormal.xyz + vNormal2.xyz );
  419. #elif (FANCY_BLENDING == 3) && (SELFILLUM == 0) && (PIXELFOGTYPE != PIXEL_FOG_TYPE_HEIGHT) && (SEAMLESS == 0) && defined( SHADER_MODEL_PS_3_0 )
  420. float3 vEdgeNormal = float3( vBlendModulateTexel.xy * 2 - 1, 0.0 );
  421. vEdgeNormal.xy *= g_flLayerNormalEdgePunchInSign;
  422. HALF minedge = max( 0, flBlendModulateFactor - g_flLayerNormalEdgeSoftness );
  423. HALF maxedge = min( 1, flBlendModulateFactor + g_flLayerNormalEdgeSoftness );
  424. float flEdgeWeight = smoothstep( minedge, maxedge, saturate( i.tangentSpaceTranspose0_vertexBlendX.w - g_flLayerNormalEdgeOffset ) );
  425. float flEdgeBlendStrength = ( 1.0 - abs( flEdgeWeight * 2.0 - 1.0 ) ) * g_flLayerNormalEdgeStrength;
  426. flEdgeBlendStrength *= blendfactor;
  427. flEdgeBlendStrength = saturate( flEdgeBlendStrength );
  428. vNormal2.xyz = lerp( vNormal2.xyz, vEdgeNormal.xyz, flEdgeBlendStrength );
  429. vNormal2.xyz = normalize( vNormal2.xyz );
  430. vNormal.xyz = lerp( vNormal.xyz, vNormal2.xyz, blendfactor);
  431. #else
  432. vNormal.xyz = lerp( vNormal.xyz, vNormal2.xyz, blendfactor);
  433. #endif
  434. #endif
  435. if ( bNormalMapAlphaEnvmapMask )
  436. {
  437. specularFactor *= (HALF)vNormal.a;
  438. // Mappers don't like that the 2nd normal alpha contributes to the envmap mask.
  439. //specularFactor *= lerp( vNormal.a, vNormal2.a, blendfactor );
  440. }
  441. }
  442. #else // BUMPMAP2 == 1
  443. {
  444. if ( bNormalMapAlphaEnvmapMask )
  445. {
  446. specularFactor *= (HALF)vNormal.a;
  447. }
  448. }
  449. #endif // BUMPMAP2 == 1
  450. }
  451. else if ( bNormalMapAlphaEnvmapMask )
  452. {
  453. specularFactor *= (HALF)vNormal.a;
  454. }
  455. #if ENVMAPMASK && defined( SHADER_MODEL_PS_3_0 )
  456. {
  457. // note - dropped support for sm2/2b
  458. float2 envmapMaskTexCoord = float2( dot( i.ENVMAPMASKCOORD, g_EnvmapMaskTexCoordTransform[0].xy ) + g_EnvmapMaskTexCoordTransform[0].w,
  459. dot( i.ENVMAPMASKCOORD, g_EnvmapMaskTexCoordTransform[1].xy ) + g_EnvmapMaskTexCoordTransform[1].w );
  460. float3 envmapMask = h3tex2D( EnvmapMaskSampler, envmapMaskTexCoord ).xyz;
  461. #if BASETEXTURE2
  462. {
  463. float2 envmapMaskTexCoord2 = float2( dot( i.ENVMAPMASKCOORD, g_EnvmapMaskTexCoordTransform2[0].xy ) + g_EnvmapMaskTexCoordTransform2[0].w,
  464. dot( i.ENVMAPMASKCOORD, g_EnvmapMaskTexCoordTransform2[1].xy ) + g_EnvmapMaskTexCoordTransform2[1].w );
  465. float3 envmapMask2 = h3tex2D( EnvmapMaskSampler2, envmapMaskTexCoord2 ).xyz;
  466. envmapMask.rgb = lerp( envmapMask.rgb, envmapMask2.rgb, blendfactor );
  467. }
  468. #endif
  469. specularFactor *= envmapMask;
  470. }
  471. #endif
  472. if ( bBaseAlphaEnvmapMask )
  473. {
  474. specularFactor *= 1.0h - blendedAlpha; // Reversing alpha blows!
  475. }
  476. HALF4 albedo = HALF4( 1.0f, 1.0f, 1.0f, 1.0f );
  477. HALF alpha = 1.0h;
  478. albedo *= baseColor;
  479. if (
  480. #if ( DETAIL_BLEND_MODE == TCOMBINE_MASK_BASE_BY_DETAIL_ALPHA )
  481. ( !bDetailTexture ) && // In this mode we must latch alpha post detail lerp blend with base texture (see "alpha *= albedo.a" below)
  482. #endif
  483. ( !bBaseAlphaEnvmapMask && !bSelfIllum )
  484. )
  485. {
  486. alpha *= baseColor.a;
  487. }
  488. float detailBlendFactor = 0.0f;
  489. if ( bDetailTexture )
  490. {
  491. if ( bDetailTexture2 )
  492. {
  493. // combine detail maps and blend factors
  494. detailColor = lerp( detailColor, detailColor2, blendfactor );
  495. detailBlendFactor = lerp( g_DetailBlendFactor, g_Detail2BlendFactor, blendfactor );
  496. }
  497. else
  498. {
  499. detailBlendFactor = g_DetailBlendFactor;
  500. }
  501. albedo = TextureCombine( albedo, detailColor, DETAIL_BLEND_MODE, detailBlendFactor );
  502. #if ( DETAIL_BLEND_MODE == TCOMBINE_MASK_BASE_BY_DETAIL_ALPHA )
  503. alpha *= albedo.a; // In this mode we latch alpha post detail lerp now, #if above ensures that we don't pre-multiply by baseColor.a earlier
  504. #endif
  505. #if ( ( DETAIL_BLEND_MODE == TCOMBINE_MOD2X_SELECT_TWO_PATTERNS ) && !BASETEXTURE2 && !SELFILLUM )
  506. {
  507. // don't do this in the SELFILLUM case since we don't have enough instructions in ps20
  508. specularFactor *= 2.0h * lerp( detailColor.g, detailColor.b, baseColor.a );
  509. }
  510. #endif
  511. }
  512. // The vertex color contains the modulation color + vertex color combined
  513. #if ( SEAMLESS == 0 )
  514. albedo.rgb *= i.vertexColor.rgb;
  515. #endif
  516. // MAINTOL4DMERGEFIXME
  517. //alpha *= i.vertexColor.a * g_flAlpha2; // not sure about this one
  518. alpha *= i.vertexColor.a; // not sure about this one
  519. float flShadowScalar = 0.0;
  520. float flShadow = 1.0;
  521. // Save this off for single-pass flashlight, since we'll still need the SSBump vector, not a real normal
  522. HALF3 vSSBumpVector = vNormal.xyz;
  523. HALF3 diffuseLighting;
  524. if ( bBumpmap && bDiffuseBumpmap )
  525. {
  526. // ssbump
  527. #if ( BUMPMAP == 2 )
  528. #if ( DETAIL_BLEND_MODE == TCOMBINE_SSBUMP_BUMP )
  529. vNormal.xyz *= lerp( HALF3( 1, 1, 1 ), 2 * detailColor.xyz, alpha );
  530. vSSBumpVector = vNormal.xyz;
  531. alpha = 1;
  532. #endif
  533. diffuseLighting = vNormal.x * lightmapColor1.rgb +
  534. vNormal.y * lightmapColor2.rgb +
  535. vNormal.z * lightmapColor3.rgb;
  536. #if ( ( CSM_BLENDING == 1 ) && ( CASCADED_SHADOW_MAPPING ) && ( CASCADE_SIZE > 0 ) )
  537. diffuseLighting = BlendBumpDiffuseLightmapWithCSM( diffuseLighting, lightmapColor1.a, lightmapColor2.a, lightmapColor3.a, vNormal.xyz, worldPos, flShadow, flShadowScalar );
  538. #endif
  539. // SSBump textures are created assuming the shader decodes lighting for each basis vector by taking dot( N, basis )*lightmap.
  540. // But the lightmaps are created assuming that the 3 coeffs sum to 1.0 and are more like barycentric coords than visibility
  541. // along the basis vector...so the lightmap math is really just a weighted average of the 3 directional light maps. So a flat
  542. // normal should have 3 weights each = 0.333. But since ssbump textures are created assuming the other math, a flat normal
  543. // converted into an ssbump texture generates 3 weights each = 0.578, so instead of all 3 weights summing to 1.0, they sum
  544. // to 1.733. To adjust for this, I'm scaling these coefficients by 1 / 1.733 = 0.578. NOTE: I'm not scaling vNormal directly
  545. // since it is used elsewhere for flashlight computations and shouldn't be scaled for that code.
  546. diffuseLighting *= 0.57735025882720947h;
  547. diffuseLighting *= (HALF3)g_TintValuesTimesLightmapScale.rgb;
  548. // now, calculate vNormal for reflection purposes. if vNormal isn't needed, hopefully
  549. // the compiler will eliminate these calculations
  550. vNormal.xyz = normalize( bumpBasis[0]*vNormal.x + bumpBasis[1]*vNormal.y + bumpBasis[2]*vNormal.z);
  551. #else
  552. HALF3 dp;
  553. dp.x = saturate( dot( vNormal.xyz, bumpBasis[0] ) );
  554. dp.y = saturate( dot( vNormal.xyz, bumpBasis[1] ) );
  555. dp.z = saturate( dot( vNormal.xyz, bumpBasis[2] ) );
  556. dp *= dp;
  557. #if ( DETAIL_BLEND_MODE == TCOMBINE_SSBUMP_BUMP )
  558. dp *= 2*detailColor.rgb;
  559. #endif
  560. diffuseLighting = dp.x * lightmapColor1.rgb +
  561. dp.y * lightmapColor2.rgb +
  562. dp.z * lightmapColor3.rgb;
  563. HALF sum = dot( dp, HALF3( 1.0f, 1.0f, 1.0f ) );
  564. #if ( ( CSM_BLENDING == 1 ) && ( CASCADED_SHADOW_MAPPING ) && ( CASCADE_SIZE > 0 ) )
  565. diffuseLighting = BlendBumpDiffuseLightmapWithCSM( diffuseLighting.rgb, lightmapColor1.a, lightmapColor2.a, lightmapColor3.a, dp, worldPos, flShadow, flShadowScalar );
  566. #endif
  567. diffuseLighting *= (HALF3)g_TintValuesTimesLightmapScale.rgb / sum;
  568. #endif
  569. }
  570. else
  571. {
  572. diffuseLighting = lightmapColor1.rgb;
  573. #if ( ( CSM_BLENDING == 1 ) && ( CASCADED_SHADOW_MAPPING ) && ( CASCADE_SIZE > 0 ) )
  574. diffuseLighting = BlendDiffuseLightmapWithCSM( diffuseLighting, lightmapColor1.a, worldPos, flShadow, flShadowScalar );
  575. #endif
  576. diffuseLighting.rgb *= g_TintValuesTimesLightmapScale.rgb;
  577. }
  578. // OLD CSM BLENDING - see above for fixed/improved. This version supports older vrad baked lightmap alpha
  579. // also a catch path for ssbump
  580. #if ( ( ( CSM_BLENDING == 0 ) ) && ( CASCADED_SHADOW_MAPPING ) && ( CASCADE_SIZE > 0 ) )
  581. {
  582. #if !defined( _X360 ) && !defined( _PS3 ) && !defined( SHADER_MODEL_PS_2_B )
  583. if ( g_bCSMEnabled )
  584. {
  585. #endif
  586. // Can't enable dynamic jumps around the Fetch4 shader, because it can't use tex2dlod()
  587. #if ( CSM_MODE != CSM_MODE_ATI_FETCH4 ) && !defined( SHADER_MODEL_PS_2_B )
  588. [branch]
  589. #endif
  590. if ( lightmapColor1.a > 0.0f )
  591. {
  592. float flSunPercent;
  593. if ( bBumpmap && bDiffuseBumpmap )
  594. {
  595. flSunPercent = lightmapColor1.a / ( Luminance( lightmapColor1.rgb + lightmapColor2.rgb + lightmapColor3.rgb ) * 0.3333 );
  596. }
  597. else
  598. {
  599. flSunPercent = lightmapColor1.a / Luminance( lightmapColor1.rgb );
  600. }
  601. flShadow = CSMComputeShadowing( worldPos );
  602. flShadowScalar = 1.0 - ( flSunPercent * ( 1.0 - flShadow ) );
  603. /* Debug - blink full shadows
  604. if ( step( frac( g_flTime * 0.5 ), 0.5 ) )
  605. {
  606. flShadowScalar = 1.0 - lightmapColor1.a;
  607. }
  608. //*/
  609. // Apply csm shadows
  610. diffuseLighting.rgb *= flShadowScalar;
  611. // Desaturate shadow color since we only have a grayscale dim factor
  612. diffuseLighting.rgb = lerp( diffuseLighting.bgr, diffuseLighting.rgb, flShadowScalar * 0.5 + 0.5 );
  613. // debug visualization
  614. // diffuseLighting.rgb = lerp( float3(1.0f-flShadowScalar,1.0f-flShadowScalar,1.0f-flShadowScalar), CSMVisualizeSplit( worldPos ), .3f );
  615. // return float4(diffuseLighting.rgb, 1.0f);
  616. }
  617. #if !defined( _X360 ) && !defined( _PS3 ) && !defined( SHADER_MODEL_PS_2_B )
  618. }
  619. #endif
  620. }
  621. #endif
  622. HALF3 worldSpaceNormal = mul( vNormal.xyz, tangenttranspose );
  623. #if !defined( SHADER_MODEL_PS_2_0 ) && ( FLASHLIGHT == 0 )
  624. diffuseLighting += (HALF3)g_cAmbientColor;
  625. #endif
  626. HALF3 diffuseComponent = albedo.rgb * diffuseLighting;
  627. #if ( defined( _X360 ) || defined( _PS3 ) ) && FLASHLIGHT
  628. // ssbump doesn't pass a normal to the flashlight...it computes shadowing a different way
  629. #if ( BUMPMAP == 2 )
  630. bool bHasNormal = false;
  631. float3 worldPosToLightVector = g_FlashlightPos - worldPos;
  632. HALF3 tangentPosToLightVector;
  633. tangentPosToLightVector.x = dot( worldPosToLightVector, tangenttranspose[0] );
  634. tangentPosToLightVector.y = dot( worldPosToLightVector, tangenttranspose[1] );
  635. tangentPosToLightVector.z = dot( worldPosToLightVector, tangenttranspose[2] );
  636. tangentPosToLightVector = normalize( tangentPosToLightVector );
  637. HALF nDotL = saturate( vSSBumpVector.x*dot( tangentPosToLightVector, bumpBasis[0]) +
  638. vSSBumpVector.y*dot( tangentPosToLightVector, bumpBasis[1]) +
  639. vSSBumpVector.z*dot( tangentPosToLightVector, bumpBasis[2]) );
  640. #else
  641. bool bHasNormal = true;
  642. HALF nDotL = 1.0h;
  643. #endif
  644. bool bShadows = FLASHLIGHTSHADOWS ? true : false;
  645. HALF3 flashlightColor = DoFlashlight( g_FlashlightPos, worldPos, i.flashlightSpacePos,
  646. worldSpaceNormal, g_FlashlightAttenuationFactors.xyz,
  647. g_FlashlightAttenuationFactors.w, FlashlightSampler, ShadowDepthSampler,
  648. RandRotSampler, 0, bShadows, i.vProjPos.xy / i.vProjPos.w, false, g_ShadowTweaks, bHasNormal );
  649. diffuseComponent = albedo.xyz * ( diffuseLighting + ( flashlightColor * nDotL * (HALF3)g_TintValuesWithoutLightmapScale.rgb ) );
  650. #endif
  651. if ( bSelfIllum )
  652. {
  653. HALF3 selfIllumComponent = (HALF3)g_SelfIllumTint.xyz * albedo.xyz;
  654. diffuseComponent = lerp( diffuseComponent, selfIllumComponent, baseColor.a );
  655. }
  656. HALF3 specularLighting = HALF3( 0.0f, 0.0f, 0.0f );
  657. #if ( CUBEMAP )
  658. {
  659. float3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, worldVertToEyeVector );
  660. // Calc Fresnel factor
  661. HALF3 eyeVect = normalize(worldVertToEyeVector);
  662. HALF fresnel = 1.0h - dot( worldSpaceNormal, eyeVect );
  663. #if ( ENVMAPANISOTROPY ) // For anisotropic reflections on macroscopically rough sufaces like asphalt
  664. // Orthogonalize the view vector to the surface normal, and use it as the anisotropy direction
  665. reflectVect = normalize( reflectVect );
  666. float3 rvec = cross( -eyeVect.xyz, worldSpaceNormal.xyz );
  667. float3 tang = cross( rvec, worldSpaceNormal.xyz );
  668. rvec = cross( tang, reflectVect );
  669. float3 reflectVectAniso = normalize( cross( rvec, worldSpaceNormal.xyz ) );
  670. // Anisotropy amount is influenced by the view angle to the surface. The more oblique the angle the more anisotropic the surface appears.
  671. anisotropyFactor *= dot( reflectVectAniso, -eyeVect );
  672. anisotropyFactor *= anisotropyFactor;
  673. reflectVect = normalize( lerp( reflectVect, reflectVectAniso, anisotropyFactor ) );
  674. #endif
  675. fresnel = max( 0, fresnel ); // precision issues on RSX cause this value to occasionally go negative, which results in a NaN presumably because of the exp(log(n)) operation
  676. fresnel = pow( fresnel, 4.0h ); //changing this to 4th power to save 2 cycles - visually it's very similar
  677. fresnel = fresnel * (HALF)g_OneMinusFresnelReflection + (HALF)g_FresnelReflection;
  678. specularLighting = (HALF)ENV_MAP_SCALE * h3texCUBE( EnvmapSampler, reflectVect ).rgb;
  679. #if (CUBEMAP == 2) //cubemap darkened by lightmap mode
  680. float3 cubemapLight = saturate( ( diffuseLighting - g_fvDiffuseCubemapMin ) * g_fvDiffuseCubemapMax );
  681. specularLighting = lerp( specularLighting, specularLighting * cubemapLight, (HALF)g_DiffuseCubemapScale ); //reduce the cubemap contribution when the pixel is in shadow
  682. #endif
  683. specularLighting *= specularFactor;
  684. specularLighting *= (HALF3)g_EnvmapTint.rgb;
  685. #if FANCY_BLENDING == 0
  686. HALF3 specularLightingSquared = specularLighting * specularLighting;
  687. specularLighting = lerp( specularLighting, specularLightingSquared, (HALF)g_EnvmapContrast );
  688. HALF3 greyScale = dot( specularLighting, HALF3( 0.299f, 0.587f, 0.114f ) );
  689. specularLighting = lerp( greyScale, specularLighting, (HALF)g_EnvmapSaturation );
  690. #endif
  691. specularLighting *= fresnel;
  692. }
  693. #endif
  694. if ( bDetailTexture )
  695. {
  696. diffuseComponent = TextureCombinePostLighting( diffuseComponent, detailColor, DETAIL_BLEND_MODE, detailBlendFactor );
  697. }
  698. // PHONG
  699. #if ( PHONG ) && ( CASCADED_SHADOW_MAPPING )
  700. [branch]
  701. if ( flShadowScalar > 0.0f )
  702. {
  703. float3 phongLighting = float3( 0.0f, 0.0f, 0.0f );
  704. float3 eyeVect = normalize( worldVertToEyeVector );
  705. float3 vLightDir = normalize( g_vCSMLightDir );
  706. float3 vHalfAngle = normalize( eyeVect.xyz + vLightDir.xyz);
  707. // need normalized worldspacenormal here else NDotH raised to phongExp blows up
  708. worldSpaceNormal = normalize(worldSpaceNormal);
  709. float NDotH = saturate( dot( worldSpaceNormal.xyz, vHalfAngle.xyz ) );
  710. float2 phongMask = float2( 0.0f, 0.0f );
  711. float2 phongTerm = float2( 0.0f, 0.0f );
  712. // greyscale phong mask
  713. phongMask.x = dot( baseColor1.rgb, float3(0.299f, 0.587f, 0.114f) );
  714. // phong lighting
  715. phongTerm.x = pow( NDotH, g_PhongExp ); // Raise to specular exponent
  716. if ( bBaseTexture2 )
  717. {
  718. phongMask.y = dot( baseColor2.rgb, float3(0.299f, 0.587f, 0.114f) );
  719. phongTerm.y = pow( NDotH, g_PhongExp2 );
  720. }
  721. // phong mask contrast, brightness
  722. phongMask.xy = saturate( ( (phongMask.xy - 0.5f) * g_PhongMask_Contrast_and_Brightness.xz ) + 0.5f + g_PhongMask_Contrast_and_Brightness.yw );
  723. // * mask
  724. phongTerm.xy *= phongMask.xy;
  725. // phong lighting material1
  726. phongLighting = phongTerm.xxx * g_PhongAmount.rgb * lerp( float3(1.0f, 1.0f, 1.0f), baseColor1.rgb, g_PhongTint ); // * amount * tint
  727. // material2
  728. if ( bBaseTexture2 )
  729. {
  730. float3 phongLighting2 = phongTerm.yyy * g_PhongAmount2.rgb * lerp( float3(1.0f, 1.0f, 1.0f), baseColor2.rgb, g_PhongTint2 ); // term * mask * amount * tint
  731. // blend
  732. phongLighting = lerp( phongLighting, phongLighting2, blendfactor );
  733. }
  734. #if ( CSM_BLENDING == 1 )
  735. // mask with N.L * ao * baked shadow * dynamic shadow
  736. phongLighting *= flShadow * flShadowScalar * specularFactor;
  737. #else
  738. phongLighting *= pow( saturate( dot( worldSpaceNormal, vLightDir ) ), 0.5f ); // Mask with N.L raised to a power
  739. phongLighting *= flShadow * diffuseLighting * specularFactor; // modulate with csm shadow, diffuse lighting, spec(env map) mask if present
  740. #endif
  741. specularLighting += phongLighting;
  742. #if ( PHONG_DEBUG == 1 )
  743. // debug phong mask
  744. diffuseComponent = 0.0f;
  745. specularLighting = lerp( phongMask.xxx, 0.0f, blendfactor );
  746. specularLighting += lerp( 0.0f, phongMask.yyy, blendfactor );
  747. #endif
  748. }
  749. // use .a channel of phongAmount as a modulator for the diffuse component (useful for debugging, or approximating energy conservation
  750. if ( bBaseTexture2 )
  751. {
  752. diffuseComponent *= lerp( g_PhongAmount.a, g_PhongAmount2.a, blendfactor );
  753. }
  754. else
  755. {
  756. diffuseComponent *= g_PhongAmount.a;
  757. }
  758. #endif
  759. HALF3 result = diffuseComponent + specularLighting;
  760. #if ( LIGHTING_PREVIEW == 3 )
  761. {
  762. return float4( worldSpaceNormal, i.worldPos_projPosZ.w );
  763. }
  764. #endif
  765. #if ( LIGHTING_PREVIEW == 1 )
  766. {
  767. float dotprod = 0.2 + abs( dot( normalize(worldSpaceNormal), normalize(worldVertToEyeVector) ) );
  768. return FinalOutput( float4( dotprod*albedo.xyz*(g_TintValuesTimesLightmapScale.rgb/g_TintValuesTimesLightmapScale.w), alpha ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
  769. }
  770. #endif
  771. #if ( LIGHTING_PREVIEW == 2 )
  772. {
  773. LPREVIEW_PS_OUT ret;
  774. ret.color = float4( albedo.xyz,alpha );
  775. ret.normal = float4( worldSpaceNormal, i.worldPos_projPosZ.w );
  776. ret.position = float4( worldPos, alpha );
  777. ret.flags = float4( 1, 1, 1, alpha );
  778. return FinalOutput( ret, 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
  779. }
  780. #endif
  781. #if ( LIGHTING_PREVIEW == 0 )
  782. {
  783. bool bWriteDepthToAlpha = false;
  784. // ps_2_b and beyond
  785. #if !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0))
  786. bWriteDepthToAlpha = ( WRITE_DEPTH_TO_DESTALPHA != 0 ) && ( WRITEWATERFOGTODESTALPHA == 0 );
  787. #endif
  788. HALF flVertexFogFactor = 0.0h;
  789. // FIXME: Reintroduce support for vertex fog
  790. //#if !HARDWAREFOGBLEND && !DOPIXELFOG
  791. //{
  792. // #if ( SEAMLESS )
  793. // {
  794. // flVertexFogFactor = i.SeamlessTexCoord_fogFactorW.w;
  795. // }
  796. // #else
  797. // {
  798. // flVertexFogFactor = i.baseTexCoord_fogFactorZ.z;
  799. // }
  800. // #endif
  801. //}
  802. //#endif
  803. HALF fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.xyz, worldPos, i.worldPos_projPosZ.w );
  804. //HALF fogFactor = CalcPixelFogFactorSupportsVertexFog( PIXELFOGTYPE, g_FogParams, g_EyePos.xyz, worldPos, i.worldPos_projPosZ.w, flVertexFogFactor );
  805. #if WRITEWATERFOGTODESTALPHA && (PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT)
  806. alpha = fogFactor;
  807. #endif
  808. float4_color_return_type vOutput = FinalOutputHalf( HALF4( result.rgb, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, bWriteDepthToAlpha, i.worldPos_projPosZ.w );
  809. #if ( defined( _X360 ) )
  810. {
  811. vOutput.xyz += ScreenSpaceOrderedDither( i.vScreenPos );
  812. }
  813. #endif
  814. return vOutput;
  815. }
  816. #endif
  817. }