《Unity着色器圣经》3.0.8 | MPD开关

目录索引

译文

译者注:MPD是MaterialPropertyDrawer(自定义材质属性绘制器,即上一小节所介绍的内容)的缩写。

在 ShaderLab 中我们无法使用布尔类型的属性,取而代之的是可以实现相同功能的开关(Toggle)。这种绘制器允许我们切换着色器的状态,这样我们就可以通过状态条件实现不同的效果。要声明一个开关,我们需要先在一对中括号里添加 Toggle 字样,接着再声明它。虽然在声明时我们需要将属性类型设为浮点数,但开关的默认值必须是0或1的整数,其中 0 表示 “关闭”,1 表示 “打开”。

声明的语法如下所示:

[Toggle] _PropertyName ("Display Name", Float) = 0

你瞧,我们按照前文中提到的方法声明了一个开关,默认是关闭(0)的状态。

在我们使用这个绘制器的时候需要注意的一点是,如果我们要在代码中使用它,我们需要写上#pragma shader_feature。这是一种着色器变体,它的作用是根据不同的状态(开或关)产生不同的条件。为了理解它是怎么运作的,让我们看看下面的例子:

Shader "InspectorPath/shaderName" 
{ 
    Properties 
    {
        _Color ("Color", Color) = (1, 1, 1, 1) 
        // declare drawer Toggle 
        [Toggle] _Enable ("Enable ?", Float) = 0 
    }
    SubShader 
    { 
        Pass 
        { 
            CGPROGRAM 
            … 
            // declare pragma 
            #pragma shader_feature _ENABLE_ON 
            … 
            float4 _Color; 
            … 
            half4 frag (v2f i) : SV_Target { 
                half4 col = tex2D(_MainTex, i.uv); 

                // generate conditions 
            #if _ENABLE_ON 
                return col; 
            #else 
                return col * _Color; 
            #endif 
            } 
            ENDCG 
        } 
    } 
}

在这个例子中,我们声明了一个叫做“_Enable”的开关属性,并在 CGPROGRAM 语义块中写上了 shader_feature 。但和我们之前接触到的属性不同的是,这个开关被声明成了“_ENABLE_ON”。在 shader_feature 中添加的变体是“常量”,它们都用大写字母书写(如果我们的属性名字是 _Change 的话,那么在变体中就是“_CHANGE”),后缀“_ON”表示开关的开启状态。在上述例子中,如果 _Enable 属性处于开启状态,我们将在片元着色器中返回默认纹理颜色;如果 _Enable 属性处于关闭状态,我们将 _Color 属性乘以它本身。

值得一提的是,shader_feature 并不能在一个项目中编译多个变体,这代表 Unity 不会在项目最终构建时加入我们未使用过的变体,我们无法在运行时从一种状态切换到另一种状态。为此,我们必须使用带有“multi_compile”变体的关键词枚举绘制器。


原文对照

Within ShaderLab we cannot use boolean type properties, instead, we have the Toggle that fulfills the same function. This drawer is going to allow switching from one state to another using a condition within our shader. To run it, we must first add the word Toggle between brackets and then declare our property, taking into account that it must be a Float type. Its default value must be an integer, either zero or one, why? Because zero symbolizes “Off” and one symbolizes “On”.

Its syntax is as follows:

[Toggle] _PropertyName ("Display Name", Float) = 0

As we see, we add the Toggle in brackets, then we declare the property, then the display name, followed by the Float data type, and finally we initialize the property to “Off” since we add a zero in its default value.

Something that we must consider when working with this drawer is that, if we want to implement it in our code, we will have to use the #pragma shader_feature. This belongs to the shader variants and its function is to generate different conditions depending on the state it is in (enabled or disabled). To understand its implementation, we will do the following operation:

Shader "InspectorPath/shaderName" 
{ 
    Properties 
    {
        _Color ("Color", Color) = (1, 1, 1, 1) 
        // declare drawer Toggle 
        [Toggle] _Enable ("Enable ?", Float) = 0 
    }
    SubShader 
    { 
        Pass 
        { 
            CGPROGRAM 
            … 
            // declare pragma 
            #pragma shader_feature _ENABLE_ON 
            … 
            float4 _Color; 
            … 
            half4 frag (v2f i) : SV_Target { 
                half4 col = tex2D(_MainTex, i.uv); 

                // generate conditions 
            #if _ENABLE_ON 
                return col; 
            #else 
                return col * _Color; 
            #endif 
            } 
            ENDCG 
        } 
    } 
}

In this example, we declared a Toggle-type property called “_Enable”. Then we added it to the shader_feature found in the CGPROGRAM, however, unlike the property in our program, the Toggle has been declared as “_ENABLE_ON“, why is this? The variants added in shader_feature are “constants” therefore they are written in capitals, this means that if, for example, our property had been called _Change, then in the shader variant it should be added as “_CHANGE”. The word _ON corresponds to the default state of the Toggle, so, if the _Enable property is active, we return the default texture color in the fragment shader stage, otherwise we multiply the _Color property by itself.

It is worth mentioning that shader_feature cannot compile multiple variants for an application, what does this mean? Unity will not include variants that we are not using in the final build, which means that we will not be able to move from one state to another at execution time. For this, we will have to use the KeywordEnum drawer that has the variant shader “multi_compile“.

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容