可视化法线矢量
此示例中的 Unity 着色器将使网格上的法线矢量值可视化。
使用 URP 无光照基本着色器一节中的 Unity 着色器源文件,并对 ShaderLab 代码进行以下更改:
在此示例的顶点着色器的输入结构
struct Attributes
中,声明包含每个顶点的法线矢量的变量。struct Attributes { float4 positionOS : POSITION; // 声明包含每个顶点的法线矢量的变量。 half3 normal : NORMAL; };
在此示例的片元着色器的输入结构
struct Varyings
中,声明存储每个片元的法线矢量值的变量:struct Varyings { float4 positionHCS : SV_POSITION; // 用于存储法线矢量值的变量。 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 代码。
// 此着色器将使网格上的法线矢量值可视化。
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;
// 声明包含每个顶点的法线矢量的
// 变量。
half3 normal : NORMAL;
};
struct Varyings
{
float4 positionHCS : SV_POSITION;
half3 normal : TEXCOORD0;
};
Varyings vert(Attributes IN)
{
Varyings OUT;
OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
// 使用 TransformObjectToWorldNormal 函数将法线
// 从对象空间变换到世界空间。此函数来自 Core.hlsl 中引用的
// SpaceTransforms.hlsl 文件。
OUT.normal = TransformObjectToWorldNormal(IN.normal);
return OUT;
}
half4 frag(Varyings IN) : SV_Target
{
half4 color = 0;
// IN.normal 是一个 3D 矢量。每个矢量分量都位于 -1..1
// 范围内。要将所有矢量元素(包括负值)都显示为
// 颜色,请将每个值压缩到 0..1 范围内。
color.rgb = IN.normal * 0.5 + 0.5;
return color;
}
ENDHLSL
}
}
}