Skip to main content

vcti-shader-mask

The mask shader feature: the vertex-stage cull that draws only the submeshes a client-owned mask marks.

Overview

A viewer needs to hide and show components of a mesh while the user works — and in a results viewer, to hide an element set the solver reported on, which is finer than a component. Rebuilding geometry for each of those is slow and gets slower as the model grows, so this feature does it differently: the mesh is divided once into submeshes — any subsets the client wants to address as units — every vertex carries the id of the one it belongs to, and the client keeps a mask of one byte per submesh, zero for hidden and one for drawn. The shader fetches each vertex's byte and collapses the vertex outside the clip volume when it is zero.

Hiding any scattered set of submeshes is then one texture write. No geometry is rebuilt, no buffer repacked, and the cost does not depend on how the affected submeshes are scattered through the mesh.

Which id the mask is indexed by, and what the mask means, are the client's choices per pass. A normal pass binds the visibility mask. A selection-outline pass binds the selection mask to the same shader and draws only the selected submeshes into an outline target. An isolate mode binds a third. The feature culls; the renderer composes passes.

vcti-shader-mask is the shader half of that arrangement. It ships the Slang that addresses the mask and applies its rule, a Python mirror of the same rule so a caller can build a mask and read one back, the specs saying what the cull needs bound, and the ShaderDefinition saying what the feature is.

Everything here is a declaration or fixed shader source. Nothing compiles or runs a shader; a build step does that, using what this package declares.

Installation

pip install vcti-shader-mask

Requires Python 3.12, 3.13, or 3.14, matching vcti-shader-base. Nothing native is built on that path, and nothing native is built by [test] either — only the [gl] extra pulls a GL binding, and only on 3.14 does that compile from source for want of a cp314 wheel.

In requirements.txt

vcti-shader-mask>=1.0.0

In pyproject.toml dependencies

dependencies = [
    "vcti-shader-mask>=1.0.0",
]

Quick Start

Build a mask

The client owns the mask, so building it is the first thing a caller does. One value per submesh, in id order:

from vcti.shader.mask import DRAWN, HIDDEN, pack_mask

visible = pack_mask([True, True, False, True])
assert visible == (DRAWN, DRAWN, HIDDEN, DRAWN) == (1, 1, 0, 1)

The shader's rule is an integer compared with zero, and the Python mirror is the same rule — any non-zero value draws, so a client that writes 255 is not wrong:

from vcti.shader.mask import is_drawn

assert not is_drawn(0)
assert is_drawn(1) and is_drawn(255)

A value a byte cannot hold is refused rather than truncated, because 256 would upload as 0 and hide a submesh the caller meant to draw:

from vcti.shader.mask import check_value

check_value(255)
try:
    check_value(256)
except ValueError as error:
    assert "outside 0-255" in str(error)

Upload it

The mask is an R8UI texture, one texel per submesh, with NEAREST filtering. The id is the address; there is no stride. The texture is two-dimensional, because a single row would cap the submesh count at whatever MAX_TEXTURE_SIZE a device reports; wrapped across rows, the cap is that number squared. A caller picks a width and the address wraps:

from vcti.shader.mask import rows_needed, texel

assert texel(14_000, 2048) == (1712, 6)
assert rows_needed(50_000, 2048) == 25

Both refuse a width that is not positive, and a negative id or count. The shader divides by the same width, so a bad value would otherwise surface on the GPU as a wrong texel with nothing to say so:

try:
    texel(0, 0)
except ValueError as error:
    assert "not positive" in str(error)

Pass the width as u_maskLutWidth. An unwritten or incomplete texture reads as zero and hides everything, which is the loud failure this design chooses over a quiet one.

What a build step binds

from vcti.shader.mask import vertex_attributes, vertex_uniforms

(attribute,) = vertex_attributes()
assert (attribute.name, attribute.type, attribute.semantic) == ("a_maskId", "int", "mask-id")

(uniform,) = vertex_uniforms()
assert uniform.name == "u_maskLutWidth"

The attribute is named for the feature, not for what the id counts. The client binds whichever id buffer it likes to it — a submesh id, a mesh-component id — and where another feature is keyed by the same id, binds the same buffer to that feature's attribute too.

The table sampler itself is not in there — a texture input cannot yet be expressed in vcti-shader-base, so it is contract rather than spec. See docs/design.md.

Select a pipeline

One tag for the behaviour and one naming the table encoding:

from vcti.shader.mask import DEFINITION

assert DEFINITION.id == "mask"
assert DEFINITION.role.value == "vertex"
assert set(DEFINITION.capabilities) == {"mask", "mask-lut-r8ui"}
assert DEFINITION.slang_modules == ("mask.slang", "mask_r8ui.slang")

The mask

Value Meaning
0 hidden — the vertex is collapsed outside the clip volume
1 drawn
anything else drawn; the shader tests != 0

One byte per submesh — not a bit, not a word — and no stride. A second per-submesh state — a selection, an isolate set — is a second mask of the same shape bound in a different pass, never a second bit here.

API surface

Name What it is
DEFINITION the ShaderDefinition a build step imports to compose this feature
SLANG_DIR, SLANG_MODULES the installed Slang directory, and the modules in it
pack_mask, mask_value, is_drawn, check_value build a mask, and read it the way the shader does
HIDDEN, DRAWN, VALUE_MAX the values
texel, rows_needed where a submesh's value lands, and how tall the texture is
vertex_attributes, vertex_uniforms, ATTRIBUTE, WIDTH what a build step binds
CAPABILITY, ENCODING, ENCODING_CAPABILITY the tags, and the shipped texture format

Dependencies

vcti-shader-base is the only runtime dependency — declaring a feature is pure data. vcti-shader-compiler>=4.0.0 and numpy are test-only, and a separate gl extra adds the GL binding the shader tests need to execute rather than skip.

Documentation

If you want to… Read
Get started using the package Quick Start above
Understand the mask contract and the decisions behind it docs/design.md
Navigate or modify the source, including the Slang docs/source-guide.md

The full API reference is generated from the source docstrings and published in the unified VCollab docs.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vcti_shader_mask-1.0.0.tar.gz (33.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

vcti_shader_mask-1.0.0-py3-none-any.whl (14.1 kB view details)

Uploaded Python 3

File details

Details for the file vcti_shader_mask-1.0.0.tar.gz.

File metadata

  • Download URL: vcti_shader_mask-1.0.0.tar.gz
  • Upload date:
  • Size: 33.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for vcti_shader_mask-1.0.0.tar.gz
Algorithm Hash digest
SHA256 2f156b079353757bfdbed0ad6401ec45470a60480e8d90b50c748bb6fb4895a6
MD5 bac716999e8389ed68e3156a166797c3
BLAKE2b-256 e1b23f1d1b09cf76fbde08142b2ed2d8056f23be84e8179bf4b50f07ffbb7c73

See more details on using hashes here.

Provenance

The following attestation bundles were made for vcti_shader_mask-1.0.0.tar.gz:

Publisher: release.yml on vcollab/vcti-python-shader-mask

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file vcti_shader_mask-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for vcti_shader_mask-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f429034595b1c0cea35b3a86689bd41316af09218cdcba1ffc02eaf27495a698
MD5 892583e56a587ae097b6302e6afab825
BLAKE2b-256 c50e7945cf3e8b375d33fad8039105f1b8cba0da6979253dd3f736825749061b

See more details on using hashes here.

Provenance

The following attestation bundles were made for vcti_shader_mask-1.0.0-py3-none-any.whl:

Publisher: release.yml on vcollab/vcti-python-shader-mask

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

1.1.0

2 files

This release

1.0.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page