Common.hlsl 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #ifndef UNIVERSAL_POSTPROCESSING_COMMON_INCLUDED
  2. #define UNIVERSAL_POSTPROCESSING_COMMON_INCLUDED
  3. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
  4. // ----------------------------------------------------------------------------------
  5. // Common shader data used in most post-processing passes
  6. struct Attributes
  7. {
  8. float4 positionOS : POSITION;
  9. float2 uv : TEXCOORD0;
  10. UNITY_VERTEX_INPUT_INSTANCE_ID
  11. };
  12. struct Varyings
  13. {
  14. float4 positionCS : SV_POSITION;
  15. float2 uv : TEXCOORD0;
  16. UNITY_VERTEX_OUTPUT_STEREO
  17. };
  18. Varyings Vert(Attributes input)
  19. {
  20. Varyings output;
  21. UNITY_SETUP_INSTANCE_ID(input);
  22. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
  23. output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
  24. output.uv = input.uv;
  25. return output;
  26. }
  27. // ----------------------------------------------------------------------------------
  28. // Render fullscreen mesh by using a matrix set directly by the pipeline instead of
  29. // relying on the matrix set by the C++ engine to avoid issues with XR
  30. float4x4 _FullscreenProjMat;
  31. float4 TransformFullscreenMesh(half3 positionOS)
  32. {
  33. return mul(_FullscreenProjMat, half4(positionOS, 1));
  34. }
  35. Varyings VertFullscreenMesh(Attributes input)
  36. {
  37. Varyings output;
  38. UNITY_SETUP_INSTANCE_ID(input);
  39. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
  40. output.positionCS = TransformFullscreenMesh(input.positionOS.xyz);
  41. output.uv = input.uv;
  42. return output;
  43. }
  44. // ----------------------------------------------------------------------------------
  45. // Samplers
  46. SAMPLER(sampler_LinearClamp);
  47. SAMPLER(sampler_LinearRepeat);
  48. SAMPLER(sampler_PointClamp);
  49. SAMPLER(sampler_PointRepeat);
  50. // ----------------------------------------------------------------------------------
  51. // Utility functions
  52. half GetLuminance(half3 colorLinear)
  53. {
  54. #if _TONEMAP_ACES
  55. return AcesLuminance(colorLinear);
  56. #else
  57. return Luminance(colorLinear);
  58. #endif
  59. }
  60. // ----------------------------------------------------------------------------------
  61. // Shared functions for uber & fast path (on-tile)
  62. // These should only process an input color, don't sample in neighbor pixels!
  63. half3 ApplyVignette(half3 input, float2 uv, float2 center, float intensity, float roundness, float smoothness, half3 color)
  64. {
  65. center = UnityStereoTransformScreenSpaceTex(center);
  66. float2 dist = abs(uv - center) * intensity;
  67. #if defined(UNITY_SINGLE_PASS_STEREO)
  68. dist.x /= unity_StereoScaleOffset[unity_StereoEyeIndex].x;
  69. #endif
  70. dist.x *= roundness;
  71. float vfactor = pow(saturate(1.0 - dot(dist, dist)), smoothness);
  72. return input * lerp(color, (1.0).xxx, vfactor);
  73. }
  74. half3 ApplyTonemap(half3 input)
  75. {
  76. #if _TONEMAP_ACES
  77. float3 aces = unity_to_ACES(input);
  78. input = AcesTonemap(aces);
  79. #elif _TONEMAP_NEUTRAL
  80. input = NeutralTonemap(input);
  81. #endif
  82. return saturate(input);
  83. }
  84. half3 ApplyColorGrading(half3 input, float postExposure, TEXTURE2D_PARAM(lutTex, lutSampler), float3 lutParams, TEXTURE2D_PARAM(userLutTex, userLutSampler), float3 userLutParams, float userLutContrib)
  85. {
  86. // Artist request to fine tune exposure in post without affecting bloom, dof etc
  87. input *= postExposure;
  88. // HDR Grading:
  89. // - Apply internal LogC LUT
  90. // - (optional) Clamp result & apply user LUT
  91. #if _HDR_GRADING
  92. {
  93. float3 inputLutSpace = saturate(LinearToLogC(input)); // LUT space is in LogC
  94. input = ApplyLut2D(TEXTURE2D_ARGS(lutTex, lutSampler), inputLutSpace, lutParams);
  95. UNITY_BRANCH
  96. if (userLutContrib > 0.0)
  97. {
  98. input = saturate(input);
  99. input.rgb = LinearToSRGB(input.rgb); // In LDR do the lookup in sRGB for the user LUT
  100. half3 outLut = ApplyLut2D(TEXTURE2D_ARGS(userLutTex, userLutSampler), input, userLutParams);
  101. input = lerp(input, outLut, userLutContrib);
  102. input.rgb = SRGBToLinear(input.rgb);
  103. }
  104. }
  105. // LDR Grading:
  106. // - Apply tonemapping (result is clamped)
  107. // - (optional) Apply user LUT
  108. // - Apply internal linear LUT
  109. #else
  110. {
  111. input = ApplyTonemap(input);
  112. UNITY_BRANCH
  113. if (userLutContrib > 0.0)
  114. {
  115. input.rgb = LinearToSRGB(input.rgb); // In LDR do the lookup in sRGB for the user LUT
  116. half3 outLut = ApplyLut2D(TEXTURE2D_ARGS(userLutTex, userLutSampler), input, userLutParams);
  117. input = lerp(input, outLut, userLutContrib);
  118. input.rgb = SRGBToLinear(input.rgb);
  119. }
  120. input = ApplyLut2D(TEXTURE2D_ARGS(lutTex, lutSampler), input, lutParams);
  121. }
  122. #endif
  123. return input;
  124. }
  125. half3 ApplyGrain(half3 input, float2 uv, TEXTURE2D_PARAM(GrainTexture, GrainSampler), float intensity, float response, float2 scale, float2 offset)
  126. {
  127. // Grain in range [0;1] with neutral at 0.5
  128. half grain = SAMPLE_TEXTURE2D(GrainTexture, GrainSampler, uv * scale + offset).w;
  129. // Remap [-1;1]
  130. grain = (grain - 0.5) * 2.0;
  131. // Noisiness response curve based on scene luminance
  132. float lum = 1.0 - sqrt(Luminance(input));
  133. lum = lerp(1.0, lum, response);
  134. return input + input * grain * intensity * lum;
  135. }
  136. half3 ApplyDithering(half3 input, float2 uv, TEXTURE2D_PARAM(BlueNoiseTexture, BlueNoiseSampler), float2 scale, float2 offset)
  137. {
  138. // Symmetric triangular distribution on [-1,1] with maximal density at 0
  139. float noise = SAMPLE_TEXTURE2D(BlueNoiseTexture, BlueNoiseSampler, uv * scale + offset).a * 2.0 - 1.0;
  140. noise = FastSign(noise) * (1.0 - sqrt(1.0 - abs(noise)));
  141. #if UNITY_COLORSPACE_GAMMA
  142. input += noise / 255.0;
  143. #else
  144. input = SRGBToLinear(LinearToSRGB(input) + noise / 255.0);
  145. #endif
  146. return input;
  147. }
  148. #endif // UNIVERSAL_POSTPROCESSING_COMMON_INCLUDED