After Effects template architecture, NexRender integration, data schema, and depth compositing pipeline
The system is composed of three distinct layers that communicate exclusively through a shared data schema. The web front end collects user input. NexRender carries that input into After Effects. After Effects evaluates it at render time. No layer has any direct knowledge of the others — they share only a vocabulary of keyword strings.
| Layer | Technology | Responsibility |
|---|---|---|
| Front end | Next.js / React | Presents user-facing variable selection. Validates input against schema. Submits job request to Django API. |
| API & render queue | Django / NexRender | Receives job request. Constructs NexRender job manifest. Queues and executes render. Returns download link on completion. |
| Render target | After Effects (2025) | Receives variable values via text layer injection. Evaluates expressions to configure precomp visibility. Composites user label into footage. Renders output file. |
The templates were built for After Effects 2025 and are not backwards-compatible with earlier versions. The expression engine behaviour and certain effect parameters differ across versions in ways that affect the depth compositing stack.
Every template in the library shares the same structural specification regardless of the recipe it contains. The specification defines reserved layer names, required composition names, the expression pattern for variety switching, and the asset naming conventions that the render pipeline depends on.
Each template contains exactly two compositions whose names are reserved and must not be altered.
| Composition name | Purpose |
|---|---|
MILK_EXPORT |
The render target. NexRender locates this composition by name to initiate the render job. Contains all variable text layers and the final composited output. |
MILK_SOURCE |
The source footage composition. Contains the original recipe video, the vessel precomp hierarchy, and depth map layers. Referenced by MILK_EXPORT. |
NexRender resolves the render target by composition name only. A composition with a corrected or abbreviated name — Milk_Export, MILKEXPORT, export — will not be found. The render job will fail silently or target the wrong composition with no error output.
A placeholder layer named MILK_LABEL exists in every template. It is blank in the source file. NexRender replaces this layer with the user-uploaded label asset at job execution time by matching the layer name string exactly.
MILK_LABEL is case-sensitive and must match exactly as writtenFour text layers in MILK_EXPORT hold the variable values. Their names are reserved. NexRender's setText action targets them by name and writes the uppercase schema keyword value before rendering begins.
| Layer name | Written by | Read by |
|---|---|---|
VARIETY_VAR |
NexRender setText action | Opacity expressions on each milk-variety precomp |
VESSEL_VAR |
NexRender setText action | Opacity expressions on vessel-type precomps |
CAP_VAR |
NexRender setText action | Opacity expressions on cap-colour layers within active vessel precomp |
SIZE_VAR |
NexRender setText action | Scale expression on vessel null; size-specific comp switch expression |
All visibility control uses the same expression pattern. An expression on a precomp's Opacity property reads the source text of the relevant variable layer and evaluates it against the keyword value associated with that precomp. The expression returns 100 if the strings match, 0 if they do not.
This pattern is intentionally minimal. The text layer contains the raw uppercase keyword string with no whitespace and no formatting. Any deviation — a trailing space, a capitalisation difference — causes the expression to evaluate to 0 and the precomp to be invisible in the render.
Long file names cause decompression failures when NexRender unpacks the project bundle for rendering. This limit was discovered during testing and is not documented by NexRender. All source assets in the templates use the following conventions:
dm_, short descriptor, extension — e.g. dm_jug_hg.exrjg_white_hg (jug, white, half-gallon)The Milk Dynamic Video Schema defines the canonical keyword string for every variable in the system. The front-end form labels, the backend API field names, the NexRender action targets, and the After Effects expression comparisons all reference the same document. The schema is the only interface between the three layers.
The schema was authored before any template was built. Templates were written to satisfy the schema, not the other way around. Introducing a new variable requires a schema revision before any template or API change is made.
| Variable | AE layer name | Accepted keyword values | Notes |
|---|---|---|---|
| Milk variety | VARIETY_VAR |
WHOLE / STRAWBERRY / CHOCOLATE / SKIM / 2PERCENT / LACTOSE-FREE |
Per-recipe availability. Recipes not containing chocolate milk do not include the chocolate precomp set. |
| Vessel type | VESSEL_VAR |
JUG / CARTON / BOTTLE |
Determines active vessel precomp hierarchy. Each vessel type has its own depth-scanned label placement null. |
| Cap colour | CAP_VAR |
RED / BLUE / WHITE / GREEN / YELLOW / ORANGE / PURPLE / BLACK / BROWN / PINK |
Cap layer visibility is controlled by expression within the active vessel precomp. Not all cap colours are available for all vessel types. |
| Carton size | SIZE_VAR |
HALF-PINT / PINT / QUART / HALF-GALLON |
Drives scale expression on vessel null. Non-standard sizes use a size-specific precomp with adjusted depth map. |
| Label asset | MILK_LABEL |
User-uploaded PNG or JPG. No keyword — the layer is replaced by NexRender directly. | Accepted dimensions: minimum 500×500 px. Transparent background supported. Labels with transparency composite against vessel surface colour. |
HALF-GALLON, LACTOSE-FREENexRender is a headless After Effects render automation system. It accepts a job manifest — a JSON object — opens the specified AE project on a render node, makes the modifications described in the manifest, and executes the render queue. It has no awareness of the content it is rendering. It reads strings and writes them to layers.
| Parameter | Detail |
|---|---|
| AE version | After Effects 2025 — required. Expressions and effect parameters are version-specific. |
| Plugins required | Displacer Pro (Jixipix) — must be licensed and installed on the render node. Renders without it will silently omit the depth displacement pass. |
| Output codec | H.264 MP4 via Adobe Media Encoder render queue. Lossless intermediate is not used due to storage constraints. |
| Asset resolution | All templates include a 9:16 (1080×1920) output. Some recipes additionally offer a 4:5 (1080×1350) output. Some recipes additionally offer a 1:1 square output. The available formats per recipe are defined at the template level. |
The setText actions are pre-render actions — they execute before the AE render queue is opened. This is critical: AE evaluates expressions at render time against the layer state in the project file. If text layer values are written after the render begins, expressions have already been evaluated and the variable switch has no effect. All variable injection must complete in the pre-render phase.
The label asset replacement via layerName matching also occurs in the pre-render phase. NexRender locates the layer by name, downloads the asset from the specified URL, and replaces the source footage reference before AE opens the composition.
The footage was shot with vessel placement and lighting engineered for a subsequent depth-scanning pass. The depth pipeline produces a per-frame displacement map that allows an incoming label asset to be composited with accurate perspective foreshortening, surface curvature, and lighting response — without any manual tracking or matchmoving.
| Stage | Tool | Output |
|---|---|---|
| Depth prediction | Depth Prediction Transformer (DPT) — monocular depth estimation from RGB footage | Per-frame 16-bit depth map — brighter values nearer to camera |
| Depth refinement | Depth Scanner Plugin — analyses surface reflections on vessel to sharpen depth discontinuities at label zone boundary | Refined EXR sequence — vessel surface isolated from background |
| Label displacement | Displacer Pro — applies depth map as a displacement field to the MILK_LABEL layer | Label warped to follow vessel surface curvature per frame |
| Label alignment | AI alignment algorithm (proprietary) — positions label within the designated safe zone using depth discontinuity as the boundary reference | Label locked to vessel surface across all frames |
Each vessel precomp defines a label safe zone — a rectangular region on the vessel surface within which any processor's label will be legible and correctly composited regardless of label artwork dimensions. The safe zone was defined during the shoot by marking the vessel with reference tape and is encoded in the vessel null's transform values in the template.
The MILK_LABEL layer is scaled to fill the safe zone by default. Labels with non-standard aspect ratios are letterboxed within the safe zone; the letterbox background matches the vessel colour inferred from the cap colour variable.
The depth map drives a secondary luminosity pass on the MILK_LABEL layer. The same practical light used on the original shoot is simulated as a directional gradient, derived from the depth map's surface normal approximation. This gives the label the appearance of being lit by the same source as the surrounding footage rather than pasted flat over it.
The lighting simulation is an approximation. Labels with strong internal contrast — e.g. a bright white panel on a dark background — may show visible seaming at the label boundary under certain lighting conditions. The safe zone was positioned during the shoot to keep the vessel in the most favourable lighting angle for all cap colour variants.
The 12,460 figure is the total number of distinct renders the system can produce across all recipes, vessel configurations, milk varieties, cap colours, and output formats. It is not a count of renders produced — it is the scope of the system. Each combination is a valid, distinct After Effects render with a unique precomp configuration, label placement, and expression state. All recipes produce a 9:16 output; some also produce 4:5 and 1:1 outputs.
Not all combinations are available for all recipes. A recipe that does not use chocolate milk does not expose the chocolate variety option. The totals below reflect the maximum available per-variable count; actual per-recipe combination counts are lower and vary by recipe.
| Variable | Count | Notes |
|---|---|---|
| Recipes (templates) | 28 | Each recipe is a discrete AE project file with unique footage |
| Vessel types | 3 | Jug, carton, bottle — each with independent depth scan and label placement |
| Carton sizes | 4 | Half-pint, pint, quart, half-gallon — size-specific precomps for non-standard formats |
| Milk varieties | 6 | Whole, strawberry, chocolate, skim, 2%, lactose-free — recipe availability varies |
| Cap colours | 10 | Per vessel type; not all colours available for all vessels |
| Output formats | 2 | 9:16 (all recipes) + 4:5 (select recipes) + 1:1 (select recipes) — format availability is per-recipe, not universal |
| Total combinations | 12,460 | 28 × 3 × 4 × 6 × 10 × 2, adjusted for per-recipe availability constraints |
The complexity implied by this number lives entirely in the template build. Every cap colour that needed to work required a precomp layer, a colour-matched asset, and an expression branch. Every carton size that differed from the default required a size-specific composition with its own depth-adjusted label transform and a corresponding safe zone calibration. Every milk variety required a footage variant — white milk and chocolate milk have visibly different liquid colour — with a separate depth-composited label zone.
At render time, NexRender writes four keyword strings and replaces one layer. The 12,460 combinations are resolved before the render job is ever queued.
The following failure modes were identified during alpha and beta testing. Most are silent — NexRender does not surface AE expression errors in its job logs, and a render that completes with the wrong variable state is indistinguishable from a correct render at the API level.
| Failure | Cause | Symptom | Resolution |
|---|---|---|---|
| Wrong precomp visible | API passes a lowercase value where the expression expects uppercase, or vice versa — e.g. chocolate instead of CHOCOLATE |
Render completes. Output shows default (first) precomp regardless of user selection. | Schema enforcement at API validation layer. All keyword values uppercased before manifest construction. |
| Label not replaced | MILK_LABEL layer name has been edited, or layer was accidentally renamed during template maintenance |
Render completes. Output shows blank vessel surface — no label visible. | Template naming lock convention: reserved layer names documented and protected via AE script that warns on save if reserved names are absent. |
| Composition not found | MILK_EXPORT composition name altered |
NexRender job fails with a composition-not-found error. No render produced. | Same naming lock convention. This failure is at least visible in the job log. |
| Decompression failure | Asset file name exceeds ~20 characters or contains special characters | NexRender fails to unpack the project bundle. Job fails before render begins. | Asset naming convention enforced at template authoring time. All names reviewed against convention before template is committed to S3. |
| Depth displacement missing | Displacer Pro not installed or not licensed on render node | Render completes. Label appears flat on vessel — no surface curvature or foreshortening. Often not immediately obvious. | Plugin license and installation verified on render node environment. Visual QA checklist includes depth displacement verification pass. |
| Expression evaluates to 0 on all precomps | Text layer contains trailing whitespace from API serialisation | All variety precomps hidden. Render completes with transparent vessel area. | API trims all keyword values before manifest construction. Schema defines no leading or trailing whitespace as valid. |
| Label scaled incorrectly | Uploaded label asset dimensions outside accepted range (<500×500 px) | Label visible but undersized relative to safe zone, or pixelated at render resolution. | Front-end validation enforces minimum upload dimensions before job submission. API rejects out-of-spec assets before manifest construction. |
Templates built in After Effects 2025 use expression engine features and effect parameter names that differ from AE 2023 and earlier. Running a template in an older AE version on a misconfigured render node will cause expression errors that are not surfaced in the NexRender log. The render may complete with all precomps defaulting to 0 opacity. The AE version on the render node is pinned and verified as part of the environment setup.