Adaptation.shader 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // Calculates adaptation to minimum/maximum luminance values,
  2. // based on "currently adapted" and "new values to adapt to"
  3. // textures (both 1x1).
  4. Shader "Hidden/Contrast Stretch Adaptation" {
  5. Properties {
  6. _MainTex ("Base (RGB)", 2D) = "white" {}
  7. _CurTex ("Base (RGB)", 2D) = "white" {}
  8. }
  9. Category {
  10. SubShader {
  11. Pass {
  12. ZTest Always Cull Off ZWrite Off
  13. Fog { Mode off }
  14. CGPROGRAM
  15. #pragma vertex vert_img
  16. #pragma fragment frag
  17. #pragma fragmentoption ARB_precision_hint_fastest
  18. #include "UnityCG.cginc"
  19. uniform sampler2D _MainTex; // currently adapted to
  20. uniform sampler2D _CurTex; // new value to adapt to
  21. uniform float4 _AdaptParams; // x=adaptLerp, y=limitMinimum, z=limitMaximum
  22. float4 frag (v2f_img i) : COLOR {
  23. // value is: max, min
  24. float2 valAdapted = tex2D(_MainTex, i.uv).xy;
  25. float2 valCur = tex2D(_CurTex, i.uv).xy;
  26. // Calculate new adapted values: interpolate
  27. // from valAdapted to valCur by script-supplied amount.
  28. //
  29. // Because we store adaptation levels in a simple 8 bit/channel
  30. // texture, we might not have enough precision - the interpolation
  31. // amount might be too small to change anything, and we'll never
  32. // arrive at the needed values.
  33. //
  34. // So we make sure the change we do is at least 1/255th of the
  35. // color range - this way we'll always change the value.
  36. const float kMinChange = 1.0/255.0;
  37. float2 delta = (valCur-valAdapted) * _AdaptParams.x;
  38. delta.x = sign(delta.x) * max( kMinChange, abs(delta.x) );
  39. delta.y = sign(delta.y) * max( kMinChange, abs(delta.y) );
  40. float4 valNew;
  41. valNew.xy = valAdapted + delta;
  42. // Impose user limits on maximum/minimum values
  43. valNew.x = max( valNew.x, _AdaptParams.z );
  44. valNew.y = min( valNew.y, _AdaptParams.y );
  45. // Optimization so that our final apply pass is faster:
  46. // z = max-min (plus a small amount to prevent division by zero)
  47. valNew.z = valNew.x - valNew.y + 0.01;
  48. // w = min/(max-min)
  49. valNew.w = valNew.y / valNew.z;
  50. return valNew;
  51. }
  52. ENDCG
  53. }
  54. }
  55. }
  56. Fallback off
  57. }