No Description
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.

Common.hlsl 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. #ifndef UNIVERSAL_POSTPROCESSING_COMMON_INCLUDED
  2. #define UNIVERSAL_POSTPROCESSING_COMMON_INCLUDED
  3. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
  4. #include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
  5. #if _FXAA
  6. // Notes on FXAA:
  7. // * We now rely on the official FXAA implementation (authored by Timothy Lottes while at NVIDIA)
  8. // with minimal changes made by Unity to integrate with URP.
  9. // * The following 'Tweakable' defines are used by the FXAA implementation and can be changed if desired:
  10. // * FXAA_PC set to 1 is the highest quality implementation ("PC" here is a misnomer, it will run on all platforms).
  11. // * FXAA_PC set to 0 is the cheaper 'FXAA_PC_CONSOLE' variant
  12. // (it's equivalent to URP's old implementation but less noisy and should run faster than before)
  13. // * FXAA_GREEN_AS_LUMA can be set to 0 for an extra performance increase but will only antialias edges that have
  14. // some green in them (will be visually equivalent on the vast majority of scenes).
  15. // * FXAA_QUALITY__PRESET is used when FXAA_PC is set ot 1. We chose preset 12 as it runs almost as fast on Switch as
  16. // our old noisy implementation did.
  17. // On all other platforms we could basically get away with preset 15 which has slightly better edge quality.
  18. // Tweakable params (can be changed to get different performance and quality tradeoffs)
  19. #if SHADER_API_PS5 && defined(HDR_INPUT)
  20. // The console implementation does not generate artefacts when the input pixels are in nits (monitor HDR range).
  21. #define FXAA_PC 0
  22. #else
  23. #define FXAA_PC 1
  24. #endif
  25. #define FXAA_GREEN_AS_LUMA 0
  26. #define FXAA_QUALITY__PRESET 12
  27. // Fixed params (should not be changed)
  28. #define FXAA_HLSL_5 1
  29. #define FXAA_GATHER4_ALPHA 0
  30. #define FXAA_PC_CONSOLE !FXAA_PC
  31. #include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/FXAA3_11.hlsl"
  32. #endif
  33. // ----------------------------------------------------------------------------------
  34. // Utility functions
  35. half GetLuminance(half3 colorLinear)
  36. {
  37. #if _TONEMAP_ACES
  38. return AcesLuminance(colorLinear);
  39. #else
  40. return Luminance(colorLinear);
  41. #endif
  42. }
  43. real3 GetSRGBToLinear(real3 c)
  44. {
  45. #if _USE_FAST_SRGB_LINEAR_CONVERSION
  46. return FastSRGBToLinear(c);
  47. #else
  48. return SRGBToLinear(c);
  49. #endif
  50. }
  51. real4 GetSRGBToLinear(real4 c)
  52. {
  53. #if _USE_FAST_SRGB_LINEAR_CONVERSION
  54. return FastSRGBToLinear(c);
  55. #else
  56. return SRGBToLinear(c);
  57. #endif
  58. }
  59. real3 GetLinearToSRGB(real3 c)
  60. {
  61. #if _USE_FAST_SRGB_LINEAR_CONVERSION
  62. return FastLinearToSRGB(c);
  63. #else
  64. return LinearToSRGB(c);
  65. #endif
  66. }
  67. real4 GetLinearToSRGB(real4 c)
  68. {
  69. #if _USE_FAST_SRGB_LINEAR_CONVERSION
  70. return FastLinearToSRGB(c);
  71. #else
  72. return LinearToSRGB(c);
  73. #endif
  74. }
  75. // ----------------------------------------------------------------------------------
  76. // Shared functions for uber & fast path (on-tile)
  77. // These should only process an input color, don't sample in neighbor pixels!
  78. half3 ApplyVignette(half3 input, float2 uv, float2 center, float intensity, float roundness, float smoothness, half3 color)
  79. {
  80. center = UnityStereoTransformScreenSpaceTex(center);
  81. float2 dist = abs(uv - center) * intensity;
  82. dist.x *= roundness;
  83. float vfactor = pow(saturate(1.0 - dot(dist, dist)), smoothness);
  84. return input * lerp(color, (1.0).xxx, vfactor);
  85. }
  86. half3 ApplyTonemap(half3 input)
  87. {
  88. #if _TONEMAP_ACES
  89. float3 aces = unity_to_ACES(input);
  90. input = AcesTonemap(aces);
  91. #elif _TONEMAP_NEUTRAL
  92. input = NeutralTonemap(input);
  93. #endif
  94. return saturate(input);
  95. }
  96. half3 ApplyColorGrading(half3 input, float postExposure, TEXTURE2D_PARAM(lutTex, lutSampler), float3 lutParams, TEXTURE2D_PARAM(userLutTex, userLutSampler), float3 userLutParams, float userLutContrib)
  97. {
  98. // Artist request to fine tune exposure in post without affecting bloom, dof etc
  99. input *= postExposure;
  100. // HDR Grading:
  101. // - Apply internal LogC LUT
  102. // - (optional) Clamp result & apply user LUT
  103. #if _HDR_GRADING
  104. {
  105. float3 inputLutSpace = saturate(LinearToLogC(input)); // LUT space is in LogC
  106. input = ApplyLut2D(TEXTURE2D_ARGS(lutTex, lutSampler), inputLutSpace, lutParams);
  107. UNITY_BRANCH
  108. if (userLutContrib > 0.0)
  109. {
  110. input = saturate(input);
  111. input.rgb = GetLinearToSRGB(input.rgb); // In LDR do the lookup in sRGB for the user LUT
  112. half3 outLut = ApplyLut2D(TEXTURE2D_ARGS(userLutTex, userLutSampler), input, userLutParams);
  113. input = lerp(input, outLut, userLutContrib);
  114. input.rgb = GetSRGBToLinear(input.rgb);
  115. }
  116. }
  117. // LDR Grading:
  118. // - Apply tonemapping (result is clamped)
  119. // - (optional) Apply user LUT
  120. // - Apply internal linear LUT
  121. #else
  122. {
  123. input = ApplyTonemap(input);
  124. UNITY_BRANCH
  125. if (userLutContrib > 0.0)
  126. {
  127. input.rgb = GetLinearToSRGB(input.rgb); // In LDR do the lookup in sRGB for the user LUT
  128. half3 outLut = ApplyLut2D(TEXTURE2D_ARGS(userLutTex, userLutSampler), input, userLutParams);
  129. input = lerp(input, outLut, userLutContrib);
  130. input.rgb = GetSRGBToLinear(input.rgb);
  131. }
  132. input = ApplyLut2D(TEXTURE2D_ARGS(lutTex, lutSampler), input, lutParams);
  133. }
  134. #endif
  135. return input;
  136. }
  137. half3 ApplyGrain(half3 input, float2 uv, TEXTURE2D_PARAM(GrainTexture, GrainSampler), float intensity, float response, float2 scale, float2 offset, float oneOverPaperWhite)
  138. {
  139. // Grain in range [0;1] with neutral at 0.5
  140. half grain = SAMPLE_TEXTURE2D(GrainTexture, GrainSampler, uv * scale + offset).w;
  141. // Remap [-1;1]
  142. grain = (grain - 0.5) * 2.0;
  143. // Noisiness response curve based on scene luminance
  144. float lum = Luminance(input);
  145. #ifdef HDR_INPUT
  146. lum *= oneOverPaperWhite;
  147. #endif
  148. lum = 1.0 - sqrt(lum);
  149. lum = lerp(1.0, lum, response);
  150. return input + input * grain * intensity * lum;
  151. }
  152. half3 ApplyDithering(half3 input, float2 uv, TEXTURE2D_PARAM(BlueNoiseTexture, BlueNoiseSampler), float2 scale, float2 offset, float paperWhite, float oneOverPaperWhite)
  153. {
  154. // Symmetric triangular distribution on [-1,1] with maximal density at 0
  155. float noise = SAMPLE_TEXTURE2D(BlueNoiseTexture, BlueNoiseSampler, uv * scale + offset).a * 2.0 - 1.0;
  156. noise = FastSign(noise) * (1.0 - sqrt(1.0 - abs(noise)));
  157. #if UNITY_COLORSPACE_GAMMA
  158. input += noise / 255.0;
  159. #elif defined(HDR_INPUT)
  160. input = input * oneOverPaperWhite;
  161. // Do not call GetSRGBToLinear/GetLinearToSRGB because the "fast" version will clamp values!
  162. input = SRGBToLinear(LinearToSRGB(input) + noise / 255.0);
  163. input = input * paperWhite;
  164. #else
  165. input = GetSRGBToLinear(GetLinearToSRGB(input) + noise /255.0);
  166. #endif
  167. return input;
  168. }
  169. #if _FXAA
  170. static const FxaaFloat kSubpixelBlendAmount = 0.65;
  171. static const FxaaFloat kRelativeContrastThreshold = 0.15;
  172. static const FxaaFloat kAbsoluteContrastThreshold = 0.03;
  173. #endif
  174. half3 ApplyFXAA(half3 color, float2 positionNDC, int2 positionSS, float4 sourceSize, TEXTURE2D_X(inputTexture), float paperWhite, float oneOverPaperWhite)
  175. {
  176. #if _FXAA
  177. FxaaTex tex = {sampler_LinearClamp, _BlitTexture};
  178. FxaaFloat4 kUnusedFloat4 = FxaaFloat4(0, 0, 0, 0);
  179. FxaaFloat4 fxaaConsolePos = 0;
  180. FxaaFloat4 kFxaaConsoleRcpFrameOpt = 0;
  181. FxaaFloat4 kFxaaConsoleRcpFrameOpt2 = 0;
  182. FxaaFloat kFxaaConsoleEdgeSharpness = 0;
  183. FxaaFloat kFxaaConsoleEdgeThreshold = 0;
  184. FxaaFloat kFxaaConsoleEdgeThresholdMin = 0;
  185. FxaaFloat2 fxaaHDROutputPaperWhiteNits = 0;
  186. #if FXAA_PC_CONSOLE == 1
  187. fxaaConsolePos = FxaaFloat4(positionNDC.xy - 0.5*sourceSize.zw, positionNDC.xy + 0.5*sourceSize.zw);
  188. kFxaaConsoleRcpFrameOpt = 0.5*FxaaFloat4(sourceSize.zw, -sourceSize.zw);
  189. kFxaaConsoleRcpFrameOpt2 = 2.0*FxaaFloat4(-sourceSize.zw, sourceSize.zw);
  190. kFxaaConsoleEdgeSharpness = 8.0;
  191. kFxaaConsoleEdgeThreshold = 0.125;
  192. kFxaaConsoleEdgeThresholdMin = 0.05;
  193. #endif
  194. fxaaHDROutputPaperWhiteNits = FxaaFloat2(paperWhite, oneOverPaperWhite);
  195. return FxaaPixelShader(
  196. positionNDC,
  197. FxaaFloat4(color, 0),
  198. fxaaConsolePos,
  199. tex,
  200. tex,
  201. tex,
  202. sourceSize.zw,
  203. kFxaaConsoleRcpFrameOpt,
  204. kFxaaConsoleRcpFrameOpt2,
  205. kUnusedFloat4,
  206. kSubpixelBlendAmount,
  207. kRelativeContrastThreshold,
  208. kAbsoluteContrastThreshold,
  209. kFxaaConsoleEdgeSharpness,
  210. kFxaaConsoleEdgeThreshold,
  211. kFxaaConsoleEdgeThresholdMin,
  212. kUnusedFloat4,
  213. fxaaHDROutputPaperWhiteNits
  214. ).rgb;
  215. #else
  216. return color;
  217. #endif
  218. }
  219. #endif // UNIVERSAL_POSTPROCESSING_COMMON_INCLUDED