hdr.hlsl
上传用户:xhbjoy
上传日期:2014-10-07
资源大小:38068k
文件大小:5k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. // RGBE mode utilities
  2. // RGB each carry a mantissa, A carries a shared exponent
  3. // The exponent is calculated based on the largest colour channel
  4. float3 decodeRGBE8(in float4 rgbe)
  5. {
  6.     // get exponent (-128 since it can be +ve or -ve)
  7. float exp = rgbe.a * 255 - 128;
  8. // expand out the rgb value
  9. return rgbe.rgb * exp2(exp);
  10. }
  11. float4 encodeRGBE8(in float3 rgb)
  12. {
  13. float4 ret;
  14.     // What is the largest colour channel?
  15. float highVal = max(rgb.r, max(rgb.g, rgb.b));
  16. // Take the logarithm, clamp it to a whole value
  17. float exp = ceil(log2(highVal));
  18.     // Divide the components by the shared exponent
  19. ret.rgb = rgb / exp2(exp);
  20. // Store the shared exponent in the alpha channel
  21. ret.a = (exp + 128) / 255;
  22. return ret;
  23. }
  24. static const float4 LUMINENCE_FACTOR  = float4(0.27f, 0.67f, 0.06f, 0.0f);
  25. static const float MIDDLE_GREY = 0.72f;
  26. static const float FUDGE = 0.001f;
  27. static const float L_WHITE = 1.5f;
  28. static const float4 BRIGHT_LIMITER = float4(0.6f, 0.6f, 0.6f, 0.0f);
  29. /** Tone mapping function 
  30. @note Only affects rgb, not a
  31. @param inColour The HDR colour
  32. @param lum The scene lumninence 
  33. @returns Tone mapped colour
  34. */
  35. float4 toneMap(float4 inColour, float lum)
  36. {
  37. // From Reinhard et al
  38. // "Photographic Tone Reproduction for Digital Images"
  39. // Initial luminence scaling (equation 2)
  40.     inColour.rgb *= MIDDLE_GREY / (FUDGE + lum);
  41. // Control white out (equation 4 nom)
  42.     inColour.rgb *= (1.0f + inColour / L_WHITE);
  43. // Final mapping (equation 4 denom)
  44. inColour.rgb /= (1.0f + inColour);
  45. return inColour;
  46. }
  47. /* Downsample a 2x2 area and convert to greyscale
  48. */
  49. float4 downscale2x2Luminence(
  50. float2 uv : TEXCOORD0,
  51. uniform sampler2D inRTT : register(s0)
  52.     ) : COLOR
  53. {
  54.     float4 accum = float4(0.0f, 0.0f, 0.0f, 0.0f);
  55. // Approximate ratio from viewport to texture
  56. float2 texelSize = 0.005;
  57. float2 texOffset[4] = {
  58. -0.5, -0.5,
  59. -0.5,  0.5, 
  60.  0.5, -0.5,
  61.  0.5, 0.5 };
  62. for( int i = 0; i < 4; i++ )
  63.     {
  64.         // Get colour from source
  65.         accum += tex2D(inRTT, uv + texelSize * texOffset[i]);
  66.     }
  67.     
  68. // Adjust the accumulated amount by lum factor
  69. // Cannot use float3's here because it generates dependent texture errors because of swizzle
  70. float lum = dot(accum, LUMINENCE_FACTOR);
  71. // take average of 4 samples
  72. lum *= 0.25;
  73. return lum;
  74. }
  75. /* Downsample a 3x3 area 
  76.  * This shader is used multiple times on different source sizes, so texel size has to be configurable
  77. */
  78. float4 downscale3x3(
  79. float2 uv : TEXCOORD0,
  80. uniform float texelSize, // depends on size of source texture
  81. uniform sampler2D inRTT : register(s0)
  82.     ) : COLOR
  83. {
  84.     float4 accum = float4(0.0f, 0.0f, 0.0f, 0.0f);
  85. float2 texOffset[9] = {
  86. -1.0, -1.0,
  87.  0.0, -1.0,
  88.  1.0, -1.0,
  89. -1.0,  0.0,
  90.  0.0,  0.0,
  91.  1.0,  0.0,
  92. -1.0,  1.0,
  93.  0.0,  1.0,
  94.  1.0,  1.0
  95. };
  96. for( int i = 0; i < 9; i++ )
  97.     {
  98.         // Get colour from source
  99.         accum += tex2D(inRTT, uv + texelSize * texOffset[i]);
  100.     }
  101.     
  102. // take average of 9 samples
  103. accum *= 0.1111111111111111;
  104. return accum;
  105. }
  106. /* Downsample a 3x3 area from main RTT and perform a brightness pass
  107. */
  108. float4 downscale3x3brightpass(
  109. float2 uv : TEXCOORD0,
  110. uniform sampler2D inRTT : register(s0),
  111. uniform sampler2D inLum : register(s1)
  112.     ) : COLOR
  113. {
  114.     float4 accum = float4(0.0f, 0.0f, 0.0f, 0.0f);
  115. // Approximate ratio from viewport to texture
  116. float2 texelSize = 0.005;
  117. float2 texOffset[9] = {
  118. -1.0, -1.0,
  119.  0.0, -1.0,
  120.  1.0, -1.0,
  121. -1.0,  0.0,
  122.  0.0,  0.0,
  123.  1.0,  0.0,
  124. -1.0,  1.0,
  125.  0.0,  1.0,
  126.  1.0,  1.0
  127. };
  128. for( int i = 0; i < 9; i++ )
  129.     {
  130.         // Get colour from source
  131.         accum += tex2D(inRTT, uv + texelSize * texOffset[i]);
  132.     }
  133.     
  134. // take average of 9 samples
  135. accum *= 0.1111111111111111;
  136.     // Reduce bright and clamp
  137.     accum = max(float4(0.0f, 0.0f, 0.0f, 1.0f), accum - BRIGHT_LIMITER);
  138. // Sample the luminence texture
  139. float4 lum = tex2D(inLum, float2(0.5f, 0.5f));
  140. // Tone map result
  141. return toneMap(accum, lum.r);
  142. }
  143. /* Gaussian bloom, requires offsets and weights to be provided externally
  144. */
  145. float4 bloom(
  146. float2 uv : TEXCOORD0,
  147. uniform float2 sampleOffsets[15],
  148. uniform float4 sampleWeights[15],
  149. uniform sampler2D inRTT : register(s0)
  150. ) : COLOR
  151. {
  152.     float4 accum = float4(0.0f, 0.0f, 0.0f, 1.0f);
  153. float2 sampleUV;
  154.     
  155.     for( int i = 0; i < 15; i++ )
  156.     {
  157.         // Sample from adjacent points, 7 each side and central
  158.         sampleUV = uv + sampleOffsets[i];
  159.         accum += sampleWeights[i] * tex2D(inRTT, sampleUV);
  160.     }
  161.     
  162.     return accum;
  163. }
  164. /* Final scene composition, with tone mapping
  165. */
  166. float4 finalToneMapping(
  167. float2 uv : TEXCOORD0,
  168. uniform sampler2D inRTT : register(s0),
  169. uniform sampler2D inBloom : register(s1),
  170. uniform sampler2D inLum : register(s2)
  171.     ) : COLOR
  172. {
  173. // Get main scene colour
  174.     float4 sceneCol = tex2D(inRTT, uv);
  175. // Get luminence value
  176. float4 lum = tex2D(inLum, float2(0.5f, 0.5f));
  177. // tone map this
  178. float4 toneMappedSceneCol = toneMap(sceneCol, lum.r);
  179. // Get bloom colour
  180.     float4 bloom = tex2D(inBloom, uv);
  181. // Add scene & bloom
  182. return float4(toneMappedSceneCol.rgb + bloom.rgb, 1.0f);
  183.      
  184. }