Основы прозрачности.

Введение.

В дополнение к тому, чтобы просто нарисовать цвет на экране, мы также можем сохранить некоторый цвет, который был на экране ранее, что делает объект прозрачным. Я объясню, как мы можем настроить этот эффект в базовом шейдере без освещения.

Чтобы понять, как реализовать прозрачность, я рекомендую вам знать основы написания шейдеров, в этом уроке я начну с результата урока по внедрению текстур.

Прозрачность.

Чтобы прозрачный объект визуализировался правильно, мы должны сказать Unity, что он прозрачен. Для этого мы изменим тип рендеринга, а также очередь. Изменяя очередь, мы гарантируем, что материал будет отображаться позже, чем непрозрачные материалы. Если бы это было не так, непрозрачный объект, который находится за прозрачным, был бы нарисован поверх прозрачного, полностью покрывая его.
Tags{ "RenderType"="Transparent" "Queue"="Transparent"}
Затем мы определяем «режим смешивания», который определяет, как существующие цвета и новые цвета смешиваются друг с другом. Режим смешивания определяется двумя ключевыми словами, первый определяет значение, на которое новый цвет умножается, а второй определяет значение, на которое ослабевает старый цвет. После умножения цветов они объединяются и результат рисуется.
При рендеринге непрозрачных материалов режим смешивания равен нулю, потому что мы берем все новое значение и ничего из старого значения. В прозрачных материалах мы хотим сделать смешение на основе альфа-значения (4-е число в возвращаемом цвете, который мы до сих пор не использовали). Таким образом, мы устанавливаем первое значение смешивания для источника alpha, источником в этом случае является выход шейдера. Второе значение должно быть обратным, поэтому это единица минус исходная альфа.
Режим смешивания может быть определен в субшадере или шейдерном проходе, но должен находиться вне области hlsl.
Blend SrcAlpha OneMinusSrcAlpha
Пояснение. SrcAlpha – альфа цвета, который мы сечас рисуем (прозрачного объекта). Т.е. видимость прозрачного объекта определяется его альфой. OneMinusSrcAlpha определяет видимость всего что за прозрачным объектом.
Вы можете посмотреть различные коэффициенты смешивания (и несколько других свойств смешивания, которые я собираюсь показать) здесь: https://docs.unity3d.com/Manual/SL-Blend.html
Я покажу вам два небольших примера того, как это работает, чтобы все было яснее.
Когда наш шейдер фрагмента возвращает значение альфа 0,5, смешение возьмет половину нового цвета и 1 - 0,5 (тоже 0,5) старого цвета, смешав их одинаково (при рисовании белого на черном будет средний серый цвет).
Когда наш шейдер фрагмента возвращает альфа-значение 0,9, смешение займет 90% нового цвета и добавит 10% старого цвета, делая старый цвет едва заметным.
С этими изменениями наш шейдер уже может использоваться для прозрачного материала. Поскольку мы сохраняем альфа-канал в шейдере фрагмента, мы можем установить альфа цвета оттенка, и это будет альфа материала (если вы используете текстуру, которая не использует альфа-канал).

Еще одна небольшая вещь, которую мы хотим сделать здесь, - это отключить запись z-буфера. Обычно, когда объект визуализируется, он записывает, расстояние до камеры в текстуру, чтобы сообщить другим объектам, которые находятся за ним, чтобы они не рисовались поверх него. Однако это не работает с прозрачными объектами, потому что прозрачные объекты не полностью закрывают все позади них (сначала отобразится самый самый отдаленный объект, а затем следующий, пока ближайший объект не окажется последним, но Unity делает это для нас, поэтому нам не нужно беспокоиться об этом). Зписывается ли буфер Z или нет может быть определено в проходе субшейдера или шейдера.

Blend SrcAlpha OneMinusSrcAlpha
ZWrite Off
Когда у нашей текстуры есть альфа-канал, этот шейдер также будет использовать его и сделать объект более прозрачным, если на текстуре будут низкие значения альфа.

Shader "Tutorial/006_Basic_Transparency"{
 Properties{
  _Color ("Tint", Color) = (0, 0, 0, 1)
  _MainTex ("Texture", 2D) = "white" {}
 }

 SubShader{
  Tags{ "RenderType"="Transparent" "Queue"="Transparent"}

  Blend SrcAlpha OneMinusSrcAlpha
  ZWrite off

  Pass{
   CGPROGRAM

   #include "UnityCG.cginc"

   #pragma vertex vert
   #pragma fragment frag

   sampler2D _MainTex;
   float4 _MainTex_ST;

   fixed4 _Color;

   struct appdata{
    float4 vertex : POSITION;
    float2 uv : TEXCOORD0;
   };

   struct v2f{
    float4 position : SV_POSITION;
    float2 uv : TEXCOORD0;
   };

   v2f vert(appdata v){
    v2f o;
    o.position = UnityObjectToClipPos(v.vertex);
    o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    return o;
   }

   fixed4 frag(v2f i) : SV_TARGET{
    fixed4 col = tex2D(_MainTex, i.uv);
    col *= _Color;
    return col;
   }

   ENDCG
  }
 }
}
 
 
Исходный код можно найти здесь: https://github.com/ronja-tutorials/ShaderTutorials/blob/master/Assets/006_Transparency/transparent.shader

Перевод Беляев В.А ака seaman

Комментариев нет:

Отправить комментарий