void MaskField(
        string label,
        Material material,
        string maskTypePropertyName,
        string maskParametersPropertyName,
        string maskAxisPropertyName,
        Vector4[] axisCache,
        Vector4[] parameterCache,
        bool normalMapEnabled)
    {
        EditorGUI.BeginChangeCheck();
        LayerMaskType maskType = (LayerMaskType)AvatarMaterialEditorGUILayout.IntField(label, material, maskTypePropertyName, layerMaskTypeLabels);

        if (EditorGUI.EndChangeCheck())
        {
            material.SetVector(maskAxisPropertyName, axisCache[(int)maskType]);
            material.SetVector(maskParametersPropertyName, parameterCache[(int)maskType]);
        }

        // Show mask-specific controls
        EditorGUI.BeginChangeCheck();
        switch (maskType)
        {
        case LayerMaskType.Positional:
            AvatarMaterialEditorGUILayout.Vector3Field("Axis", material, maskAxisPropertyName);
            AvatarMaterialEditorGUILayout.VectorComponentField("Center distance", material, maskParametersPropertyName, 0);
            AvatarMaterialEditorGUILayout.VectorComponentField("Fade above", material, maskParametersPropertyName, 1);
            AvatarMaterialEditorGUILayout.VectorComponentField("Fade below", material, maskParametersPropertyName, 2);
            break;

        case LayerMaskType.ViewReflection:
            AvatarMaterialEditorGUILayout.Vector3Field("Axis", material, maskAxisPropertyName);
            AvatarMaterialEditorGUILayout.VectorComponentField("Fade begin", material, maskParametersPropertyName, 0);
            AvatarMaterialEditorGUILayout.VectorComponentField("Fade end", material, maskParametersPropertyName, 1);
            if (normalMapEnabled)
            {
                AvatarMaterialEditorGUILayout.VectorComponentField("Normal map strength", material, maskParametersPropertyName, 2);
            }
            break;

        case LayerMaskType.Fresnel:
            AvatarMaterialEditorGUILayout.VectorComponentField("Power", material, maskParametersPropertyName, 0);
            AvatarMaterialEditorGUILayout.VectorComponentField("Fade begin", material, maskParametersPropertyName, 1);
            AvatarMaterialEditorGUILayout.VectorComponentField("Fade end", material, maskParametersPropertyName, 2);
            if (normalMapEnabled)
            {
                AvatarMaterialEditorGUILayout.VectorComponentField("Normal map strength", material, maskParametersPropertyName, 3);
            }
            break;

        case LayerMaskType.Pulse:
            AvatarMaterialEditorGUILayout.Vector3Field("Axis", material, maskAxisPropertyName);
            AvatarMaterialEditorGUILayout.VectorComponentField("Pulse distance", material, maskParametersPropertyName, 0);
            AvatarMaterialEditorGUILayout.VectorComponentField("Pulse speed", material, maskParametersPropertyName, 1);
            AvatarMaterialEditorGUILayout.VectorComponentField("Power", material, maskParametersPropertyName, 2);
            break;
        }
        if (EditorGUI.EndChangeCheck())
        {
            parameterCache[(int)maskType] = material.GetVector(maskParametersPropertyName);
            axisCache[(int)maskType]      = material.GetVector(maskAxisPropertyName);
        }
    }