stride3d/stride · error · NotImplementedException
Unsupported format when converting vertex element ({srcDef.V
Error message
Unsupported format when converting vertex element ({srcDef.VertexElement.Format}) What it means
When converting vertex elements by semantic (e.g. POSITION), VertexBufferHelper dispatches on the source PixelFormat to pick a typed copy routine. Only a fixed set of formats (R32G32B32A32_Float, R16G16_Float, R16G16B16A16_Float, R16G16B16A16_UInt, R8G8B8A8_UInt, R8G8B8A8_UNorm) is implemented; anything else hits the default case and throws NotImplementedException. This signals the requested source format conversion is simply not implemented in this helper.
Solutions
- Re-export or convert the mesh so its vertex elements use one of the supported formats (R32G32B32A32_Float, R16G16_Float, R16G16B16A16_Float, R16G16B16A16_UInt, R8G8B8A8_UInt, R8G8B8A8_UNorm)
- Convert the buffer yourself to a supported format (e.g. expand R32G32_Float to R32G32B32A32_Float) before calling the helper
- Extend the switch in VertexBufferHelper with a SelectSrcType call for the missing format if you own the code
- Inspect srcDef.VertexElement.Format at runtime and log it to identify the exact unsupported format
Example fix
// before
var decl = VertexElement.Layout<PositionColorVertex>(); // uses R32G32_Float position
var helper = new VertexBufferHelper(...); // helper.Convert throws
// after
var decl = new VertexDeclaration(
new VertexElement("POSITION", 0, PixelFormat.R32G32B32A32_Float, 0)); // supported format Defensive patterns
Strategy: validation
Validate before calling
static readonly PixelFormat[] supported = { PixelFormat.R32G32B32A32_Float, PixelFormat.R16G16_Float, PixelFormat.R16G16B16A16_Float, PixelFormat.R16G16B16A16_UInt, PixelFormat.R8G8B8A8_UInt, PixelFormat.R8G8B8A8_UNorm };
bool ok = decl.VertexElements.All(e => supported.Contains(e.Format)); Try / catch
try { helper.Convert(...); }
catch (NotImplementedException ex) { logger.Error(ex, "Vertex format unsupported, re-export mesh with supported formats"); throw; } Prevention
- Restrict mesh exporters to the six supported PixelFormats
- Validate vertex declarations at asset-import time
- Add unit tests covering every format in your vertex declarations
When it happens
Trigger: Calling Convert (semantic-based vertex conversion) with an input declaration whose element format is outside the supported list, e.g. R32G32_Float, R10G10B10A2_UNorm, R16G16B16A16_SNorm or any integer/normalized format not in the switch.
Common situations: Importing meshes saved with a different vertex compression format than the helper supports; switching platform/exporter settings that change vertex formats; assuming the helper supports arbitrary formats like it might for interop with other engines.
Related errors
- Unsupported format when converting vertex element ({format})
- Unsupported format when converting vertex element ({elementD
- Invalid Z slice index
- MipLevels must be <= {maxMips}
- Width/Height/Depth must be power of 2
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/8f5a1aebb0b87d2a.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Graphics/VertexBufferHelper.cs:142
{
if (Binding.Declaration.TryGetElement(destDef.VertexElement.SemanticName, destDef.VertexElement.SemanticIndex, out var srcDef))
{
var srcOffset = srcDef.Offset;
var destOffset = destDef.Offset;
var srcFormat = srcDef.VertexElement.Format;
switch (destDef.VertexElement.Format)
{
// The particular semantic used doesn't matter too much here, we're just abusing the relaxed definition to fit any TDest
case PixelFormat.R32G32_Float: SelectSrcType<Relaxed<PositionSemantic>, Vector2>(parameters, srcOffset, destOffset, srcFormat); break;
case PixelFormat.R32G32B32_Float: SelectSrcType<Relaxed<PositionSemantic>, Vector3>(parameters, srcOffset, destOffset, srcFormat); break;
case PixelFormat.R32G32B32A32_Float: SelectSrcType<Relaxed<PositionSemantic>, Vector4>(parameters, srcOffset, destOffset, srcFormat); break;
case PixelFormat.R16G16_Float: SelectSrcType<Relaxed<PositionSemantic>, Half2>(parameters, srcOffset, destOffset, srcFormat); break;
case PixelFormat.R16G16B16A16_Float: SelectSrcType<Relaxed<PositionSemantic>, Half4>(parameters, srcOffset, destOffset, srcFormat); break;
case PixelFormat.R16G16B16A16_UInt: SelectSrcType<Relaxed<PositionSemantic>, UShort4>(parameters, srcOffset, destOffset, srcFormat); break;
case PixelFormat.R8G8B8A8_UInt: SelectSrcType<Relaxed<PositionSemantic>, Byte4>(parameters, srcOffset, destOffset, srcFormat); break;
case PixelFormat.R8G8B8A8_UNorm: SelectSrcType<Relaxed<PositionSemantic>, Color>(parameters, srcOffset, destOffset, srcFormat); break;
default: throw new NotImplementedException($"Unsupported format when converting vertex element ({srcDef.VertexElement.Format})");
}
}
else
{
missing = true;
}
}
return missing;
static void SelectSrcType<TSemantic, TOutput>(InterleavedParameters param, int srcElemOffset, int destElemOffset, PixelFormat format)
where TSemantic :
IConverter<Vector2, TOutput>,
IConverter<Vector3, TOutput>,
IConverter<Vector4, TOutput>,
IConverter<Half2, TOutput>,
IConverter<Half4, TOutput>,
IConverter<UShort4, TOutput>,View on GitHub (pinned to 96fad776d2)