Страница 1 из 1

Объясните пару строчек кода

СообщениеДобавлено: 14 авг 2013, 20:21
GufRip
Нашел на форуме движка ПостЭффект радиального размытия, добавил изменение цвета для своих нужд. В принципе всё работает, почти всё устраивает, но хочется понять как работает размытие. Почти всё понятно кроме парочки строчек. Вот код:
Синтаксис:
  1. Shader "MyShaders/radialBlur" { 
  2.  
  3. Properties { 
  4.  
  5. _MainTex ("Input", RECT) = "white" {} 
  6.  
  7. _BlurStrength ("", Float) = 0.5 
  8.  
  9. _BlurWidth ("", Float) = 0.5 
  10.  
  11.  
  12. SubShader { 
  13.  
  14. Pass { 
  15.  
  16. ZTest Always Cull Off ZWrite Off 
  17.  
  18. Fog { Mode off } 
  19.  
  20.  
  21.  
  22. CGPROGRAM 
  23. // Upgrade NOTE: excluded shader from DX11, Xbox360, OpenGL ES 2.0 because it uses unsized arrays 
  24. #pragma exclude_renderers d3d11 xbox360 gles 
  25. #pragma target 3.0 
  26. #pragma vertex vert 
  27. #pragma fragment frag 
  28. #pragma fragmentoption ARB_precision_hint_fastest  
  29. #include "UnityCG.cginc" 
  30.  
  31. struct v2f { 
  32. float4 pos : POSITION; 
  33. float2 uv : TEXCOORD0; 
  34. }; 
  35.  
  36. uniform sampler2D _MainTex; 
  37.  
  38. uniform half _BlurStrength; 
  39.  
  40. uniform half _BlurWidth; 
  41.  
  42. uniform half _iWidth; 
  43.  
  44. uniform half _iHeight; 
  45. uniform float _Colr; 
  46. uniform float _Colg; 
  47. v2f vert (appdata_img v) 
  48. v2f o; 
  49. o.pos = mul (UNITY_MATRIX_MVP, v.vertex); 
  50. o.uv = MultiplyUV (UNITY_MATRIX_TEXTURE0, v.texcoord); 
  51. return o; 
  52.  
  53.  
  54. half4 frag (v2f i) : COLOR { 
  55.  
  56. half4 color = tex2D(_MainTex, i.uv); 
  57.  
  58.  
  59.  
  60. // некоторые образцы позиций 
  61.  
  62. half samples[10] = half[](-0.08,-0.05,-0.03,-0.02,-0.01,0.01,0.02,0.03,0.05,0.08); // вот это мне непонятно 
  63.  
  64.  
  65.  
  66. //вектор к центру экрана 
  67.  
  68. half2 dir = 0.5 * half2(_iHeight,_iWidth) - i.uv; 
  69.  
  70.  
  71.  
  72. //расстояние до центра 
  73.  
  74. half dist = sqrt(dir.x*dir.x + dir.y*dir.y); 
  75.  
  76.  
  77.  
  78. //нормализация направления 
  79.  
  80. dir = dir/dist; 
  81.  
  82.  
  83.  
  84. //дополнителные сэмплы в сторону экрана 
  85.  
  86. half4 sum = color;  
  87. for(int n = 0; n < 10; n++) //и вот это непонятно  
  88.  
  89. {  
  90.  
  91. sum += tex2D(_MainTex, i.uv + dir * samples[n] * _BlurWidth * _iWidth);  
  92.  
  93. }  
  94.  
  95.  
  96.  
  97. //11 Сэмплов. ??? почему 11 если samples[10] 
  98.  
  99. sum *= 1.0/11.0; 
  100.  
  101.  
  102.  
  103. //сила размытия в зависимости от расстояния до центра экрана 
  104.  
  105. half t = dist * _BlurStrength / _iWidth; 
  106.  
  107. t = clamp(t, 0.0, 1.0); 
  108.  
  109.  
  110.  
  111. //объединяем оригинальную текстуру с размытой 
  112. color = lerp(color, sum, t); 
  113. //добавляем цвет 
  114. color.r*=_Colr; 
  115. color.g*=_Colg; 
  116. return color; 
  117.  
  118.  
  119. ENDCG 
  120.  
  121.  
  122. }  
  123.  


теперь вопросы :D Что это за сэмплы, откуда их взяли и с чем их кушать???
Синтаксис:
  1. half samples[10] = half[](-0.08,-0.05,-0.03,-0.02,-0.01,0.01,0.02,0.03,0.05,0.08); // вот это мне непонятно 


что вообще здесь происходит???
Синтаксис:
  1. //дополнителные сэмплы в сторону экрана(Перевёл гуглом:D) 
  2.  
  3. half4 sum = color; //и вот это непонятно 
  4. for(int n = 0; n < 10; n++)  
  5.  
  6. {  
  7.  
  8. sum += tex2D(_MainTex, i.uv + dir * samples[n] * _BlurWidth * _iWidth);  
  9.  
  10. }  


и почему среднее арифметическое(если я правильно понял)
Синтаксис:
  1. sum *= 1.0/11.0; 
равно sum/11 если сэмплов 10

Re: Объясните пару строчек кода

СообщениеДобавлено: 15 авг 2013, 14:27
WhiteDevil
Ну во-первых, там делят на 11, а не на 10, так как переменная sum изначально имела еще и значение color. Значит в переменную было добавлено 11 значений, после чего ее нужно нормализировать.
Во-вторых, смотрим на картинку тут
Пиксели копируются

Если не использовать семплы, то получится обычное смазывание, как здесь
http://ploobs.com.br/?p=1661
Чем дальше от центра, тем больше блурится.

Выбирается пиксель и к нему добавляются соседние пиксели, на расстояниях от (-0.1 до 0.1) и смешиваются. Эффект усиливается при увеличении расстояния

Re: Объясните пару строчек кода

СообщениеДобавлено: 15 авг 2013, 18:09
GufRip
ну со средним арифметическим всё понятно, но вот откуда взялись эти сэмплы я понять не могу, просто из головы любой набор UV координат, или что это???

Re: Объясните пару строчек кода

СообщениеДобавлено: 15 авг 2013, 18:28
WhiteDevil
Не из головы, а наверное из горького опыта :)
Там же не рендомные значения, а красивая симметричная линейка :)
Вообще написание шейдеров представляет собой жульничество и обман, лишь бы выглядело красиво и работало быстро.

Значение ячейки - смещение относительно координаты просматриваемого в данный момент пикселя. К примеру "смотрим" мы сейчас на пиксель с координатой (0.7,0.7) и добавляем в этот пиксель 10 соседних пикселей: 5 по направлению к центру и 5 от него, со смещением в 8%, 5%, 3%, 2% и 1% от размеров экрана. Таким образом пиксели дублируются, видно же на картинке.

Re: Объясните пару строчек кода

СообщениеДобавлено: 15 авг 2013, 18:46
GufRip
Всё спасибо, понял, это координаты смещения вычисленные путём проб и ошибок:-) Выглядит кстати не очень красиво, видно что картинка дублируется особенно при больших значениях силы и ширины размытия.

Re: Объясните пару строчек кода

СообщениеДобавлено: 15 авг 2013, 18:59
GufRip
Изображение

Re: Объясните пару строчек кода

СообщениеДобавлено: 15 авг 2013, 19:09
WhiteDevil
Тогда не используй переменную samples, и будет обычное размытие.
Может результат понравится больше