docs.unity3d.com
    显示 / 隐藏目录

    可视化法线矢量

    此示例中的 Unity 着色器将使网格上的法线矢量值可视化。

    使用 URP 无光照基本着色器一节中的 Unity 着色器源文件,并对 ShaderLab 代码进行以下更改:

    1. 在此示例的顶点着色器的输入结构 struct Attributes 中,声明包含每个顶点的法线矢量的变量。

      struct Attributes
      {
          float4 positionOS   : POSITION;
          // 声明包含每个顶点的法线矢量的变量。
          half3 normal        : NORMAL;
      };
      
    2. 在此示例的片元着色器的输入结构 struct Varyings 中,声明存储每个片元的法线矢量值的变量:

      struct Varyings
      {
          float4 positionHCS  : SV_POSITION;
          // 用于存储法线矢量值的变量。
          half3 normal        : TEXCOORD0;
      };
      

      此示例使用法线矢量的三个分量作为每个片元的 RGB 颜色值。

    3. 要在网格上渲染法线矢量值,请使用以下代码作为片元着色器:

      half4 frag(Varyings IN) : SV_Target
      {
          half4 color = 0;
          color.rgb = IN.normal;
          return color;
      }
      
    4. Unity 在网格上渲染法线矢量值:

      无压缩渲染法线

      胶囊体的一部分为黑色。这是因为这些点中的法线矢量的所有三个分量都是负值。下一步将展示如何在这些区域中也渲染值。

    5. 要渲染负法线矢量分量,请使用压缩技术。要将法线分量值范围 (-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
            }
        }
    }
    
    返回到顶部
    Copyright © 2023 Unity Technologies — 商标和使用条款
    • 法律条款
    • 隐私政策
    • Cookie
    • 不要出售或分享我的个人信息
    • Your Privacy Choices (Cookie Settings)