stride3d/stride · error · ArgumentException

meshData is not simple.

Error message

meshData is not simple.

What it means

GenerateTangentBinormal computes per-vertex tangents and binormals and only supports 'simple' meshes — a single vertex buffer containing all attributes. This ArgumentException is thrown when meshData.IsSimple() returns false (multiple vertex buffers or non-simple layout), because the tangent math indexes directly into VertexBuffers[0].

Solutions

  1. Re-interleave the mesh into one vertex buffer so IsSimple() is true, then compute tangents
  2. Compute tangents manually for multi-buffer meshes (parallel arrays) instead of using this extension
  3. Skip tangent generation and supply tangents from the asset/importer

Example fix

// before
mesh.GenerateTangentBinormal(); // multi-buffer mesh
// after
if (mesh.IsSimple())
    mesh.GenerateTangentBinormal();
else
    mesh = RebuildSingleBuffer(mesh); // then GenerateTangentBinormal
Defensive patterns

Strategy: validation

Validate before calling

if (mesh.IsSimple()) mesh.GenerateTangentBinormal();
else mesh = RebuildSingleBuffer(mesh); // then generate tangents

Type guard

static bool CanGenerateTangents(MeshDraw mesh) => mesh.IsSimple();

Try / catch

try { mesh.GenerateTangentBinormal(); }
catch (ArgumentException ex) when (ex.Message.Contains("not simple")) {
    mesh = RebuildSingleBuffer(mesh);
    mesh.GenerateTangentBinormal();
}

Prevention

When it happens

Trigger: Calling GenerateTangentBinormal on a MeshDraw with multiple vertex buffers, or one whose declaration is not a simple interleaved layout.

Common situations: Meshes with split position/attribute streams; multi-buffer meshes produced by merge tooling; forgetting to check IsSimple before generating tangents.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/9e0df2a4c6209b74. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Rendering/Extensions/TNBExtensions.cs:23

using Stride.Graphics.Data;
using Stride.Rendering;

namespace Stride.Extensions
{
    public static class TNBExtensions
    {
        /// <summary>
        /// Generates the tangents and binormals for this mesh data.
        /// Tangents and bitangents will be encoded as float4:
        /// float3 for tangent and an additional float for handedness (1 or -1),
        /// so that bitangent can be reconstructed.
        /// More info at http://www.terathon.com/code/tangent.html
        /// </summary>
        /// <param name="meshData">The mesh data.</param>
        public static unsafe void GenerateTangentBinormal(this MeshDraw meshData)
        {
            if (!meshData.IsSimple())
                throw new ArgumentException("meshData is not simple.");

            if (meshData.PrimitiveType != PrimitiveType.TriangleList
                && meshData.PrimitiveType != PrimitiveType.TriangleListWithAdjacency)
                throw new NotImplementedException();

            var oldVertexBufferBinding = meshData.VertexBuffers[0];
            var indexBufferBinding = meshData.IndexBuffer;
            var indexData = indexBufferBinding?.Buffer.GetSerializationData().Content;

            var oldVertexStride = oldVertexBufferBinding.Declaration.VertexStride;
            var bufferData = oldVertexBufferBinding.Buffer.GetSerializationData().Content;

            fixed (byte* indexBufferStart = indexData)
            fixed (byte* oldBuffer = bufferData)
            {
                var result = VertexHelper.GenerateTangentBinormal(
                    vertexDeclaration: oldVertexBufferBinding.Declaration,
                    vertexBufferData: (nint)oldBuffer,

View on GitHub (pinned to 96fad776d2)