Planar Mapping

Введение.

Иногда у вас нет текстурных координат на вашем объекте, но вы хотите, чтобы текстуры нескольких объектов были выровнены или у вас есть другая причина для генерации собственных UV-координат ... В этом уроке мы начнем с самого простого способа генерации собственных координаты, planar mapping.
Этот урок опирается на простой текстурированный шейдер, но вы можете использовать эту технику с любым шейдером, включая поверхностные шейдеры.

Основа.

Начнем с удаления координат uv из входной структуры, поскольку мы создадим собственные координаты текстуры.

struct appdata{
    float vertex : POSITION;
};
Так как UV-координаты все еще должны быть интерполированы между вершинами, как это было раньше, мы вычисляем новые UV в вершинном шейдере. В начале мы можем установить UV-координаты для значений x и z координат объекта. Этого достаточно, чтобы текстура появилась на нашей модели, и будет выглядеть как будто она выжата на ней сверху.

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

Настраиваемый тайлинг.

Это не учитывает масштабирование текстуры, и мы можем захотеть, чтобы текстура не вращалась и не двигалась вместе с объектом, как сейчас. Чтобы исправить масштабирование и смещение текстуры, мы просто поместим макрос TRANSFORM_TEX вокруг координат uv.

v2f vert(appdata v){
    v2f o;
    o.position = UnityObjectToClipPos(v.vertex);
    o.uv = TRANSFORM_TEX(v.vertex.xz, _MainTex);
    return o;
}
Текстурные координаты, основанные на мировой позиции. Чтобы взять положение объекта и вращение, мы должны использовать положение вершины в мире (ранее мы использовали положение относительно центра объекта). Чтобы вычислить мировое положение, мы умножаем объект на мировую матрицу (здесь я не буду вдаваться в матричное умножение). После того, как мы получим мировое положение, мы используем это, чтобы установить uv-координаты.

v2f vert(appdata v){
 v2f o;
 //рассчитываем позицию вершины в пространстве объекта
 o.position = UnityObjectToClipPos(v.vertex);
 //рассчитываем позицию вершины в мировом пространстве
 float4 worldPos = mul(unity_ObjectToWorld, v.vertex);
 //изменяем UV на основе тайлинга и смещения текстуры
 o.uv = TRANSFORM_TEX(worldPos.xz, _MainTex);
 return o;
}
Как вы видите, у этой техники есть некоторые недостатки, в основном, что она работает только с тайлящимися текстурами и имеет растяжение по бокам, но это можно смягчить с помощью более продвинутых методов, таких как трипланарный маппинг, о котором я расскажу в более позднем уроке.

Shader "Tutorial/008_Planar_Mapping"{
 //показываем значения свойств для редактирования в инспекторе
 Properties{
  _Color ("Tint", Color) = (0, 0, 0, 1)
  _MainTex ("Texture", 2D) = "white" {}
 }

 SubShader{
  //материал полностью непрозрачный и визуализируется в то же время что остальная непрозрачная геометрия
  Tags{ "RenderType"="Opaque" "Queue"="Geometry"}

  Pass{
   CGPROGRAM

   #include "UnityCG.cginc"

   #pragma vertex vert
   #pragma fragment frag

   //текстура и ее тайлинг/смещение
   sampler2D _MainTex;
   float4 _MainTex_ST;

   fixed4 _Color;

   struct appdata{
    float4 vertex : POSITION;
   };

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

   v2f vert(appdata v){
    v2f o;
    // рассчитываем позицию вершины в пространстве объекта
    o.position = UnityObjectToClipPos(v.vertex);
    // рассчитываем позицию вершины в мировом пространстве
    float4 worldPos = mul(unity_ObjectToWorld, v.vertex);
    // изменяем UV на основе тайлинга и смещения текстуры
    o.uv = TRANSFORM_TEX(worldPos.xz, _MainTex);
    return o;
   }

   fixed4 frag(v2f i) : SV_TARGET{
    //читаем текстуру в UV позиции
    fixed4 col = tex2D(_MainTex, i.uv);
    // умножаем цвет текстуры на цвет оттенка
    col *= _Color;
    return col;
   }

   ENDCG
  }
 }
 FallBack "Standard" //fallback добавляет проход рассчета тени для получения теней на других объектах
}


Вы можете найти код к уроку тут:
https://github.com/ronja-tutorials/ShaderTutorials/blob/master/Assets/008_Planar_Mapping/planar_mapping.shader

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

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

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