drawnui/drawnui.net/skmech
Claude Code and agent skill by drawnui/drawnui.net
- community
Checking that the SKILL.md file is still in the repository.
Guidance for SkiaSharp SKMesh custom mesh drawing with SkSL shaders. Use this whenever the user mentions SKMesh, SKMech, custom vertex meshes, mesh shaders, SkSL vertex/fragment programs, 2.5D effects, perspective-warped quads, indexed triangle meshes, or wants to draw geometry through SKCanvas.DrawMesh instead of regular paths or SKVertices.
Install
npx vskill@latest install drawnui/drawnui.net/skmechSKILL.md
SKMech / SKMesh
Use this skill for the experimental SkiaSharp mesh API that wraps Skia's SkMesh.
This API is not the ordinary released 4.147.0 preview surface. Verified on:
- SkiaSharp source branch:
mattleibow/dev-skmesh-api - package version:
4.147.0-pr.3779.2(PR #3779 build artifacts) - EAP feed short URL:
https://aka.ms/skiasharp-eap/index.json
When helping a user, first establish which of these they actually have:
- mesh-enabled package version
- mesh-enabled source branch
- a project that restores from the correct feed or local source
If they are on ordinary stable SkiaSharp packages, do not assume SKMesh exists.
If SKMesh, SKMeshSpecification, SKMeshVertexBuffer, SKMeshIndexBuffer, or SKCanvas.DrawMesh(...) cannot be found, treat that as a package/source mismatch first, not as a coding mistake. In that case use the verified mesh-enabled packages, version 4.147.0-pr.3779.2.
Those packages were verified from the Azure DevOps public PR build artifacts for PR #3779:
- build page:
https://dev.azure.com/xamarin/public/_build/results?buildId=157123 - artifact source:
nuget_previewfrom build157123
Do not assume 4.147.0-preview.1.1 or 4.147.0-preview.1.3 contain SKMesh; they were checked and did not expose the mesh API.
Core mental model
The flow is always:
- Define a mesh specification with attributes, varyings, and SkSL shader source.
- Create vertex data, and optionally index data.
- Wrap that data in
SKMeshVertexBufferand optionallySKMeshIndexBuffer. - Create
SKMeshorSKMesh.MakeIndexed(...). - Draw it with
SKCanvas.DrawMesh(...).
The important objects are:
SKMeshSpecification: schema + SkSL programsSKMeshVertexBuffer: raw vertex bytesSKMeshIndexBuffer: raw index bytes (ushortindices)SKMesh: compiled draw objectSKCanvas.DrawMesh(mesh, paint)orSKCanvas.DrawMesh(mesh, blender, paint)
Constraints to remember
These come from the native SkMesh design and matter during diagnosis:
- At least one attribute is required.
- Vertex shader signature must be
Varyings main(const Attributes attrs). - Fragment shader signature must be either
float2 main(const Varyings varyings)orfloat2 main(const Varyings varyings, out half4 color)/out float4 color. - A
float2varying namedpositionmust exist in the final varying set. If omitted, native Skia adds it implicitly; if declared manually with the wrong type, specification creation fails. - Maximum stride is
1024bytes. - Maximum attributes is
8. - Maximum varyings is
6. - Stride and offsets must be 4-byte aligned.
- Indexed meshes use unsigned 16-bit indices.
- Use
SKRect boundsthat fully encloses the generated geometry. Bad bounds lead to undefined results or clipped output. - If the fragment shader has the `out half4 color` / `out float4 color` parameter you MUST call the `SKMeshSpecification.Make` overload that takes `SKColorSpace` + `SKAlphaType`. The 5-arg overload (no color space) returns
nullwith error:Must provide a color space if FS returns a color. PassSKColorSpace.CreateSrgb()andSKAlphaType.Premulfor normal cases.
Indexed mesh on Blazor WASM - broken PInvoke
In 4.147.0-pr.3779.2, calling SKMeshIndexBuffer.Make(...) followed by SKMesh.MakeIndexed(...) from a Blazor WASM host crashes the Mono interpreter immediately and aborts the runtime. Symptom in browser console:
The non-indexed SKMesh.Make(...) path works fine. The crash is on the PInvoke signature build for the indexed-mesh native call, not on shader / spec / buffer content. Until the SkiaSharp WASM build fixes that signature, on Blazor:
- Use
SKMesh.Make(spec, SKMeshMode.Triangles, vb, vertexCount, 0, bounds, out err)and duplicate shared vertices (6 verts for a quad instead of 4 + indices). - For triangle strips a contiguous strip via
SKMesh.Make(spec, SKMeshMode.TriangleStrip, ...)is also fine.
This restriction is WASM-specific. MAUI / desktop AOT paths can still use MakeIndexed.
Backend support - CRITICAL
`SKCanvas.DrawMesh` is a silent no-op on the CPU/raster backend in the current `4.147.0-pr.3779.2` build. The mesh creation succeeds (spec != null, mesh.IsValid == true), DrawMesh returns without exception, but no pixels are produced. You MUST draw onto a GPU surface for the mesh to be visible.
Surface implications by host:
- Blazor WebAssembly (DrawnUI): default
CanvasRenderingModeisDefault-> CPU raster -> mesh invisible. SetRenderingMode="@RenderingModeType.Accelerated"to switch toSkiaViewAccelerated(WebGL surface) whereDrawMeshactually rasterises. Verified working with the yellow triangle inBlazorSandbox/Pages/SkMeshProbe.razor. - MAUI / desktop: ensure draw target is a GPU-backed surface (e.g.
SKCanvasViewwith hardware acceleration /SkiaViewAccelerated). - Server-side / `SKSurface.Create(SKImageInfo)`: that is a raster surface - mesh will not draw. Use
SKSurface.Create(GRRecordingContext, ...)if you need offscreen GPU.
If a mesh "draws nothing" but no errors appear and mesh.IsValid is true, the backend is the first suspect, before shader or buffer packing.
Blazor WebAssembly trimming - CRITICAL
SkiaSharp ships as a trimmable assembly. In a default Blazor WASM build (Debug dotnet build is enough - does not require Publish) the trimmer removes every SKMesh* type from the runtime SkiaSharp.wasm because the host project does not statically reference them at build time, even when user razor pages reference them. Razor-compiled references are not seen by the trimmer's flow analysis early enough to keep the type metadata.
Symptom at runtime:
Verification commands:
Fix - add to the host .csproj (e.g. BlazorSandbox.csproj):
Do NOT use <TrimmerRootAssembly Include="SkiaSharp" /> alone - without RootMode="EntireAssembly" the assembly is rooted but individual unused types are still pruned, so the symptom persists. After changing this you usually have to delete `bin/` and `obj/` of the Blazor host project before rebuilding because the webcil output is content-hashed and the cached trimmed copy is otherwise reused.
Practical workflow
When asked to implement or debug mesh drawing:
- Verify package/branch availability first.
- Verify host is rendering on a GPU surface (Accelerated mode, WebGL canvas, hardware MAUI canvas) - raster = silent no-op.
- For Blazor WASM, verify trimmer is rooting
SkiaSharp(TrimmerRootAssemblywithRootMode="EntireAssembly"). - Start from a tiny non-indexed triangle.
- Keep the first spec minimal: one
Float2position attribute, no custom varyings. - Make the fragment shader output a solid color first - and use the
Makeoverload withSKColorSpace+SKAlphaTypebecauseout half4 colorrequires it. - Only after that works, add indexed geometry, uniforms, children, or perspective math.
- Treat the
errorsout parameter fromSKMeshSpecification.Make(...)andSKMesh.Make(...)as the first diagnostic signal.
Diagnostic decision tree
Symptom-first triage when "mesh doesn't draw":
System.TypeLoadExceptionfor anySKMesh*type -> trimmer stripped types. ApplyTrimmerRootAssembly RootMode="EntireAssembly"and cleanbin/+obj/.- Mono interp crash with
ves_pinvoke_method/get_build_args_from_sig_infoafter a successful unrelated mesh draw -> indexed-mesh PInvoke broken on Blazor WASM. Switch to non-indexedSKMesh.Make. spec == null, error containsMust provide a color space if FS returns a color-> switch to color-space overload ofSKMeshSpecification.Make.spec == null, other shader text -> SkSL syntax / missing varying / wrong main signature.mesh == null-> vertex/index count, offset, or bounds wrong.mesh.IsValid == true,DrawMeshreturns silently, no pixels -> CPU raster backend. Switch host to GPU surface (Accelerated mode in Blazor / hardware-accelerated surface in MAUI).- Pixels appear but wrong color/position -> fragment returning bad position; flip to outputting solid color and
return varyings.positionas-is to verify pipeline.
API reminders
SKMeshSpecification.Make(...)returnsnullplus an error string on shader/spec failure.SKMesh.Make(...)andSKMesh.MakeIndexed(...)also returnnullplus an error string on failure.mesh.IsValidis a useful sanity check after creation.SKMeshVertexBuffer.Make(ReadOnlySpan<byte>)andSKMeshIndexBuffer.Make(ReadOnlySpan<byte>)copy raw bytes, so callers usually packfloat[]orushort[]withMemoryMarshal.AsBytes(...).SKMesh.Make(...)can take optionalSKData uniformsandReadOnlySpan<SKRuntimeEffectChild> children.SKCanvas.DrawMesh(...)still requires a normalSKPaint.
What to read next
Read references/api-overview.md when you need the API surface, packaging notes, and common failure modes.
Read references/examples.md when you need copyable examples for:
- first triangle
- indexed quad
- upgrade from plain color to paint shader/blender interaction
- debugging checklist
Output expectations
When answering with this skill active:
- state whether the user's package/source likely contains
SKMesh - give the smallest working example first
- call out whether the issue is package mismatch, shader/spec error, buffer packing error, or bounds error
- prefer concrete code over abstract explanation
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingdocs/skills/skmech/SKILL.md
Popularity
- Repository stars
- 409
- Repository forks
- 39
- 7-day trend score
- 0
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/drawnui/drawnui.net/skmech)