可以为表面着色器 appdata 输入设置顶点 alpha 吗?

Can vertex alpha be set for a surface shader appdata input?

我的着色器做了一些数学运算来确定顶点 alpha,所以我有一个函数可以在数据传递到我的 surf 函数之前执行此操作。

    #pragma surface surf Standard alpha
    #pragma target 3.0

    struct Input
    {
        float2 uv_MainTex;
        float tranparency;
    };

    void foo(inout appdata_full v, out Input o) {
        UNITY_INITIALIZE_OUTPUT(Input, o);
        float someAlpha;
        [...some maths to create someAlpha value...]
        v.color.a = someAlpha;
        o.transparency = v.color.a;
    }

    half _Glossiness;
    half _Metallic;
    fixed4 _Color;

    UNITY_INSTANCING_BUFFER_START(Props)
    UNITY_INSTANCING_BUFFER_END(Props)

    void surf (Input IN, inout SurfaceOutputStandard o)
    {
        fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
        o.Albedo = c.rgb;
        o.Metallic = _Metallic;
        o.Smoothness = _Glossiness;
        o.Alpha = c.a;
    }

然后当我使用 Input IN 时,我希望在设置 alpha 时反映 someAlpha:

o.Alpha = c.a; //Can I do c.a * IN.transparency ?

目前,完全没有任何反应。如何在 surf 中使用我想要的 alpha 值?

是的。您可以向 Input 对象添加 COLOR 语义:

struct Input {
    float4 uv_MainTex;
    float4 color : COLOR;
    };

然后在foo中分配给它(尽管如果你有#pragma surface surf这可能没有必要):

void foo(inout appdata_full v, out Input o) {
    UNITY_INITIALIZE_OUTPUT(Input, o);
    float someAlpha;
    [...some maths to create someAlpha value...]
    v.color.a = someAlpha;

    o.color = v.color;
}

然后在surf中使用:

void surf (Input IN, inout SurfaceOutputStandard o)
{
    fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
    fixed4 vertexColor = IN.color;
    o.Albedo = c.rgb;
    o.Metallic = _Metallic;
    o.Smoothness = _Glossiness;
    o.Alpha = vertexColor.a * c.a; 
}

最后,通过将 #pragma surface surf Standard alpha 更改为:

,告诉 Unity 在表面着色器之前使用 foo 作为顶点着色器
#pragma surface surf Standard alpha vertex:foo

我无法确认批准的答案中写的是什么。我 运行 进行了一些测试并查看了生成的代码。

表面着色器总是将顶点程序中的颜色设置为:

o.color = v.color;

不管它实际上说了什么。所以如果你有:

struct Input {
    fixed4 color : COLOR;
};

void vert(inout appdata v, out Input o) {
    o.color = v.color * fixed4(2,1,1,1);
}

Unity 会生成这个:

v2f_surf vert_surf (appdata v) {
  UNITY_SETUP_INSTANCE_ID(v);
  v2f_surf o;
  [...]
  Input customInputData;
  vert (v, customInputData);
  [...]
  o.color = v.color;
  [...]
}

所以您可以做的是将您的代码放入 surf 函数中:

float4 vertexColor = IN.color * fixed4(2,1,1,1);