Мне кажется, что этот шейдер эмулирует альфа-тестирование между текстурой, похожей на буфер, (передаваемой через sampler2D _MainTex
) и сгенерированной яркостью облака (представленной float lum
), сопоставленной с градиентом.Это усложняет ситуацию, потому что вы не можете просто подделать размытие и позволить альфа-блендингу позаботиться обо всем остальном.Вам также нужно будет изменить процедуру альфа-тестирования, чтобы вместо этого эмулировать альфа-смесь или соответствующим образом реструктурировать конвейер рендеринга.Сначала мы рассмотрим размытие облаков.
Первый вопрос, который вам нужно задать себе, - это если вам нужно размытие на экране.Видя механику этого фрагментного шейдера, я бы подумал, что нет - вы хотите размыть облака на реальной модели.Учитывая это, этого должно быть достаточно, чтобы размыть нижележащие текстуры и получить размытый результат - за исключением того, что вы эмулируете альфа-отсечение, так что вы получите грубые края.Вопрос в том, что делать с этими неровными краями.Вот где начинается альфа-смешивание.
Вы можете эмулировать альфа-смешивание, используя lerp (линейную интерполяцию) между цветом turb
и c
с функцией lerp () (в зависимости от того, какой язык шейдера вы используете).повторное использование).Вы, вероятно, захотите что-то, похожее на return lerp(c, turb, 1 - pos);
вместо return turb;
... Я ожидаю, что вы захотите постоянно подстраивать это, пока не поймете и начнете получать желаемые результаты.(Например, вы можете предпочесть lerp(c, turb, 1 - pow(pos,4))
)
На самом деле, вы можете попробовать этот последний шаг (просто добавив lerp) перед изменением ваших текстур, чтобы получить представление о том, что альфа-смешивание сделает для вас.
Редактировать: Я не рассматривал случай, когда сэмплеры _NoiseO
и _NoiseT
постоянно менялись, поэтому простое указание размыть их было минимально полезным советом.Вы можете эмулировать размытие, используя фильтр нескольких нажатий.Самый простой способ состоит в том, чтобы взять равномерно расположенные образцы, взвесить их и суммировать, чтобы получить окончательный цвет.(Как правило, вы хотите, чтобы сами веса составляли 1.)
Как говорится, вы можете или не можете сделать это на самих текстурах _NoiseO
и _NoiseT
- вы можете захотетьвместо этого создать размытие экранного пространства, которое может выглядеть более интересным для зрителя.В этом случае применяется та же концепция, но вам необходимо выполнить вычисления для координат смещения для каждого касания, а затем выполнить взвешенное суммирование.
Например, если мы собирались с первым случаем, и мы хотелисэмплер из сэмплера _Noise0 и немного размытие, мы могли бы использовать этот прямоугольный фильтр (где все веса одинаковы и сумма равна 1, что дает среднее значение):
// Untested code.
half4 nO = 0.25 * tex2D(_Noise0, IN.uv_MainTex + float2( 0, 0))
+ 0.25 * tex2D(_Noise0, IN.uv_MainTex + float2( 0, g_offset.y))
+ 0.25 * tex2D(_Noise0, IN.uv_MainTex + float2(g_offset.x, 0))
+ 0.25 * tex2D(_Noise0, IN.uv_MainTex + float2(g_offset.x, g_offset.y))
В качестве альтернативы, если мы хотеливывод всего облака выглядит размытым, мы бы обернули часть генерации облака в функцию и вызвали бы ее вместо tex2D()
для отводов.
// More untested code.
half4 genCloud(float2 tc) {
half4 nO = tex2D (_NoiseO, IN.uv_MainTex);
half4 nT = tex2D (_NoiseT, IN.uv_MainTex);
float4 turbulence = nO + nT;
float lum = Luminance(turbulence);
float pos = lum - 1.0;
if( pos > 0.98f ) pos = 0.98f;
if( pos < 0.02f ) pos = 0.02f;
float2 texCord = (pos, pos);
half4 turb = tex2D (_Gradient, texCord);
// Figure out how you'd generate your alpha blending constant here for your lerp
turb.a = ACTUAL_ALPHA;
return turb;
}
И фильтрация с несколькими отводами будет выглядеть следующим образом:
// And even more untested code.
half4 cloudcolor = 0.25 * genCloud(IN.uv_MainTex + float2( 0, 0))
+ 0.25 * genCloud(IN.uv_MainTex + float2( 0, g_offset.y))
+ 0.25 * genCloud(IN.uv_MainTex + float2(g_offset.x, 0))
+ 0.25 * genCloud(IN.uv_MainTex + float2(g_offset.x, g_offset.y))
return lerp(c, cloudcolor, cloudcolor.a);
Однако выполнение этого будет относительно медленным для вычислений, если вы сделаете функцию облака слишком сложной.Если вы связаны растровыми операциями и чтением текстур (передачей текстурных / буферных данных в память и из памяти), есть вероятность, что это не будет иметь большого значения, если вы не используете гораздо более продвинутую технику размытия (такой успешный понижающий дискретизатор с помощью буферов с пинг-понгом, полезнодля размытия / фильтров, которые дороги, потому что они имеют много кранов).Но производительность - это еще одно соображение, основанное на том, чтобы получить желаемый вид.