fragment_shaders

Custom and composable per-fragment shaders shared by the renderers.

A fragment stage is a Taichi @ti.func with the uniform stage contract (see algan.rendering.raytracing.shading_taichi): it shades one surface hit from the running color, the interpolated surface attributes, its slice of the per-primitive parameter block and the scene lights, and returns the new vec4 (RGB + glow). Stages are composed into a pipeline (a list run left-to-right, each fed the previous stage’s output) via register_pipeline(), which bakes the pipeline into a single injected @ti.func (see taichi-func-injection) and hands back a per-primitive pipeline id.

Users reach this through algan.animatable_base.mob_materials.MobMaterialsMixin.set_fragment_shader(). A stage may be a built-in material (the @ti.func ports of the core lit shaders, exposed here as FragmentStage and also resolvable from their PyTorch shader functions, e.g. phong_shader) or a custom FragmentStage wrapping the user’s own @ti.func plus its animatable parameter specs.

Because a stage is plain Taichi scalar math, existing built-in materials double as fragment shaders and compose with custom ones, e.g. mob.set_fragment_shader([cosine_color, phong_shader]) recolors each fragment with a cosine wave and then lights the result with Blinn-Phong.

Classes

FragmentPipelineShader

Marker shader for a mob with a custom fragment pipeline.

FragmentStage

A fragment shader stage: a Taichi @ti.func plus its parameter specs.

Functions

build_frag_pipelines(pids=None)[source]

Composed pipeline funcs to inject as the shade kernel’s frag_pipelines template argument, indexed by pid - _USER_PIPELINE_BASE and ordered by id.

pids is the batch’s own pipeline ids in packing order; everything else is dropped (see _select_by_pid()). Pass it. The registry is process-global and append-only, and Taichi specialises the shade kernels on this tuple, so handing over the whole registry puts every render in a process that ever registered a pipeline onto its own uncached kernel variant – including renders with no custom shader at all, which is both the pathology this argument exists to close and the reason a batch-narrowed tuple is what the tracer passes. None (the whole registry) is the conservative fallback for a batch whose merged scene cannot enumerate its ids.

build_frag_scatters(pids=None)[source]

Per-pipeline custom scatter funcs (None = default scatter), ordered by id, for the monolithic wavefront’s per-material continuation dispatch – and for the path tracer’s, which takes the same tuple and continues along one sampled branch of it (pt_shade).

Narrowed by pids exactly as build_frag_pipelines() is, and for the same reason.

build_fragment_pipeline(shader)[source]

Resolve + register a fragment shader (a stage or a list of stages) and return (marker, param_specs).

marker is a FragmentPipelineShader to assign to the mob’s shader; param_specs is an ordered [(name, default)] of the pipeline’s animatable parameters (duplicate names across stages are suffixed) for the mob to register as animatable attributes.

register_pipeline(stages)[source]

Register a pipeline (list of FragmentStage) for in-kernel use.

Returns (pipeline_id, total_width, layout) where layout is a list of (name, slot, width, default) for every parameter across all stages (with slot the absolute offset into the per-primitive param block). Identical pipelines (same stage funcs + widths + scatter) reuse the same id and composed func.

resolve_stage(shader)[source]

Resolve a user-supplied shader to a FragmentStage.

Accepts a FragmentStage (returned as-is) or a built-in PyTorch material shader function (mapped to its stage port). Raises for anything else – a custom fragment shader must be wrapped in a FragmentStage so its parameters are known.