Визуализация нормальных векторов в шейдере в URP
Шейдер Unity в этом примере визуализирует нормальные векторы на сетке.
Используйте исходный файл шейдера Unity из раздела Базовый неосвещённый шейдер URP и введите следующие изменения в код ShaderLab:
-
В
struct Attributes, которая является входной структурой для вершинного шейдера в этом примере, объявляется переменная, содержащая нормальный вектор для каждой вершины.struct Attributes { float4 positionOS : POSITION; // Declaring the variable containing the normal vector for each vertex. half3 normal : NORMAL; }; -
В
struct Varyings, который является входной структурой для шейдера фрагмента в этом примере, объявьте переменную для хранения значений нормального вектора для каждого фрагмента:struct Varyings { float4 positionHCS : SV_POSITION; // The variable for storing the normal vector values. half3 normal : TEXCOORD0; };В этом примере три компоненты нормального вектора используются в качестве цветовых значений RGB для каждого фрагмента.
-
Для отображения нормальных векторных значений на сетке используйте следующий код в качестве шейдера фрагмента:
half4 frag(Varyings IN) : SV_Target { half4 color = 0; color.rgb = IN.normal; return color; } -
Unity отображает нормальные векторы на сетке:
Отображение нормалей без сжатия Часть капсулы чёрная. Это потому, что в этих точках все три компоненты нормального вектора отрицательны. Следующий шаг показывает, как отобразить значения в этих областях также.
-
Чтобы отобразить отрицательные нормальные векторные компоненты, используйте технику сжатия. Чтобы сжать диапазон значений нормальных компонентов
(-1..1)в цветовой диапазон значений(0..1), измените следующую строку:color.rgb = IN.normal;к этой строке:
color.rgb = IN.normal * 0.5 + 0.5;
Теперь Unity отображает нормальные векторы в виде цветов на сетке.
Ниже приведен полный код ShaderLab для этого примера.
// This shader visualizes the normal vector values on the mesh.
Shader "Example/URPUnlitShaderNormal"
{
Properties
{ }
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
// Declaring the variable containing the normal vector for each
// vertex.
half3 normal : NORMAL;
};
struct Varyings
{
float4 positionHCS : SV_POSITION;
half3 normal : TEXCOORD0;
};
Varyings vert(Attributes IN)
{
Varyings OUT;
OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
// Use the TransformObjectToWorldNormal function to transform the
// normals from object to world space. This function is from the
// SpaceTransforms.hlsl file, which is referenced in Core.hlsl.
OUT.normal = TransformObjectToWorldNormal(IN.normal);
return OUT;
}
half4 frag(Varyings IN) : SV_Target
{
half4 color = 0;
// IN.normal is a 3D vector. Each vector component has the range
// -1..1. To show all vector elements as color, including the
// negative values, compress each value into the range 0..1.
color.rgb = IN.normal * 0.5 + 0.5;
return color;
}
ENDHLSL
}
}
}