ChromaticAberrationShader.shader 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
  2. Shader "Hidden/ChromaticAberration" {
  3. Properties {
  4. _MainTex ("Base", 2D) = "" {}
  5. }
  6. CGINCLUDE
  7. #include "UnityCG.cginc"
  8. struct v2f {
  9. float4 pos : SV_POSITION;
  10. float2 uv : TEXCOORD0;
  11. };
  12. sampler2D _MainTex;
  13. float4 _MainTex_TexelSize;
  14. half _ChromaticAberration;
  15. half _AxialAberration;
  16. half _Luminance;
  17. half2 _BlurDistance;
  18. v2f vert( appdata_img v )
  19. {
  20. v2f o;
  21. o.pos = UnityObjectToClipPos(v.vertex);
  22. o.uv = v.texcoord.xy;
  23. return o;
  24. }
  25. half4 fragDs(v2f i) : SV_Target
  26. {
  27. half4 c = tex2D (_MainTex, i.uv.xy + _MainTex_TexelSize.xy * 0.5);
  28. c += tex2D (_MainTex, i.uv.xy - _MainTex_TexelSize.xy * 0.5);
  29. c += tex2D (_MainTex, i.uv.xy + _MainTex_TexelSize.xy * float2(0.5,-0.5));
  30. c += tex2D (_MainTex, i.uv.xy - _MainTex_TexelSize.xy * float2(0.5,-0.5));
  31. return c/4.0;
  32. }
  33. half4 frag(v2f i) : SV_Target
  34. {
  35. half2 coords = i.uv;
  36. half2 uv = i.uv;
  37. coords = (coords - 0.5) * 2.0;
  38. half coordDot = dot (coords,coords);
  39. half2 uvG = uv - _MainTex_TexelSize.xy * _ChromaticAberration * coords * coordDot;
  40. half4 color = tex2D (_MainTex, uv);
  41. #if SHADER_API_D3D9
  42. // Work around Cg's code generation bug for D3D9 pixel shaders :(
  43. color.g = color.g * 0.0001 + tex2D (_MainTex, uvG).g;
  44. #else
  45. color.g = tex2D (_MainTex, uvG).g;
  46. #endif
  47. return color;
  48. }
  49. // squeezing into SM2.0 with 9 samples:
  50. static const int SmallDiscKernelSamples = 9;
  51. static const half2 SmallDiscKernel[SmallDiscKernelSamples] =
  52. {
  53. half2(-0.926212,-0.40581),
  54. half2(-0.695914,0.457137),
  55. half2(-0.203345,0.820716),
  56. half2(0.96234,-0.194983),
  57. half2(0.473434,-0.480026),
  58. half2(0.519456,0.767022),
  59. half2(0.185461,-0.893124),
  60. half2(0.89642,0.412458),
  61. half2(-0.32194,-0.932615),
  62. };
  63. half4 fragComplex(v2f i) : SV_Target
  64. {
  65. half2 coords = i.uv;
  66. half2 uv = i.uv;
  67. // corner heuristic
  68. coords = (coords - 0.5h) * 2.0h;
  69. half coordDot = dot (coords,coords);
  70. half4 color = tex2D (_MainTex, uv);
  71. half tangentialStrength = _ChromaticAberration * coordDot * coordDot;
  72. half maxOfs = clamp(max(_AxialAberration, tangentialStrength), _BlurDistance.x, _BlurDistance.y);
  73. // we need a blurred sample tap for advanced aberration
  74. // NOTE: it's relatively important that input is HDR
  75. // and if you do have a proper HDR setup, lerping .rb might yield better results than .g
  76. // (see below)
  77. half4 blurredTap = color * 0.1h;
  78. for(int l=0; l < SmallDiscKernelSamples; l++)
  79. {
  80. half2 sampleUV = uv + SmallDiscKernel[l].xy * _MainTex_TexelSize.xy * maxOfs;
  81. half3 tap = tex2D(_MainTex, sampleUV).rgb;
  82. blurredTap.rgb += tap;
  83. }
  84. blurredTap.rgb /= (float)SmallDiscKernelSamples + 0.2h;
  85. // debug:
  86. //return blurredTap;
  87. half lumDiff = Luminance(abs(blurredTap.rgb-color.rgb));
  88. half isEdge = saturate(_Luminance * lumDiff);
  89. // debug #2:
  90. //return isEdge;
  91. color.rb = lerp(color.rb, blurredTap.rb, isEdge);
  92. return color;
  93. }
  94. ENDCG
  95. Subshader {
  96. // 0: box downsample
  97. Pass {
  98. ZTest Always Cull Off ZWrite Off
  99. CGPROGRAM
  100. #pragma vertex vert
  101. #pragma fragment fragDs
  102. ENDCG
  103. }
  104. // 1: simple chrom aberration
  105. Pass {
  106. ZTest Always Cull Off ZWrite Off
  107. CGPROGRAM
  108. #pragma vertex vert
  109. #pragma fragment frag
  110. ENDCG
  111. }
  112. // 2: simulates more chromatic aberration effects
  113. Pass {
  114. ZTest Always Cull Off ZWrite Off
  115. CGPROGRAM
  116. #pragma vertex vert
  117. #pragma fragment fragComplex
  118. ENDCG
  119. }
  120. }
  121. Fallback off
  122. } // shader