Skip to main content

vcti-shader-derive

The derived-value shader feature: the fragment-stage math that reduces a multi-component result to one scalar.

Overview

A CAE solver reports vectors and tensors — a displacement per node, a stress tensor per element. A colormap needs a single number. Turning one into the other is what vcti-shader-derive does, on the GPU, at draw time: given a stress tensor it produces von Mises, or a principal, or the xy component, and the fringe feature colours whatever comes out.

Doing it in the shader rather than ahead of it is the point. The result buffer is uploaded once, and switching from von Mises to max principal, or from one component order to another, sets a uniform — no re-upload, no CPU pass, no rebuilt shader.

The package ships one Slang module per data family:

Family Components What it derives
scalar 1 identity, absolute, unit conversions
vector2, vector3 2, 3 components, magnitude
dof6_2d, dof6_3d 4, 6 translational and rotational components and magnitudes
symtensor2d 3 components, mean, von Mises, principals, max shear
symtensor3d 6 the above plus invariants, equivalent strain, intensity, deviatoric principals

Around that math the package declares two things: the specs saying what each family needs supplied — which attributes, which uniforms — and the ShaderDefinition saying what the feature is. Both are plain data. Nothing here compiles or runs a shader; a build step does that, using what this package declares.

The math also exists on the CPU, in vcti-derived, which is where value ranges, legends and exports get the same numbers. Two implementations can disagree, so the test suite runs every dispatch case of every family headlessly on a real GPU — through the compiler's render_readback — and diffs it against the catalog. That is test machinery, and it ships with the source, not with the package.

Installation

pip install vcti-shader-derive

Requires Python 3.12, 3.13, or 3.14, matching vcti-shader-base and vcti-derived. 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-derive>=1.0.0

In pyproject.toml dependencies

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

Quick Start

What the feature is

from vcti.shader.derive import DEFINITION

DEFINITION.id, DEFINITION.role.value      # ('derive', 'fragment')
DEFINITION.capabilities                   # ('scalar', 'vector2', 'vector3', 'dof6_2d', …)
len(DEFINITION.slang_modules)             # 7 — one per family

DEFINITION is built at import, so importing the package is all it takes to have one. Its capabilities are one tag per data family, not one for the feature: a shader over a stress tensor takes different inputs from one over a displacement vector, and the two are not interchangeable, so a build step selects on the family it has data for.

Which derived types a family offers

Every derived type a family can produce is a case of one u_derivedType integer, and the table is built from the vcti-derived catalog rather than listed here:

from vcti.derived import DataFamily
from vcti.shader.derive import build_dispatch_table

cases = build_dispatch_table()[DataFamily.SYMTENSOR3D]
[(c.value, c.name) for c in cases][:4]
# [(0, 'xx'), (1, 'yy'), (2, 'zz'), (3, 'xy')]

next(c for c in cases if c.name == "von_mises").value    # 7 — write this to u_derivedType

Not everything in the catalog is here. A derived type ships as a GPU case only if it produces a scalar and all of its parameters have defaults — so principal directions and traction vectors are absent, because there is nothing to colour and a plane normal is field data rather than a uniform.

These integers are a wire contract. They are compiled into the switch in each .slang, written into built shaders, and stored by whatever selected one, so they are append-only; tests/test_dispatch.py pins the whole table so a catalog reordering fails loudly instead of silently renumbering what has already shipped.

What its math needs supplied

Pick a family, and the specs follow from it:

from vcti.shader.derive import (
    component_order_uniform, derived_type_uniform, parameter_uniforms, result_attributes,
)

[(a.name, a.type, a.semantic) for a in result_attributes(DataFamily.SYMTENSOR3D)]
# [('a_result0', 'vec3', 'result.0'), ('a_result1', 'vec3', 'result.1')]

component_order_uniform(DataFamily.SYMTENSOR3D).gl_type          # 'int[6]'
derived_type_uniform({c.name: c.value for c in cases}).name      # 'u_derivedType'
[u.name for u in parameter_uniforms(p for c in cases for p in c.parameters)]
# ['u_nu'] — equivalent strain's Poisson ratio, the family's one parameter

Three things are worth knowing about that.

Results arrive packed. Multi-component data goes into vec3 attributes — ceil(n / 3) of them, zero-padded — because a vertex attribute is at most four components wide and a six-component tensor does not fit in one. The scalar family is the exception and uses a single float.

Component order is a uniform, not a repack. u_componentOrder maps each canonical slot to the lane the host actually packed it into, mirroring vcti-derived's ComponentOrder. A solver that writes (xx, xy, yy, …) is drawn by setting six integers rather than by rewriting the buffer.

Parameters are uniforms too. A defaultable parameter — equivalent strain's nu, an affine conversion's scale and offset — becomes u_<name>, so the derived type stays one dispatch case instead of one shader per value.

Building a shader from it

This package does not compile anything, so the last step belongs to a build step:

# 1. Give the compiler somewhere to resolve `import derive_symtensor3d;` from.
include_dirs = [DEFINITION.slang_dir]

# 2. Merge this feature's specs with a vertex-stage feature's.
attributes = vertex_attributes(stage) + result_attributes(family)

slang_dir is the field with teeth: the .slang files install inside this package, so only this package can resolve where they are.


Dependencies

  • vcti-shader-base — the zero-dependency vocabulary this feature declares itself with (ShaderDefinition, StageRole, AttributeSpec, UniformSpec).
  • vcti-derived — the catalog of derived fields. Unlike its sibling features, derive cannot describe itself without a second dependency: the dispatch table, the capability tags and the contract builders are all read off the catalog at import. The feature is a mirror of that catalog's GPU-supported subset, and the dependency is what keeps the mirror from drifting.

The rest are test-only — needed to run the shader, not to declare the feature, and split across two extras:

  • [test]vcti-shader-compiler>=3.0, whose render_readback the suite drives to run the emitted math headlessly. The test module imports the compiler at module scope, so without it the tests fail to collect rather than skip — which is why it sits here and not under [gl].
  • [gl]vcti-shader-compiler[gl], the GL binding that makes the probes actually run. Every shader package defines a gl extra meaning "what I need to execute shaders"; ci-shader.yml installs .[test,gl] on that contract.

Without [gl] the probe tests skip and everything else passes, which is the right default: compiling a GL binding is a cost only the machines that run shaders should pay.

Nothing that combines, selects, or discovers features: a feature declares itself and stops there.


Documentation

If you want to… Read
Get started using the package Quick Start above
Understand the derived-value model and the design decisions 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_derive-1.0.0.tar.gz (27.4 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_derive-1.0.0-py3-none-any.whl (19.8 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for vcti_shader_derive-1.0.0.tar.gz
Algorithm Hash digest
SHA256 bc1a70c750691132faf535874be490f5066b768a42d900adafbf08b43980db1e
MD5 fde44eac0ad3a46eabb15fb05672cd30
BLAKE2b-256 b820e080fdc7f322da72cf2b8d8b6f0d3649826a19996d069e21b479e8be618c

See more details on using hashes here.

Provenance

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

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

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

File metadata

File hashes

Hashes for vcti_shader_derive-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 33b07f45e906aedc85c871208cc8a4f6f3893d42b4795176055c3332fdfec5dd
MD5 c067ddf9453f7471d728c3e583525afa
BLAKE2b-256 f0a41119863b4515b004f3593dba457d9c50c1b64907e508a88786e1eee7b74d

See more details on using hashes here.

Provenance

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

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

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

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 files

Supported by

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