Во встроенном конвейере рендеринга шейдеры поверхностиупрощенный способ написания шейдеров для встроенного конвейера рендеринга. Подробнее
См. в Словарь имеют некоторую поддержку тесселяции DirectX 11 / OpenGL Core GPU.
Совместимость конвейера рендеринга
Название функции | Встроенный конвейер рендеринга | Универсальный конвейер рендеринга (URP) | Конвейер рендеринга высокого разрешения (HDRP) | Пользовательский SRP |
---|---|---|---|---|
Surface Shaders | Да | No
Чтобы узнать об упрощенном способе создания объектов Shader в URP, см. раздел Shader Graph. |
No
Чтобы узнать об упрощенном способе создания объектов Shader в HDRP, см. раздел Shader Graph. |
Нет |
Обзор
- Тесселяция обозначается модификатором
tessellate:FunctionName
. Эта функция вычисляет край треугольника и внутренние факторы тесселяции. - При использовании тесселяции «модификатор вершины» (
vertex:FunctionName
) вызывается после тесселяции для каждой сгенерированной вершины в домене шейдерПрограмма, работающая на графическом процессоре. Подробнее
См. в Словарь. Здесь обычно используется картирование смещения. - Шейдеры поверхности могут дополнительно вычислять тесселяцию Фонга для сглаживания поверхности модели даже без отображение смещения.
Текущие ограничения поддержки тесселяции:
- Только треугольный домен – без четырехугольниковПримитивный объект, напоминающий плоскость, но длина его ребер составляет всего одну единицу, он использует всего 4 вершины, а поверхность ориентирована в плоскости XY локального координатного пространства. Подробнее
См. в Словарь, без тесселяции изолиний. - При использовании тесселяции шейдер автоматически компилируется в модель шейдера цель 4.6, что предотвращает поддержку работы на старых графических целях.
Без тесселяции GPU, смещение в модификаторе вершин
В следующем примере показан шейдер поверхности, который выполняет отображение смещения без использования тесселяции. Он просто перемещает вершины вдоль их нормалей в зависимости от величины, полученной из карты смещения:
Shader "Tessellation Sample" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_DispTex ("Disp Texture", 2D) = "gray" {}
_NormalMap ("Normalmap", 2D) = "bump" {}
_Displacement ("Displacement", Range(0, 1.0)) = 0.3
_Color ("Color", color) = (1,1,1,0)
_SpecColor ("Spec color", color) = (0.5,0.5,0.5,0.5)
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 300
CGPROGRAM
#pragma surface surf BlinnPhong addshadow fullforwardshadows vertex:disp nolightmap
#pragma target 4.6
struct appdata {
float4 vertex : POSITION;
float4 tangent : TANGENT;
float3 normal : NORMAL;
float2 texcoord : TEXCOORD0;
};
sampler2D _DispTex;
float _Displacement;
void disp (inout appdata v)
{
float d = tex2Dlod(_DispTex, float4(v.texcoord.xy,0,0)).r * _Displacement;
v.vertex.xyz += v.normal * d;
}
struct Input {
float2 uv_MainTex;
};
sampler2D _MainTex;
sampler2D _NormalMap;
fixed4 _Color;
void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Specular = 0.2;
o.Gloss = 1.0;
o.Normal = UnpackNormal(tex2D(_NormalMap, IN.uv_MainTex));
}
ENDCG
}
FallBack "Diffuse"
}
Приведенный выше шейдер довольно стандартный:
- Модификатор вершины
disp
выбирает карту смещения и перемещает вершины по их нормалям. - Используется пользовательская структура ввода данных вершины (
appdata
) вместо используемой по умолчаниюappdata_full
. Это пока не нужно, но для тесселяции эффективнее использовать как можно меньшую структуру. - Поскольку у данных вершин нет второй UV-координаты, мы добавляем директиву
nolightmap
, чтобы исключить карты освещенияПредварительно визуализированная текстура, содержащая эффекты источников света на статических объектах сцены. Карты освещения накладываются поверх геометрии сцены для создания эффекта освещения. Подробнее
См. в Словарь.
На изображении ниже показаны некоторые простые GameObjectsфундаментальные объекты в сценах Unity, которые могут представлять персонажей, реквизит, декорации, камеры. , путевые точки и многое другое. Функциональность GameObject определяется прикрепленными к нему компонентами. Подробнее
См. в Словарь с применением этого шейдера.
Фиксированная степень тесселяции
Если лица вашей модели примерно одинакового размера на экране, добавьте фиксированную степень тесселяции к Meshосновной графике. примитив единства. Меши составляют большую часть ваших 3D-миров. Unity поддерживает триангулированные или четырехугольные полигональные сетки. Поверхности Nurbs, Nurms, Subdiv должны быть преобразованы в полигоны. Подробнее
См. в Словарь (один и тот же уровень тесселяции по всей сетке). р>
В следующем примере сценария применяется фиксированная степень тесселяции.
Shader "Tessellation Sample" {
Properties {
_Tess ("Tessellation", Range(1,32)) = 4
_MainTex ("Base (RGB)", 2D) = "white" {}
_DispTex ("Disp Texture", 2D) = "gray" {}
_NormalMap ("Normalmap", 2D) = "bump" {}
_Displacement ("Displacement", Range(0, 1.0)) = 0.3
_Color ("Color", color) = (1,1,1,0)
_SpecColor ("Spec color", color) = (0.5,0.5,0.5,0.5)
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 300
CGPROGRAM
#pragma surface surf BlinnPhong addshadow fullforwardshadows vertex:disp tessellate:tessFixed nolightmap
#pragma target 4.6
struct appdata {
float4 vertex : POSITION;
float4 tangent : TANGENT;
float3 normal : NORMAL;
float2 texcoord : TEXCOORD0;
};
float _Tess;
float4 tessFixed()
{
return _Tess;
}
sampler2D _DispTex;
float _Displacement;
void disp (inout appdata v)
{
float d = tex2Dlod(_DispTex, float4(v.texcoord.xy,0,0)).r * _Displacement;
v.vertex.xyz += v.normal * d;
}
struct Input {
float2 uv_MainTex;
};
sampler2D _MainTex;
sampler2D _NormalMap;
fixed4 _Color;
void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Specular = 0.2;
o.Gloss = 1.0;
o.Normal = UnpackNormal(tex2D(_NormalMap, IN.uv_MainTex));
}
ENDCG
}
FallBack "Diffuse"
}
В приведенном выше примере функция тесселяции tessFixed
возвращает четыре фактора тесселяции в виде одного значения float4: три фактора для каждого края треугольника и один фактор для внутренней части треугольника. треугольник.
В этом примере возвращается постоянное значение, заданное в свойствах материала.
Тесселяция на основе расстояния
Вы также можете изменить уровень тесселяции в зависимости от расстояния до камерыкомпонента, который создает изображение определенной точки обзора в вашем место действия. Вывод либо рисуется на экране, либо фиксируется в виде текстуры. Подробнее
См. в Словарь.
Например, вы можете определить два значения расстояния:
- The distance when tessellation is at maximum (for example, 10 meters).
- The distance when the tessellation level gradually decreases (for example, 20 meters).
Shader "Tessellation Sample" {
Properties {
_Tess ("Tessellation", Range(1,32)) = 4
_MainTex ("Base (RGB)", 2D) = "white" {}
_DispTex ("Disp Texture", 2D) = "gray" {}
_NormalMap ("Normalmap", 2D) = "bump" {}
_Displacement ("Displacement", Range(0, 1.0)) = 0.3
_Color ("Color", color) = (1,1,1,0)
_SpecColor ("Spec color", color) = (0.5,0.5,0.5,0.5)
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 300
CGPROGRAM
#pragma surface surf BlinnPhong addshadow fullforwardshadows vertex:disp tessellate:tessDistance nolightmap
#pragma target 4.6
#include "Tessellation.cginc"
struct appdata {
float4 vertex : POSITION;
float4 tangent : TANGENT;
float3 normal : NORMAL;
float2 texcoord : TEXCOORD0;
};
float _Tess;
float4 tessDistance (appdata v0, appdata v1, appdata v2) {
float minDist = 10.0;
float maxDist = 25.0;
return UnityDistanceBasedTess(v0.vertex, v1.vertex, v2.vertex, minDist, maxDist, _Tess);
}
sampler2D _DispTex;
float _Displacement;
void disp (inout appdata v)
{
float d = tex2Dlod(_DispTex, float4(v.texcoord.xy,0,0)).r * _Displacement;
v.vertex.xyz += v.normal * d;
}
struct Input {
float2 uv_MainTex;
};
sampler2D _MainTex;
sampler2D _NormalMap;
fixed4 _Color;
void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Specular = 0.2;
o.Gloss = 1.0;
o.Normal = UnpackNormal(tex2D(_NormalMap, IN.uv_MainTex));
}
ENDCG
}
FallBack "Diffuse"
}
Здесь функция тесселяции принимает данные вершин трех углов треугольника до тесселяции в качестве трех параметров.
Это нужно Unity для вычисления уровней тесселяции, которые зависят от положения вершин.
Пример включает встроенный вспомогательный файл Tessellation.cginc и вызывает функцию UnityDistanceBasedTess
из файла для выполнения всей работы. Эта функция вычисляет расстояние от каждой вершины до камеры и выводит окончательные коэффициенты тесселяции.
Тесселяция на основе длины края
Тесселяция, основанная исключительно на расстоянии, эффективна только в том случае, если размеры треугольников очень похожи. На изображении выше игровые объекты с маленькими треугольниками слишком сильно мозаичны, а игровые объекты с большими треугольниками — недостаточно мозаичны.
Один из способов улучшить это — вычислить уровни тесселяции на основе длины края треугольника на экране. Unity должен применять больший коэффициент тесселяции к более длинным краям.
Shader "Tessellation Sample" {
Properties {
_EdgeLength ("Edge length", Range(2,50)) = 15
_MainTex ("Base (RGB)", 2D) = "white" {}
_DispTex ("Disp Texture", 2D) = "gray" {}
_NormalMap ("Normalmap", 2D) = "bump" {}
_Displacement ("Displacement", Range(0, 1.0)) = 0.3
_Color ("Color", color) = (1,1,1,0)
_SpecColor ("Spec color", color) = (0.5,0.5,0.5,0.5)
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 300
CGPROGRAM
#pragma surface surf BlinnPhong addshadow fullforwardshadows vertex:disp tessellate:tessEdge nolightmap
#pragma target 4.6
#include "Tessellation.cginc"
struct appdata {
float4 vertex : POSITION;
float4 tangent : TANGENT;
float3 normal : NORMAL;
float2 texcoord : TEXCOORD0;
};
float _EdgeLength;
float4 tessEdge (appdata v0, appdata v1, appdata v2)
{
return UnityEdgeLengthBasedTess (v0.vertex, v1.vertex, v2.vertex, _EdgeLength);
}
sampler2D _DispTex;
float _Displacement;
void disp (inout appdata v)
{
float d = tex2Dlod(_DispTex, float4(v.texcoord.xy,0,0)).r * _Displacement;
v.vertex.xyz += v.normal * d;
}
struct Input {
float2 uv_MainTex;
};
sampler2D _MainTex;
sampler2D _NormalMap;
fixed4 _Color;
void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Specular = 0.2;
o.Gloss = 1.0;
o.Normal = UnpackNormal(tex2D(_NormalMap, IN.uv_MainTex));
}
ENDCG
}
FallBack "Diffuse"
}
В этом примере вы вызываете функцию UnityEdgeLengthBasedTess
из Tessellation.cginc, чтобы выполнить всю работу.
Из соображений производительности вместо этого вызовите функцию UnityEdgeLengthBasedTessCull, которая выполняет отбраковку усеченной части. Это немного удорожает шейдер, но экономит ресурсы графического процессора для частей мешей, которые находятся за пределами поля зрения камеры.
Тесселяция Фонга
Мозаика Фонга изменяет положение разделенных граней таким образом, чтобы результирующая поверхность повторяла сетка немного нормализуется. Это довольно эффективный способ сделать низкополигональные сетки более гладкими.
Поверхностные шейдеры Unity могут автоматически вычислять тесселяцию Фонга с помощью директивы компиляции tessphong:VariableName
. Вот пример шейдера:
Shader "Phong Tessellation" {
Properties {
_EdgeLength ("Edge length", Range(2,50)) = 5
_Phong ("Phong Strengh", Range(0,1)) = 0.5
_MainTex ("Base (RGB)", 2D) = "white" {}
_Color ("Color", color) = (1,1,1,0)
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 300
CGPROGRAM
#pragma surface surf Lambert vertex:dispNone tessellate:tessEdge tessphong:_Phong nolightmap
#include "Tessellation.cginc"
struct appdata {
float4 vertex : POSITION;
float3 normal : NORMAL;
float2 texcoord : TEXCOORD0;
};
void dispNone (inout appdata v) { }
float _Phong;
float _EdgeLength;
float4 tessEdge (appdata v0, appdata v1, appdata v2)
{
return UnityEdgeLengthBasedTess (v0.vertex, v1.vertex, v2.vertex, _EdgeLength);
}
struct Input {
float2 uv_MainTex;
};
fixed4 _Color;
sampler2D _MainTex;
void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
Вот сравнение между обычным шейдером (верхний ряд) и шейдером, использующим тесселяцию Фонга (нижний ряд). Обратите внимание, что даже без карт смещения поверхность становится более круглой.
- Tessellation for Metal добовлен в 2018.1