Skip to content

顶点着色器块

顶点块是可选的,可以用来控制材质的顶点着色阶段。顶点块必须包含有效的ESSL 3.0代码(OpenGL ES 3.0支持的GLSL版本)。你可以自由地在顶点块中创建多个函数,但是你必须声明materialVertex函数:

vertex {
    void materialVertex(inout MaterialVertexInputs material) {
        // vertex shading code
    }
}

这个函数将在运行时由着色系统自动调用,并使您能够使用MaterialVertexInputs结构读取和修改材料属性。这个结构的完整定义可以在材质顶点输入部分找到。

您可以使用此结构来计算自定义变量/插值或修改属性的值。例如,下面的顶点块会随时间修改顶点的颜色和UV坐标:

material {
    requires : [uv0, color]
}
vertex {
    void materialVertex(inout MaterialVertexInputs material) {
        material.color *= sin(getUserTime().x);
        material.uv0 *= sin(getUserTime().x);
    }
}

为了更加方便的访问MaterialVertexInputs结构,还可以使用封装的ShaderAPI

Material vertex inputs

struct MaterialVertexInputs {
    float4 color;              // if the color attribute is required
    float2 uv0;                // if the uv0 attribute is required
    float2 uv1;                // if the uv1 attribute is required
    float3 worldNormal;        // only if the shading model is not unlit
    float4 worldPosition;      // always available (see note below about world-space)

    mat4   clipSpaceTransform; // default: identity, transforms the clip-space position, only available for `vertexDomain:device`

    // variable* names are replaced with actual names
    float4 variable0;          // if 1 or more variables is defined
    float4 variable1;          // if 2 or more variables is defined
    float4 variable2;          // if 3 or more variables is defined
    float4 variable3;          // if 4 or more variables is defined
};

!!! Note: 为了获得良好的精度,顶点着色器中的worldPosition坐标会随着摄像机的位置而移动。要获得真实的世界空间位置,用户可以使用getUserWorldPosition(),但是要注意,真实的世界位置可能无法装入浮点数,或者可能以严重降低的精度表示。

!!! Note: 默认情况下,材质的顶点着色器将翻转当前网格材质的UV属性的Y坐标。Uv0 = vec2(mesh_uv0.x, 1.0 - mesh_uv0.y)。您可以使用flipUV属性并将其设置为false来控制此行为。

自定义顶点属性

你可以使用多达8个自定义顶点属性,所有类型都是float4。这些属性可以使用顶点块着色函数getCustom0()到getCustom7()来访问。然而,在使用自定义属性之前,你必须在材料的require属性中声明这些属性:

material {
    requires : [
        custom0,
        custom1,
        custom2
    ]
}