Team Fortress 2 Source Code as on 22/4/2020
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.

339 lines
8.8 KiB

  1. // DYNAMIC: "MODE" "0..9"
  2. // STATIC: "CONVERT_TO_SRGB" "0..1" [ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC]
  3. // STATIC: "CONVERT_TO_SRGB" "0..0" [= 0] [XBOX]
  4. // STATIC: "LINEAR_TO_SRGB" "0..1" [ps20b]
  5. #define HDRTYPE HDR_TYPE_NONE
  6. #include "common_ps_fxc.h"
  7. const float g_Alpha : register( c0 );
  8. sampler BaseTextureSampler : register( s0 );
  9. sampler BaseTextureSampler2 : register( s1 );
  10. struct PS_INPUT
  11. {
  12. float2 baseTexCoord : TEXCOORD0;
  13. };
  14. float3 RGBtoHSV( in float3 rgb )
  15. {
  16. float3 hsv;
  17. float fmin, fmax, delta;
  18. fmin = min( min( rgb.r, rgb.g ), rgb.b );
  19. fmax = max( max( rgb.r, rgb.g) , rgb.b );
  20. hsv.b = fmax; // v
  21. delta = fmax - fmin;
  22. if( delta != 0 )
  23. {
  24. hsv.g = delta / fmax; // s
  25. if( rgb.r == fmax )
  26. hsv.r = ( rgb.g - rgb.b ) / delta; // between yellow & magenta
  27. else if( rgb.g == fmax )
  28. hsv.r = 2 + ( rgb.b - rgb.r ) / delta; // between cyan & yellow
  29. else
  30. hsv.r = 4 + ( rgb.r - rgb.g ) / delta; // between magenta & cyan
  31. hsv.r *= 60; // degrees
  32. if( hsv.r < 0 )
  33. hsv.r += 360;
  34. }
  35. else
  36. {
  37. // r = g = b = 0 // s = 0, v is undefined
  38. hsv.g = 0;
  39. hsv.r = -1;
  40. }
  41. return hsv;
  42. }
  43. float3 HSVtoRGB( in float3 hsv )
  44. {
  45. int i;
  46. float3 rgb;
  47. float h = hsv.r;
  48. float s = hsv.g;
  49. float v = hsv.b;
  50. float f, p, q, t;
  51. if( s == 0 )
  52. {
  53. // achromatic (grey)
  54. rgb.rgb = v;
  55. }
  56. else
  57. {
  58. h /= 60; // sector 0 to 5
  59. i = floor( h );
  60. f = h - i; // factorial part of h
  61. p = v * ( 1 - s );
  62. q = v * ( 1 - s * f );
  63. t = v * ( 1 - s * ( 1 - f ) );
  64. if( h < 1)
  65. {
  66. rgb.r = v;
  67. rgb.g = t;
  68. rgb.b = p;
  69. }
  70. else if( h >= 1 && h < 2 )
  71. {
  72. rgb.r = q;
  73. rgb.g = v;
  74. rgb.b = p;
  75. }
  76. else if( h >= 2 && h < 3 )
  77. {
  78. rgb.r = p;
  79. rgb.g = v;
  80. rgb.b = t;
  81. }
  82. else if( h >= 3 && h < 4 )
  83. {
  84. rgb.r = p;
  85. rgb.g = q;
  86. rgb.b = v;
  87. }
  88. else if( h >= 4 && h < 5 )
  89. {
  90. rgb.r = t;
  91. rgb.g = p;
  92. rgb.b = v;
  93. }
  94. else // if ( h >= 5 )
  95. {
  96. rgb.r = v;
  97. rgb.g = p;
  98. rgb.b = q;
  99. }
  100. }
  101. return rgb;
  102. }
  103. // We have to run through this input converter on OpenGL if the
  104. // rest of the shader code is expecting sRGB values
  105. float3 SampleTexture( sampler texSampler, float2 tc )
  106. {
  107. float3 c = tex2D( texSampler, tc ).xyz;
  108. #if ( LINEAR_TO_SRGB )
  109. {
  110. c = LinearToGamma( c );
  111. }
  112. #endif
  113. return c;
  114. }
  115. // We have to run through this output converter on OpenGL if we
  116. // expect to be writing out sRGB values (since sRGB will be forced on)
  117. float3 OutputColor( float3 result )
  118. {
  119. #if ( LINEAR_TO_SRGB )
  120. {
  121. return GammaToLinear( result );
  122. }
  123. #endif
  124. return result;
  125. }
  126. float4 main( PS_INPUT i ) : COLOR
  127. {
  128. float3 result;
  129. #if MODE == 0
  130. // negative greyscale of scene * gman
  131. float3 scene = SampleTexture( BaseTextureSampler, i.baseTexCoord );
  132. float3 gman = SampleTexture( BaseTextureSampler2, i.baseTexCoord );
  133. float scale = 1.0f / 3.0f;
  134. scene.xyz = dot( float3( scale, scale, scale), scene.xyz );
  135. scene = float3( 1, 1, 1 ) - scene;
  136. return FinalOutput( float4( OutputColor( scene * gman ), g_Alpha ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
  137. #endif
  138. #if MODE == 1
  139. float3 scene = SampleTexture( BaseTextureSampler, i.baseTexCoord );
  140. float3 gman = SampleTexture( BaseTextureSampler2, i.baseTexCoord );
  141. float scale = 1.0f / 3.0f;
  142. scene.xyz = dot( float3( scale, scale, scale ), scene.xyz );
  143. float gmanLum = dot( float3( scale, scale, scale ), gman );
  144. if( gmanLum < 0.3 )
  145. {
  146. result = OutputColor( float3( 1, 1, 1 ) - gman );
  147. return FinalOutput( float4( result, g_Alpha ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
  148. }
  149. else
  150. {
  151. result = OutputColor( ( float3( 1, 1, 1 ) - gman ) * scene );
  152. return FinalOutput( float4( result, g_Alpha ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
  153. }
  154. #endif
  155. #if MODE == 2
  156. float3 scene = SampleTexture( BaseTextureSampler, i.baseTexCoord );
  157. float3 gman = SampleTexture( BaseTextureSampler2, i.baseTexCoord );
  158. float startRamp = .2;
  159. float endRamp = .5;
  160. float scale = 1.0f / 3.0f;
  161. float gmanLum = dot( float3( scale, scale, scale ), gman );
  162. float sceneLum = dot( float3( scale, scale, scale ), scene );
  163. float blend = ( gmanLum - startRamp ) * ( 1.0f / ( endRamp - startRamp ) );
  164. blend = saturate( blend );
  165. // return gmanLum * ( 1.0f - blend ) + scene * blend;
  166. result = OutputColor( min( gmanLum.xxx, scene ) );
  167. return FinalOutput( float4( result, g_Alpha ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
  168. #endif
  169. #if MODE == 3
  170. float3 scene = SampleTexture( BaseTextureSampler, i.baseTexCoord );
  171. float3 gman = SampleTexture( BaseTextureSampler2, i.baseTexCoord );
  172. float scale = 1.0f / 3.0f;
  173. float gmanLum = dot( float3( scale, scale, scale ), gman );
  174. float sceneLum = dot( float3( scale, scale, scale ), scene );
  175. float a = 0.0f;
  176. float b = 0.4f;
  177. float c = 0.7f;
  178. float d = 1.0f;
  179. float blend;
  180. if( gmanLum < b )
  181. {
  182. blend = ( gmanLum - a ) / ( b - a );
  183. }
  184. else if( gmanLum > c )
  185. {
  186. blend = 1.0f - ( ( gmanLum - c) / ( d - c ) );
  187. }
  188. else
  189. {
  190. blend = 1.0f;
  191. }
  192. blend = saturate( blend );
  193. result = OutputColor( gmanLum.xxx * ( float3( 1, 1, 1 ) - blend.xxx ) + scene * blend.xxx );
  194. return FinalOutput( float4( result, g_Alpha ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
  195. #endif
  196. #if MODE == 4
  197. float3 scene = SampleTexture( BaseTextureSampler, i.baseTexCoord );
  198. float3 gman = SampleTexture( BaseTextureSampler2, i.baseTexCoord );
  199. float scale = 1.0f / 3.0f;
  200. float gmanLum = dot( float3( scale, scale, scale ), gman );
  201. float sceneLum = dot( float3( scale, scale, scale ), scene );
  202. float a = 0.0f;
  203. float b = 0.4f;
  204. float c = 0.7f;
  205. float d = 1.0f;
  206. float blend;
  207. if( gmanLum < b )
  208. {
  209. blend = ( gmanLum - a ) / ( b - a );
  210. }
  211. else if( gmanLum > c )
  212. {
  213. blend = 1.0f - ( ( gmanLum - c) / ( d - c ) );
  214. }
  215. else
  216. {
  217. blend = 1.0f;
  218. }
  219. blend = saturate( blend );
  220. result = OutputColor( gman * ( float3( 1, 1, 1 ) - blend.xxx ) + scene * blend.xxx );
  221. return FinalOutput( float4( result, g_Alpha ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
  222. #endif
  223. #if MODE == 5
  224. float3 scene = SampleTexture( BaseTextureSampler, i.baseTexCoord );
  225. float3 gman = SampleTexture( BaseTextureSampler2, i.baseTexCoord );
  226. float scale = 1.0f / 3.0f;
  227. // float sceneLum = dot( float3( scale, scale, scale ), scene );
  228. float sceneLum = scene.r;
  229. if( sceneLum > 0.0f )
  230. {
  231. return FinalOutput( float4( OutputColor( scene ), g_Alpha ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
  232. }
  233. else
  234. {
  235. float3 hsv = RGBtoHSV( gman );
  236. // float blend = saturate( hsv.b - .5 );
  237. float blend = hsv.b - .5;
  238. hsv.b *= 1.0f + blend;
  239. hsv.g *= 1.0f - blend;
  240. return FinalOutput( float4( OutputColor( HSVtoRGB( hsv ) ), g_Alpha ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
  241. }
  242. #endif
  243. #if MODE == 6
  244. float3 scene = SampleTexture( BaseTextureSampler, i.baseTexCoord );
  245. float3 gman = SampleTexture( BaseTextureSampler2, i.baseTexCoord );
  246. return FinalOutput( float4( OutputColor( scene + gman ), g_Alpha ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
  247. #endif
  248. #if MODE == 7
  249. float3 scene = SampleTexture( BaseTextureSampler, i.baseTexCoord );
  250. return FinalOutput( float4( OutputColor( scene ), g_Alpha ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
  251. #endif
  252. #if MODE == 8
  253. float3 gman = SampleTexture( BaseTextureSampler2, i.baseTexCoord );
  254. return FinalOutput( float4( OutputColor( gman ), g_Alpha ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
  255. #endif
  256. #if MODE == 9
  257. // Fetch textures
  258. float3 cLayer1 = SampleTexture( BaseTextureSampler, i.baseTexCoord.xy );
  259. float3 cLayer2 = SampleTexture( BaseTextureSampler2, i.baseTexCoord.xy );
  260. /*
  261. // Put colors roughly back into gamma space
  262. float3 cGammaLayer1 = pow( cLayer1, 0.454545f );
  263. float3 cGammaLayer2 = pow( cLayer2, 0.454545f );
  264. // Brightness
  265. //float flLayer1Brightness = saturate( dot( cGammaLayer1.rgb, float3( 0.3f, 0.59f, 0.11f ) ) );
  266. //float flLayer2Brightness = saturate( dot( cGammaLayer2.rgb, float3( 0.3f, 0.59f, 0.11f ) ) );
  267. float flLayer1Brightness = saturate( dot( cGammaLayer1.rgb, float3( 0.333f, 0.334f, 0.333f ) ) );
  268. float flLayer2Brightness = saturate( dot( cGammaLayer2.rgb, float3( 0.333f, 0.334f, 0.333f ) ) );
  269. // Blend layers in rough gamma space
  270. float3 cGammaOverlayResult;
  271. if ( flLayer1Brightness < 0.5f )
  272. {
  273. cGammaOverlayResult.rgb = ( 2.0f * cGammaLayer1.rgb * cGammaLayer2.rgb );
  274. }
  275. else
  276. {
  277. cGammaOverlayResult.rgb = ( 1.0f - ( 2.0f * ( 1.0f - cGammaLayer1.rgb ) * ( 1.0f - cGammaLayer2.rgb ) ) );
  278. }
  279. // Convert back to linear space
  280. float3 cLinearOverlayResult = pow( cGammaOverlayResult.rgb, 2.2f );
  281. //*/
  282. float flLayer1Brightness = saturate( dot( cLayer1.rgb, float3( 0.333f, 0.334f, 0.333f ) ) );
  283. float flLayer2Brightness = saturate( dot( cLayer2.rgb, float3( 0.333f, 0.334f, 0.333f ) ) );
  284. // Modify layer 1 to be more contrasty
  285. cLayer1.rgb = saturate( cLayer1.rgb * cLayer1.rgb * 2.0f );
  286. float3 cLinearOverlayResult = cLayer1.rgb + cLayer2.rgb * saturate( 1.0f - flLayer1Brightness * 2.0f );
  287. // Tonemap, fog, etc.
  288. return FinalOutput( float4( OutputColor( cLinearOverlayResult.rgb ), g_Alpha ), 0, PIXEL_FOG_TYPE_NONE, TONEMAP_SCALE_NONE );
  289. #endif
  290. }