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.

559 lines
17 KiB

  1. //========== Copyright (c) Valve Corporation, All rights reserved. ==========//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. // Dummy build counter (used to force all shaders to be rebuilt): 33
  8. //
  9. //===========================================================================//
  10. #ifndef COMMON_FXC_H_
  11. #define COMMON_FXC_H_
  12. #if defined( _PS3 ) || defined( _X360 )
  13. # define _GAMECONSOLE 1
  14. #endif
  15. #include "common_pragmas.h"
  16. #include "common_hlsl_cpp_consts.h"
  17. #if defined( NV3X ) || defined( _PS3 )
  18. # define HALF half
  19. # define HALF2 half2
  20. # define HALF3 half3
  21. # define HALF4 half4
  22. # define HALF3x3 half3x3
  23. # define HALF3x4 half3x4
  24. # define HALF4x3 half4x3
  25. # define HALF_CONSTANT( _constant ) ((HALF)_constant)
  26. #else
  27. # define HALF float
  28. # define HALF2 float2
  29. # define HALF3 float3
  30. # define HALF4 float4
  31. # define HALF3x3 float3x3
  32. # define HALF3x4 float3x4
  33. # define HALF4x3 float4x3
  34. # define HALF_CONSTANT( _constant ) _constant
  35. # define h4tex2D tex2D
  36. # define h3tex2D tex2D
  37. # define h3texCUBE texCUBE
  38. # define h4texCUBE texCUBE
  39. #endif
  40. #ifdef _PS3
  41. #define TEXCOORD0_centroid TEXCOORD0
  42. #define TEXCOORD1_centroid TEXCOORD1
  43. #define TEXCOORD2_centroid TEXCOORD2
  44. #define TEXCOORD3_centroid TEXCOORD3
  45. #define TEXCOORD4_centroid TEXCOORD4
  46. #define TEXCOORD5_centroid TEXCOORD5
  47. #define TEXCOORD6_centroid TEXCOORD6
  48. #define TEXCOORD7_centroid TEXCOORD7
  49. #endif
  50. #define FP16_MAX 65504.0f
  51. // This is where all common code for both vertex and pixel shaders.
  52. #define OO_SQRT_3 0.57735025882720947f
  53. static const HALF3 bumpBasis[3] = {
  54. HALF3( 0.81649661064147949f, 0.0f, OO_SQRT_3 ),
  55. HALF3( -0.40824833512306213f, 0.70710676908493042f, OO_SQRT_3 ),
  56. HALF3( -0.40824821591377258f, -0.7071068286895752f, OO_SQRT_3 )
  57. };
  58. static const HALF3 bumpBasisTranspose[3] = {
  59. HALF3( 0.81649661064147949f, -0.40824833512306213f, -0.40824833512306213f ),
  60. HALF3( 0.0f, 0.70710676908493042f, -0.7071068286895752f ),
  61. HALF3( OO_SQRT_3, OO_SQRT_3, OO_SQRT_3 )
  62. };
  63. #if defined( _X360 )
  64. #define REVERSE_DEPTH_ON_X360 //uncomment to use D3DFMT_D24FS8 with an inverted depth viewport for better performance. Keep this in sync with the same named #define in public/shaderapi/shareddefs.h
  65. //Note that the reversal happens in the viewport. So ONLY reading back from a depth texture should be affected. Projected math is unaffected.
  66. #endif
  67. bool IsX360( void )
  68. {
  69. #if defined( _X360 )
  70. return true;
  71. #else
  72. return false;
  73. #endif
  74. }
  75. bool IsSonyPS3( void )
  76. {
  77. #if defined( _PS3 )
  78. return true;
  79. #else
  80. return false;
  81. #endif
  82. }
  83. bool IsGameConsole( void )
  84. {
  85. #if defined( _GAMECONSOLE )
  86. return true;
  87. #else
  88. return false;
  89. #endif
  90. }
  91. #if defined( _PS3 )
  92. #define hlsl_float4x3_element( MATRIX,ROW4,COL3 ) ((MATRIX)[COL3][ROW4])
  93. #define hlsl_float4x3 float3x4
  94. #else
  95. #define hlsl_float4x3_element( MATRIX,ROW4,COL3 ) ((MATRIX)[ROW4][COL3])
  96. #define hlsl_float4x3 float4x3
  97. #endif
  98. // For CS:GO
  99. //#define SOFTEN_COSINE_EXP 1.5
  100. float SoftenCosineTerm( float flDot )
  101. {
  102. return ( flDot + ( flDot * flDot ) ) * 0.5;
  103. //return rsqrt( flDot ) * ( flDot * flDot );
  104. //return pow( flDot, SOFTEN_COSINE_EXP );
  105. }
  106. float3 CalcReflectionVectorNormalized( float3 normal, float3 eyeVector )
  107. {
  108. // FIXME: might be better of normalizing with a normalizing cube map and
  109. // get rid of the dot( normal, normal )
  110. // compute reflection vector r = 2 * ((n dot v)/(n dot n)) n - v
  111. return 2.0 * ( dot( normal, eyeVector ) / dot( normal, normal ) ) * normal - eyeVector;
  112. }
  113. float3 CalcReflectionVectorUnnormalized( float3 normal, float3 eyeVector )
  114. {
  115. // FIXME: might be better of normalizing with a normalizing cube map and
  116. // get rid of the dot( normal, normal )
  117. // compute reflection vector r = 2 * ((n dot v)/(n dot n)) n - v
  118. // multiply all values through by N.N. uniformly scaling reflection vector won't affect result
  119. // since it is used in a cubemap lookup
  120. return (2.0*(dot( normal, eyeVector ))*normal) - (dot( normal, normal )*eyeVector);
  121. }
  122. float3 HuePreservingColorClamp( float3 c )
  123. {
  124. // Get the max of all of the color components and a specified maximum amount
  125. float maximum = max( max( c.x, c.y ), max( c.z, 1.0f ) );
  126. return (c / maximum);
  127. }
  128. float3 HuePreservingColorClamp( float3 c, float maxVal )
  129. {
  130. // Get the max of all of the color components and a specified maximum amount
  131. float maximum = max( max( c.x, c.y ), max( c.z, maxVal ) );
  132. return (c * ( maxVal / maximum ) );
  133. }
  134. #if (AA_CLAMP==1)
  135. float2 ComputeLightmapCoordinates( float4 Lightmap1and2Coord, float2 Lightmap3Coord )
  136. {
  137. float2 result = saturate(Lightmap1and2Coord.xy) * Lightmap1and2Coord.wz * 0.99;
  138. result += Lightmap3Coord;
  139. return result;
  140. }
  141. void ComputeBumpedLightmapCoordinates( float4 Lightmap1and2Coord, float2 Lightmap3Coord,
  142. out float2 bumpCoord1,
  143. out float2 bumpCoord2,
  144. out float2 bumpCoord3 )
  145. {
  146. float2 result = saturate(Lightmap1and2Coord.xy) * Lightmap1and2Coord.wz * 0.99;
  147. result += Lightmap3Coord;
  148. bumpCoord1 = result + float2(Lightmap1and2Coord.z, 0);
  149. bumpCoord2 = result + 2*float2(Lightmap1and2Coord.z, 0);
  150. bumpCoord3 = result + 3*float2(Lightmap1and2Coord.z, 0);
  151. }
  152. #else
  153. float2 ComputeLightmapCoordinates( float4 Lightmap1and2Coord, float2 Lightmap3Coord )
  154. {
  155. return Lightmap1and2Coord.xy;
  156. }
  157. void ComputeBumpedLightmapCoordinates( float4 Lightmap1and2Coord, float2 Lightmap3Coord,
  158. out float2 bumpCoord1,
  159. out float2 bumpCoord2,
  160. out float2 bumpCoord3 )
  161. {
  162. bumpCoord1 = Lightmap1and2Coord.xy;
  163. bumpCoord2 = Lightmap1and2Coord.wz; // reversed order!!!
  164. bumpCoord3 = Lightmap3Coord.xy;
  165. }
  166. #endif
  167. // Versions of matrix multiply functions which force HLSL compiler to explictly use DOTs,
  168. // not giving it the option of using MAD expansion. In a perfect world, the compiler would
  169. // always pick the best strategy, and these shouldn't be needed.. but.. well.. umm..
  170. //
  171. // lorenmcq
  172. float3 mul3x3(float3 v, float3x3 m)
  173. {
  174. #if defined( _PS3 )
  175. return mul( m, v );
  176. #elif !defined( _X360 )
  177. return float3(dot(v, transpose(m)[0]), dot(v, transpose(m)[1]), dot(v, transpose(m)[2]));
  178. #else
  179. // xbox360 fxc.exe (new back end) borks with transposes, generates bad code
  180. return mul( v, m );
  181. #endif
  182. }
  183. float3 mul4x3(float4 v, hlsl_float4x3 m)
  184. {
  185. #if defined( _PS3 )
  186. return mul( m, v );
  187. #elif !defined( _X360 )
  188. return float3(dot(v, transpose(m)[0]), dot(v, transpose(m)[1]), dot(v, transpose(m)[2]));
  189. #else
  190. // xbox360 fxc.exe (new back end) borks with transposes, generates bad code
  191. return mul( v, m );
  192. #endif
  193. }
  194. float3 DecompressHDR( float4 input )
  195. {
  196. return input.rgb * input.a * MAX_HDR_OVERBRIGHT;
  197. }
  198. float4 CompressHDR( float3 input )
  199. {
  200. // FIXME: want to use min so that we clamp to white, but what happens if we
  201. // have an albedo component that's less than 1/MAX_HDR_OVERBRIGHT?
  202. // float fMax = max( max( color.r, color.g ), color.b );
  203. float4 output;
  204. float fMax = min( min( input.r, input.g ), input.b );
  205. if( fMax > 1.0f )
  206. {
  207. float oofMax = 1.0f / fMax;
  208. output.rgb = oofMax * input.rgb;
  209. output.a = min( fMax / MAX_HDR_OVERBRIGHT, 1.0f );
  210. }
  211. else
  212. {
  213. output.rgb = input.rgb;
  214. output.a = 0.0f;
  215. }
  216. return output;
  217. }
  218. // 2.2 gamma conversion routines
  219. float LinearToGamma( const float f1linear )
  220. {
  221. return pow( f1linear, 1.0f / 2.2f );
  222. }
  223. float3 LinearToGamma( const float3 f3linear )
  224. {
  225. return pow( f3linear, 1.0f / 2.2f );
  226. }
  227. float4 LinearToGamma( const float4 f4linear )
  228. {
  229. return float4( pow( f4linear.xyz, 1.0f / 2.2f ), f4linear.w );
  230. }
  231. float GammaToLinear( const float gamma )
  232. {
  233. return pow( gamma, 2.2f );
  234. }
  235. float3 GammaToLinear( const float3 gamma )
  236. {
  237. return pow( gamma, 2.2f );
  238. }
  239. float4 GammaToLinear( const float4 gamma )
  240. {
  241. return float4( pow( gamma.xyz, 2.2f ), gamma.w );
  242. }
  243. // sRGB gamma conversion routines
  244. float3 SrgbGammaToLinear( float3 vSrgbGammaColor )
  245. {
  246. // 15 asm instructions
  247. float3 vLinearSegment = vSrgbGammaColor.rgb / 12.92f;
  248. float3 vExpSegment = pow( ( ( vSrgbGammaColor.rgb / 1.055f ) + ( 0.055f / 1.055f ) ), 2.4f );
  249. float3 vLinearColor = { ( vSrgbGammaColor.r <= 0.04045f ) ? vLinearSegment.r : vExpSegment.r,
  250. ( vSrgbGammaColor.g <= 0.04045f ) ? vLinearSegment.g : vExpSegment.g,
  251. ( vSrgbGammaColor.b <= 0.04045f ) ? vLinearSegment.b : vExpSegment.b };
  252. return vLinearColor.rgb;
  253. }
  254. HALF3 h3SrgbGammaToLinear( HALF3 vSrgbGammaColor )
  255. {
  256. // 15 asm instructions
  257. HALF3 vLinearSegment = vSrgbGammaColor.rgb / 12.92h;
  258. HALF3 vExpSegment = pow( ( ( vSrgbGammaColor.rgb / 1.055h) + ( 0.055h / 1.055h ) ), 2.4h );
  259. HALF3 vLinearColor = { ( vSrgbGammaColor.r <= 0.04045h ) ? vLinearSegment.r : vExpSegment.r,
  260. ( vSrgbGammaColor.g <= 0.04045h ) ? vLinearSegment.g : vExpSegment.g,
  261. ( vSrgbGammaColor.b <= 0.04045h ) ? vLinearSegment.b : vExpSegment.b };
  262. return vLinearColor.rgb;
  263. }
  264. float3 SrgbLinearToGamma( float3 vLinearColor )
  265. {
  266. // 15 asm instructions
  267. float3 vLinearSegment = vLinearColor.rgb * 12.92f;
  268. float3 vExpSegment = ( 1.055f * pow( vLinearColor.rgb, ( 1.0f / 2.4f ) ) ) - 0.055f;
  269. float3 vGammaColor = { ( vLinearColor.r <= 0.0031308f ) ? vLinearSegment.r : vExpSegment.r,
  270. ( vLinearColor.g <= 0.0031308f ) ? vLinearSegment.g : vExpSegment.g,
  271. ( vLinearColor.b <= 0.0031308f ) ? vLinearSegment.b : vExpSegment.b };
  272. return vGammaColor.rgb;
  273. }
  274. // These two functions use the XBox 360's exact piecewise linear algorithm
  275. float3 X360GammaToLinear( float3 v360GammaColor )
  276. {
  277. // This code reduces the asm down to 11 instructions from the 63 instructions in the 360 XDK
  278. float4 vTmpMul1 = { 1.0f, 2.0f, 4.0f, 8.0f };
  279. float4 vTmpAdd1 = { 0.0f, ( -64.0f / 255.0f ), ( -96.0f / 255.0f ), ( -192.0f / 255.0f ) };
  280. float4 vTmpAdd2 = { 0.0f, ( 64.0f / 255.0f ), ( 128.0f / 255.0f ), ( 513.0f / 255.0f ) };
  281. float4 vRed = ( v360GammaColor.r * vTmpMul1.xyzw * 0.25f ) + ( ( ( vTmpAdd1.xyzw * vTmpMul1.xyzw ) + vTmpAdd2.xyzw ) * 0.25f );
  282. float4 vGreen = ( v360GammaColor.g * vTmpMul1.xyzw * 0.25f ) + ( ( ( vTmpAdd1.xyzw * vTmpMul1.xyzw ) + vTmpAdd2.xyzw ) * 0.25f );
  283. float4 vBlue = ( v360GammaColor.b * vTmpMul1.xyzw * 0.25f ) + ( ( ( vTmpAdd1.xyzw * vTmpMul1.xyzw ) + vTmpAdd2.xyzw ) * 0.25f );
  284. float3 vMax1 = { max( vRed.x, vRed.y ), max( vGreen.x, vGreen.y ), max( vBlue.x, vBlue.y ) };
  285. float3 vMax2 = { max( vRed.z, vRed.w ), max( vGreen.z, vGreen.w ), max( vBlue.z, vBlue.w ) };
  286. float3 vLinearColor = max( vMax1.rgb, vMax2.rgb );
  287. return vLinearColor.rgb;
  288. }
  289. #ifndef _PS3
  290. float X360LinearToGamma( float flLinearValue )
  291. {
  292. // This needs to be optimized
  293. float fl360GammaValue;
  294. flLinearValue = saturate( flLinearValue );
  295. if ( flLinearValue < ( 128.0f / 1023.0f ) )
  296. {
  297. if ( flLinearValue < ( 64.0f / 1023.0f ) )
  298. {
  299. fl360GammaValue = flLinearValue * ( 1023.0f * ( 1.0f / 255.0f ) );
  300. }
  301. else
  302. {
  303. fl360GammaValue = flLinearValue * ( ( 1023.0f / 2.0f ) * ( 1.0f / 255.0f ) ) + ( 32.0f / 255.0f );
  304. }
  305. }
  306. else
  307. {
  308. if ( flLinearValue < ( 512.0f / 1023.0f ) )
  309. {
  310. fl360GammaValue = flLinearValue * ( ( 1023.0f / 4.0f ) * ( 1.0f / 255.0f ) ) + ( 64.0f / 255.0f );
  311. }
  312. else
  313. {
  314. fl360GammaValue = flLinearValue * ( ( 1023.0f /8.0f ) * ( 1.0f / 255.0f ) ) + ( 128.0f /255.0f ); // 1.0 -> 1.0034313725490196078431372549016
  315. fl360GammaValue = saturate( fl360GammaValue );
  316. }
  317. }
  318. fl360GammaValue = saturate( fl360GammaValue );
  319. return fl360GammaValue;
  320. }
  321. float3 X360LinearToGamma( float3 flLinearValue )
  322. {
  323. return float3( X360LinearToGamma( flLinearValue.r ), X360LinearToGamma( flLinearValue.g ), X360LinearToGamma( flLinearValue.b ) );
  324. }
  325. float3 SrgbGammaTo360Gamma( float3 vSrgbGammaColor )
  326. {
  327. float3 vColor = SrgbGammaToLinear( vSrgbGammaColor.rgb );
  328. return X360LinearToGamma( vColor );
  329. }
  330. #endif
  331. // Function to do srgb read in shader code
  332. #ifndef SHADER_SRGB_READ
  333. #define SHADER_SRGB_READ 0
  334. #endif
  335. // comment out to revert to PWL srgb shader reads and gamma RT's
  336. #ifndef CSTRIKE15
  337. #define CSTRIKE15
  338. #endif
  339. float4 tex2Dsrgb( sampler iSampler, float2 iUv )
  340. {
  341. // This function is named as a hint that the texture is meant to be read with
  342. // an sRGB->linear conversion. We have to do this in shader code on the 360 sometimes.
  343. #if ( SHADER_SRGB_READ == 0 )
  344. {
  345. // Don't fake the srgb read in shader code
  346. return tex2D( iSampler, iUv.xy );
  347. }
  348. #else
  349. {
  350. if ( IsX360() )
  351. {
  352. float4 vTextureValue = tex2D( iSampler, iUv.xy );
  353. #if defined( CSTRIKE15 )
  354. // [mariod] - shader gamma read
  355. // assume we don't have a mix of pwl and srgb textures (all source is srgb for CS:GO, and all RT's are already in gamma space and not read through this path)
  356. // GammaToLinear much faster than SrgbGammaToLinear, what is the real quality trade-off?
  357. vTextureValue.rgb = GammaToLinear( vTextureValue.rgb );
  358. //vTextureValue.rgb = SrgbGammaToLinear( vTextureValue.rgb );
  359. #else
  360. vTextureValue.rgb = X360GammaToLinear( vTextureValue.rgb );
  361. #endif
  362. return vTextureValue.rgba;
  363. }
  364. else
  365. {
  366. float4 vTextureValue = tex2D( iSampler, iUv.xy );
  367. vTextureValue.rgb = SrgbGammaToLinear( vTextureValue.rgb );
  368. return vTextureValue.rgba;
  369. }
  370. }
  371. #endif
  372. }
  373. HALF3 h3tex2Dsrgb( sampler iSampler, float2 iUv )
  374. {
  375. // This function is named as a hint that the texture is meant to be read with
  376. // an sRGB->linear conversion. We have to do this in shader code on the 360 sometimes.
  377. #if ( SHADER_SRGB_READ == 0 )
  378. {
  379. // Don't fake the srgb read in shader code
  380. return h3tex2D( iSampler, iUv.xy ).xyz;
  381. }
  382. #else
  383. {
  384. if ( IsX360() )
  385. {
  386. HALF3 vTextureValue = tex2D( iSampler, iUv.xy );
  387. #if defined( CSTRIKE15 )
  388. // [mariod] - shader gamma read
  389. // assume we don't have a mix of pwl and srgb textures (all source is srgb for CS:GO, and all RT's are already in gamma space and not read through this path)
  390. // GammaToLinear much faster than SrgbGammaToLinear, what is the real quality trade-off?
  391. vTextureValue.rgb = GammaToLinear( vTextureValue.rgb );
  392. //vTextureValue.rgb = SrgbGammaToLinear( vTextureValue.rgb );
  393. #else
  394. vTextureValue.rgb = X360GammaToLinear( vTextureValue.rgb );
  395. #endif
  396. return vTextureValue.rgb;
  397. }
  398. else
  399. {
  400. HALF3 vTextureValue = h3tex2D( iSampler, iUv.xy );
  401. vTextureValue.rgb = h3SrgbGammaToLinear( vTextureValue.rgb );
  402. return vTextureValue.rgb;
  403. }
  404. }
  405. #endif
  406. }
  407. HALF4 h4tex2Dsrgb( sampler iSampler, float2 iUv )
  408. {
  409. // This function is named as a hint that the texture is meant to be read with
  410. // an sRGB->linear conversion. We have to do this in shader code on the 360 sometimes.
  411. #if ( SHADER_SRGB_READ == 0 )
  412. {
  413. // Don't fake the srgb read in shader code
  414. return h4tex2D( iSampler, iUv.xy );
  415. }
  416. #else
  417. {
  418. if ( IsX360() )
  419. {
  420. HALF4 vTextureValue = tex2D( iSampler, iUv.xy );
  421. #if defined( CSTRIKE15 )
  422. // [mariod] - shader gamma read
  423. // assume we don't have a mix of pwl and srgb textures (all source is srgb for CS:GO, and all RT's are already in gamma space and not read through this path)
  424. // GammaToLinear much faster than SrgbGammaToLinear, what is the real quality trade-off?
  425. vTextureValue.rgb = GammaToLinear( vTextureValue.rgb );
  426. //vTextureValue.rgb = SrgbGammaToLinear( vTextureValue.rgb );
  427. #else
  428. vTextureValue.rgb = X360GammaToLinear( vTextureValue.rgb );
  429. #endif
  430. return vTextureValue.rgba;
  431. }
  432. else
  433. {
  434. HALF4 vTextureValue = h4tex2D( iSampler, iUv.xy );
  435. vTextureValue.rgb = h3SrgbGammaToLinear( vTextureValue.rgb );
  436. return vTextureValue.rgba;
  437. }
  438. }
  439. #endif
  440. }
  441. // Tangent transform helper functions
  442. float3 Vec3WorldToTangent( float3 iWorldVector, float3 iWorldNormal, float3 iWorldTangent, float3 iWorldBinormal )
  443. {
  444. float3 vTangentVector;
  445. vTangentVector.x = dot( iWorldVector.xyz, iWorldTangent.xyz );
  446. vTangentVector.y = dot( iWorldVector.xyz, iWorldBinormal.xyz );
  447. vTangentVector.z = dot( iWorldVector.xyz, iWorldNormal.xyz );
  448. return vTangentVector.xyz; // Return without normalizing
  449. }
  450. float3 Vec3WorldToTangentNormalized( float3 iWorldVector, float3 iWorldNormal, float3 iWorldTangent, float3 iWorldBinormal )
  451. {
  452. return normalize( Vec3WorldToTangent( iWorldVector, iWorldNormal, iWorldTangent, iWorldBinormal ) );
  453. }
  454. float3 Vec3TangentToWorld( float3 iTangentVector, float3 iWorldNormal, float3 iWorldTangent, float3 iWorldBinormal )
  455. {
  456. float3 vWorldVector;
  457. vWorldVector.xyz = iTangentVector.x * iWorldTangent.xyz;
  458. vWorldVector.xyz += iTangentVector.y * iWorldBinormal.xyz;
  459. vWorldVector.xyz += iTangentVector.z * iWorldNormal.xyz;
  460. return vWorldVector.xyz; // Return without normalizing
  461. }
  462. float3 Vec3TangentToWorldNormalized( float3 iTangentVector, float3 iWorldNormal, float3 iWorldTangent, float3 iWorldBinormal )
  463. {
  464. return normalize( Vec3TangentToWorld( iTangentVector, iWorldNormal, iWorldTangent, iWorldBinormal ) );
  465. }
  466. // returns 1.0f for no fog, 0.0f for fully fogged
  467. float CalcRangeFogFactorFixedFunction( float3 worldPos, float3 eyePos, float flFogMaxDensity, float flFogEndOverRange, float flFogOORange )
  468. {
  469. float dist = distance( eyePos.xyz, worldPos.xyz );
  470. return max( flFogMaxDensity, ( -dist * flFogOORange ) + flFogEndOverRange );
  471. }
  472. // returns 0.0f for no fog, 1.0f for fully fogged which is opposite of what fixed function fog expects so that we don't have to do a "1-x" in the pixel shader.
  473. float CalcRangeFogFactorNonFixedFunction( float3 worldPos, float3 eyePos, float flFogMaxDensity, float flFogEndOverRange, float flFogOORange )
  474. {
  475. float dist = distance( eyePos.xyz, worldPos.xyz );
  476. return min( flFogMaxDensity, saturate( flFogEndOverRange + ( dist * flFogOORange ) ) );
  477. }
  478. float4 TransformFlashlightWorldToTexture( float3 vWorldPos, float4x4 vFlashlightWorldToTexture )
  479. {
  480. #ifdef _PS3
  481. float4 vSpotTexCoord = mul( vFlashlightWorldToTexture, float4( vWorldPos, 1.0f ) );
  482. #else // _PS3
  483. float4 vSpotTexCoord = mul( float4( vWorldPos, 1.0f ), vFlashlightWorldToTexture );
  484. #endif // !_PS3
  485. return vSpotTexCoord;
  486. }
  487. #endif //#ifndef COMMON_FXC_H_