Skip to main content

vcti-shader-base

The vocabulary a shader feature declares itself with: attribute/uniform/output specs and the ShaderDefinition record. Zero dependencies.

Overview

Shaders in this system are compiled ahead of time.

A build step turns Slang sources into GLSL ES text. Whatever draws with the result later — a web viewer, a test harness — did not compile it and cannot inspect it. So it has to be told what the shader expects:

  • which buffer belongs in each vertex attribute,
  • which uniforms exist and how large they are,
  • which integer selects which mode.

Writing that down is what this package is for.

A shader feature is one piece of composable shading math. Here are some examples:

  • deform moves geometry,
  • fringe colors it by bands,
  • derive computes a quantity from a source field — scalar, vector, 6-DOF or tensor,
  • atom-lut culls hidden atoms.

Each ships as its own installable package. Each declares what its own math needs, and says what it is.

vcti-shader-base is the vocabulary for writing exactly that declaration, and nothing more:

  • Field specsAttributeSpec (per-vertex inputs), UniformSpec (draw-constant values), OutputSpec (fragment outputs).
  • The definitionShaderDefinition, with StageRole: how a feature names the stage it runs in, the Slang modules it ships, and the capability tags it introduces.

Declaring a feature needs nothing else — no compiler, no build toolchain, no other package.

Installation

pip install vcti-shader-base

Requires Python 3.12, 3.13, or 3.14. No runtime dependencies.

In requirements.txt

vcti-shader-base>=1.0.0

In pyproject.toml dependencies

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

Quick Start

Declare what the shading math needs

Consider a structural analysis. A CAE solver reports how far each node of a mesh moves under a load, and we want to draw the deformed shape.

Every vertex carries two values — where it sits, and how far it moved. Both vary per vertex, so both are attributes. We also want to exaggerate the movement, scaling it independently in x, y and z; that factor is the same for every vertex in the draw, so it is a uniform:

from vcti.shader.base import AttributeSpec, UniformSpec

inputs = (
    AttributeSpec("a_position", "vec3", "coordinates"),
    AttributeSpec("a_deformation", "vec3", "deformation"),
)
uniforms = (UniformSpec("u_deformScale", "vec3"),)

a_position and a_deformation are the names the shader source uses. The third argument is the semantic, and it is what makes the declaration useful to a caller. A caller has buffers of its own — node coordinates, a displacement field — and must know which one goes where. The name cannot answer that: it is a shader-source detail and can be renamed. The semantic names the data instead, so coordinates means mesh node positions and deformation means the displacement vector.

Two optional fields are worth knowing. array_length stays a number so Python can size a buffer, and gl_type joins it onto the type only where the type is emitted:

UniformSpec("u_bandColors", "vec4", array_length=8).gl_type   # 'vec4[8]'
UniformSpec("u_deformScale", "vec3").gl_type                  # 'vec3'

named_values turns an integer a caller would otherwise hard-code into something nameable:

mode = UniformSpec("u_deformMode", "int", named_values={"displacement": 0, "rotation": 1})
mode.named_values["rotation"]      # 1 — the value to write

A feature in the fragment stage also declares what it writes:

from vcti.shader.base import OutputSpec

outputs = (OutputSpec("fragColor", "vec4"),)

Describe the feature itself

The specs say what the shading math needs. A ShaderDefinition says what the feature is. Each feature constructs exactly one and exports it as DEFINITION:

from pathlib import Path
from vcti.shader.base import ShaderDefinition, StageRole

DEFINITION = ShaderDefinition(
    id="deform",
    role=StageRole.VERTEX,
    capabilities=("deform3", "deform6"),
    slang_modules=("deform.slang",),
    slang_dir=Path(__file__).parent / "slang",
    description="deform3 scaled displacement; deform6 Rodrigues rotation.",
)
  • role is where the feature's math runs. VERTEX moves geometry; FRAGMENT decides color.
  • capabilities are the tags this feature offers. They are opaque strings and each feature owns its own, so adding one needs no release of this package.
  • slang_modules names the Slang modules this feature publishes for a shader to import. slang_dir says where they live — and it is the field with teeth: the .slang files are installed inside the feature's own package, so only the feature can resolve the directory, and the build passes it to the compiler as an import search path. This package only records the path; it never opens it, so confirming the files are really there is the feature's own test's job.

A feature that stops here is complete: it constructs one ShaderDefinition, exports it as DEFINITION, and declares the specs its math needs.

Type Reference

Type Fields Notes
AttributeSpec name, type, semantic A per-vertex input, and what its data is
UniformSpec name, type, array_length=None, named_values=None gl_type joins the array suffix; named_values only on dispatch uniforms
OutputSpec name, type A fragment output; no semantic, since there is nothing to bind
ShaderDefinition id, role, capabilities, slang_modules, slang_dir, description="" One feature's self-declaration
StageRole VERTEX, FRAGMENT Where the feature's math runs

Every type is immutable and compared by value, and every one is hashable — so specs can go in a set or a dict key, and duplicates drop out on their own.

Dependencies

None — the standard library covers it. A feature can declare its specs and its definition without installing a compiler or a build toolchain behind it.

Development extras: test (pytest, pytest-cov), lint (ruff), typecheck (mypy).

Documentation

If you want to… Read
Get started using the package Quick Start above
Build and ship a complete feature, and avoid the pitfalls docs/patterns.md
Understand what these types describe and why docs/design.md
Navigate or modify the source docs/source-guide.md

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_base-1.0.0.tar.gz (11.8 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_base-1.0.0-py3-none-any.whl (8.7 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for vcti_shader_base-1.0.0.tar.gz
Algorithm Hash digest
SHA256 7585aefb468fad4a11697a97176122fe8861f1d7d1f095ad9dbe7213a7f3a553
MD5 b0fe18dde656c14305aa20e3a35bc955
BLAKE2b-256 8b7d2572981a48a29489115beb89c858f2a2a29f90f61426d7bfe5585663590b

See more details on using hashes here.

Provenance

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

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

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_base-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for vcti_shader_base-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fad2a1ea2c04a3ab8ff7fda3f31a4d144faf24de8ac375d4ee6ad13f12a09829
MD5 75114728fd93ce92a66107715dc58b52
BLAKE2b-256 50ef315c3eecd7e6158d806f73fa1f12bf2ead9c1e262894148b23adaa2e1ef0

See more details on using hashes here.

Provenance

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

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

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

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page