Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/alpha-compositing-foundation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@basementstudio/shader-lab": patch
---

Preserve alpha when copying external input textures and applying effect passes. Source layers use straight-alpha source-over blending; effect passes preserve input coverage and retain their existing alpha-as-strength behavior. Opaque compositions and legacy mask semantics are unchanged.
5 changes: 5 additions & 0 deletions .changeset/displaced-rings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@basementstudio/shader-lab": minor
---

Add Displaced Rings with rings/half-discs, progressive transforms, seeded offsets, and Distort/Cutout output. Support transformed coverage in the editor and runtime so grouped photographic cutouts reveal external layers, with opacity interpolating color and alpha together.
5 changes: 5 additions & 0 deletions .changeset/editor-groups.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@basementstudio/shader-lab": minor
---

Support isolated groups in exported ShaderLabConfig layer lists using group layers and parentId references. Evaluate group visibility and opacity before building the render tree, preserving child effect scope in composition and headless rendering. Existing flat configs remain compatible.
5 changes: 5 additions & 0 deletions .changeset/isolated-group-rendering.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@basementstudio/shader-lab": patch
---

Add isolated, nested group rendering to the internal renderer frame contract. Group children render against transparent targets before the combined result is blended into the parent. Existing flat public shader configs retain their behavior; editor grouping controls and persisted groups follow separately.
5 changes: 5 additions & 0 deletions .changeset/transparent-media-bounds.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@basementstudio/shader-lab": patch
---

Support transparent borders for contained image and video layers with `params.transparentBounds: true`. Existing runtime configs without the setting retain black borders.
4 changes: 4 additions & 0 deletions .changeset/transparent-text-defaults.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
---

New editor text uses normal composition over a transparent background. Clarify the background opacity control and preserve the solid fallback for saved text that omits the setting. This editor-only change does not require a package release.
22 changes: 22 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
branches:
- main
- git-chad/shader-lab-v3-plan
- git-chad/v3-*
push:
branches:
- main
Expand Down Expand Up @@ -50,3 +51,24 @@ jobs:
- name: Ensure changeset exists for PR changes
if: github.event_name == 'pull_request'
run: bunx changeset status --since=origin/${{ github.base_ref }}

composition:
# Linux Chromium/SwiftShader currently drops its GPU instance during these
# texture-backed shader compilations. Keep the full GPU checks on macOS.
runs-on: macos-14
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- run: bun install --frozen-lockfile
- run: bunx playwright install chromium
- run: bun run test:composition
- name: Upload rendered compositions
if: always()
uses: actions/upload-artifact@v4
with:
name: composition-actuals
path: .context/composition-test/
if-no-files-found: ignore
48 changes: 35 additions & 13 deletions V3-ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,25 @@ El orden es una **propuesta de ejecución**; las prioridades de producto son rev

## Flujo de integración y entrega

Todo el trabajo de V3 se entrega mediante PRs pequeños dirigidos a una rama de integración de V3. Un PR principal reúne esa rama y tiene como destino `main`.
Todo el trabajo de V3 se entrega mediante PRs pequeños apilados. Cada nuevo PR parte de la rama del PR anterior y la usa como base. El primer PR de la pila apunta a la rama de integración de V3; un PR principal reúne esa rama y tiene como destino `main`.

**PRs pequeños → rama de integración de V3 → PR principal → `main`.**
**PR nuevo → PR anterior → rama de integración de V3 → PR principal → `main`.**

Los PRs pequeños pueden integrarse progresivamente en la rama de V3. Ningún cambio de V3 se integra en `main` hasta completar el alcance obligatorio del plan y su validación global de la fase 7. La fase 8 sigue siendo opcional y no bloquea esa entrega.

La rama de integración es `git-chad/shader-lab-v3-plan`. Todos los PRs pequeños de V3 deben usarla como base; únicamente el PR principal apunta a `main` y permanece en borrador hasta completar la validación obligatoria.
La rama de integración es `git-chad/shader-lab-v3-plan`. La pila comienza con [#151](https://github.com/basementstudio/shader-lab/pull/151), en `git-chad/v3-composition-alpha`, seguido de [#152](https://github.com/basementstudio/shader-lab/pull/152), en `git-chad/v3-transparent-media-bounds`. La base compartida de composición alfa continúa desde esta última rama. Al integrar PRs, actualizar las bases de los descendientes para conservar la pila; únicamente el PR principal apunta a `main` y permanece en borrador hasta completar la validación obligatoria.

PR principal: [#150 — V3: designer-focused composition and experimental graphics](https://github.com/basementstudio/shader-lab/pull/150).

Primer paso de la fase 1: [baselines de composición y mapa del canal alfa](tests/composition/README.md). Esta cobertura inicial no cierra la fase ni sustituye la validación visual con las catorce referencias elegidas.

Avance de 1.3: grupos aislados con hasta ocho niveles, controles del editor, reordenamiento de subárboles, plegado, visibilidad, opacidad, duplicación, deshacer, persistencia v7 y exportación de configuración. Las pruebas cubren estado, hidratación real y píxeles guardados/reabiertos. El usuario confirmó la prueba de aislamiento de foto + halftone, opacidad y plegado; la [lista manual ampliada](tests/composition/GROUPS-MANUAL-QA.md) sigue disponible para la validación global.

**Prioridades revisadas con el usuario (17 de septiembre de 2026):** texto transparente por defecto (2.1) implementado en #156 y confirmado por el usuario. Siguiente entrega: prototipo de los anillos desplazados ya previstos en 3.2–3.3; no es una familia adicional. Posponer las máscaras básicas de círculo/rectángulo y su interfaz genérica: no bloquean texto ni la exploración de anillos; revisar cuándo retomarlas al cerrar el alcance de V3. Desarrollar modos de máscara adaptados al lenguaje visual de los efectos seleccionados. Registrar con prioridad baja una revisión de calidad de Blob Tracking y sus posibilidades como máscara (6.3).

## Fase 1 — Resolver la base de composición y proteger proyectos existentes

**Prioridad máxima:** transparencia, grupos y máscaras sostienen la composición. La preparación inicial debe ser breve y servir a la ejecución.
**Prioridad máxima:** transparencia y grupos sostienen la composición. La cobertura alfa necesaria para los modos creativos de máscara se incorpora con los efectos que la usan; la interfaz de máscaras básicas queda aplazada. La preparación inicial debe ser breve y servir a la ejecución.

### 1.1 Preparar pruebas y referencias mínimas

Expand All @@ -30,15 +38,17 @@ Permitir regiones vacías junto a contenido totalmente opaco. Bajar la opacidad

### 1.3 Introducir grupos reales con alcance propio

Los grupos y sus máscaras son **requisitos confirmados**, pedidos explícitamente por un colega diseñador. Se propone composición aislada por defecto: procesar los contenidos pertinentes del grupo y luego integrarlo al conjunto. Sus efectos no deben afectar capas externas. Agregar carpetas sobre una cadena global de filtros no resuelve el requisito.
Los grupos con alcance propio son **requisitos confirmados**, pedidos explícitamente por un colega diseñador. Las máscaras de grupo también se solicitaron, pero el usuario decidió posponer la interfaz de máscaras básicas y priorizar modos creativos ligados a efectos (1.4). Se propone composición aislada por defecto: procesar los contenidos pertinentes del grupo y luego integrarlo al conjunto. Sus efectos no deben afectar capas externas. Agregar carpetas sobre una cadena global de filtros no resuelve el requisito.

Incluir organización, reordenamiento, plegado, visibilidad, opacidad, deshacer y guardado. Definir la profundidad de anidamiento durante la implementación, sin prometer reproducir todo Photoshop.

### 1.4 Resolver máscaras de capa y grupo
### 1.4 Orientar las máscaras hacia modos creativos por efecto

**Decisión de producto:** posponer las máscaras básicas de círculo/rectángulo adjuntas a capas o grupos. Priorizar modos adaptados a cada efecto: por ejemplo, anillos o semidiscos desplazados que revelan fotografía y dejan huecos, o regiones detectadas por Blob Tracking que sirven de máscara. Los anillos se exploran en 3.2–3.3; Blob Tracking tiene prioridad baja en 6.3. No asumir que todas las capas necesitan el mismo interruptor genérico de máscara.

Darles asignación clara, inversión, desactivación y bordes consistentes. La máscara de grupo recorta el resultado combinado y revela capas inferiores, sin rellenar de negro ni producir halos negros en bordes suaves.
Al incorporar cada modo, definir qué contenido recorta, cómo se asigna y cómo se invierte/desactiva. La cobertura debe revelar capas inferiores, sin rellenos negros ni halos oscuros en bordes suaves. Mantener la composición aislada del grupo y la apariencia de los modos de máscara guardados. La transformación de la imagen y el recorte de su cobertura son comportamientos distintos que deben quedar claros en los controles.

Usar esta pila de prueba, de arriba hacia abajo:
Conservar esta pila como referencia de alcance para cuando se retomen las máscaras de grupo; no es un requisito del siguiente PR:

```text
Texto — fuera del grupo
Expand All @@ -48,13 +58,13 @@ Grupo «Retrato» — máscara circular
Fondo — fuera del grupo
```

Halftone modifica solo la fotografía; la máscara circular recorta el grupo; texto y fondo quedan fuera de su alcance. Las máscaras de recorte que usan la silueta de otra capa son una extensión sugerida, con alcance inicial pendiente.
Halftone modifica solo la fotografía; la máscara circular recorta el grupo; texto y fondo quedan fuera de su alcance. La asignación arbitraria de la silueta de otra capa sigue como extensión sugerida, con alcance pendiente; no debe confundirse con un modo de máscara propio de un efecto.

### 1.5 Anticipar las decisiones de viabilidad 3D

Probar brevemente formatos, materiales, animaciones, conservación de recursos y geometría SVG. Registrar decisiones abiertas para las fases 4 y 5 sin demorar la composición. Una entrada de catálogo o tipo de capa no demuestra soporte completo de modelos.

**Cierre:** huecos transparentes y contenido opaco conviven; máscaras y efectos mantienen su alcance al reordenar, deshacer, guardar, reabrir y exportar. Las escenas anteriores conservan su apariencia y los bordes suaves quedan limpios.
**Cierre de la base:** huecos transparentes y contenido opaco conviven; grupos y efectos mantienen su alcance al reordenar, deshacer, guardar, reabrir y exportar. Las escenas anteriores conservan su apariencia y los bordes suaves quedan limpios. Cada modo creativo de máscara incorporado debe superar esas mismas pruebas en su fase; la interfaz básica aplazada no bloquea el cierre de esta base.

## Fase 2 — Facilitar las piezas tipográficas y pulir las capas actuales

Expand All @@ -64,7 +74,7 @@ Probar brevemente formatos, materiales, animaciones, conservación de recursos y

El usuario reporta texto blanco sobre negro y la necesidad de recurrir a máscaras, Screen o cambiar manualmente el fondo. El requisito es insertar texto visible, con contenido opaco y color editable sobre fondo transparente, sin esos rodeos. Mantener el fondo sólido como una opción deliberada y conservar el uso de texto como máscara cuando se elija expresamente.

La lectura de este checkout confirma que `layers.ts` crea texto en modo máscara y `layer-registry.ts` define fondo negro con alfa 1. `text-pass.ts` ya distingue el alfa del fondo y dibuja el texto opaco; admite color editable y posición mediante anclaje y desplazamiento. Esto orienta la revisión de valores iniciales y composición; no constituye una reproducción visual del problema.
La inspección inicial confirmó que `layers.ts` creaba texto en modo máscara y `layer-registry.ts` definía fondo negro con alfa 1. `text-pass.ts` ya distingue el alfa del fondo y dibuja el texto opaco; admite color editable y posición mediante anclaje y desplazamiento. La corrección debe cambiar los valores de capas nuevas y conservar el fondo sólido de archivos anteriores que omitan ese parámetro.

### 2.2 Explorar selección y arrastre directo en el lienzo

Expand Down Expand Up @@ -102,7 +112,7 @@ La base principal son las catorce imágenes elegidas, más Lovedance —forma ro

| Familia candidata | Resultado y referencias |
| --- | --- |
| Anillos desplazados y rotados | Bandas circulares transformables; afiche fotográfico azul y negro con círculos concéntricos desalineados. |
| Anillos desplazados y rotados | Bandas circulares transformables; afiche fotográfico azul y negro con círculos concéntricos desalineados (`16-anillos-desfasados-azules.png`). Incluir en la exploración semidiscos de diferentes tamaños y desplazamientos, con huecos transparentes como modo propio del efecto. |
| Recortes por celdas o bloques | Revelar bloques con detalle fotográfico interior y contornos opcionales. El puente presenta siluetas escalonadas, no grandes píxeles planos; el afiche blanco combina regiones de color, bordes celulares y puntos finos. |
| Revelado fotográfico alterado | Inversiones tonales parciales, expansión de luces y sombras, neblina y erosión; James Blake verde, retrato azul difuso con anotaciones y retrato gris de apariencia solarizada. |

Expand All @@ -114,6 +124,12 @@ Exigir el caso de **48 anillos**, aunque la referencia muestre seis u ocho. Expl

Permitir destruir completamente el reconocimiento de la imagen. Preparar combinaciones editables, como anillos + dos tintas + erosión, usando componentes disponibles y ampliándolas al incorporar familias posteriores.

Separar la transformación de la fotografía dentro de cada banda del modo que recorta su cobertura. Probar anillos completos y semidiscos, con desplazamiento y rotación, y definir controles útiles para revelar/ocultar regiones. Los huecos deben mostrar el contenido inferior y los efectos deben respetar los límites del grupo. Este trabajo amplía la exploración de anillos existente; no agrega otra familia ni exige implementar primero máscaras geométricas genéricas.

**Primer prototipo implementado, pendiente de validación visual del usuario:** Displaced Rings admite 1–128 bandas (48 comprobadas), anillos/semidiscos, centro, radio, distribución, desplazamiento alternado/progresivo/aleatorio con semilla, rotación global y por banda, escala progresiva, separación y bordes suaves. Output distingue Distort y Cutout; dentro de un grupo, Cutout revela las capas externas por los huecos. Editor y runtime comparten el comportamiento, con pruebas de píxeles, hidratación real, deshacer, guardado/reapertura y PNG. El catálogo incorpora una vista previa fotográfica y muestra el efecto primero. Ver [alcance y prueba manual](tests/composition/DISPLACED-RINGS-MANUAL-QA.md).

Esto no cierra la fase 3: quedan la curaduría visual con las referencias completas, combinaciones con otros efectos, rendimiento con fotografías/video a resoluciones representativas y la selección de las otras familias. El prototipo usa transformaciones progresivas; no incluye controles individuales por anillo ni inversión de cobertura.

### 3.4 Reorganizar el catálogo junto con cada incorporación

Dar protagonismo a los nuevos efectos y menor prominencia a los actuales, manteniéndolos accesibles. «Legacy» es una denominación informal, no una deprecación. El nombre público está abierto; **Essentials** fue una sugerencia no confirmada. Acompañar cada alta posterior con esta organización.
Expand Down Expand Up @@ -170,7 +186,13 @@ Derivar geometría de los contornos y ofrecer profundidad de extrusión, bisel,

Elegir según resultados visuales y viabilidad, aplicar los criterios de controles y valores iniciales, actualizar el catálogo en cada incorporación y ampliar las combinaciones editables.

**Cierre:** las familias seleccionadas pasan sus pruebas visuales, de libertad y composición; las candidatas pospuestas quedan identificadas sin presentarlas como entregas prometidas.
### 6.3 Revisar Blob Tracking y sus modos de máscara — prioridad baja

Pedido del usuario: dedicar una revisión de calidad a Blob Tracking porque tiene potencial visual desaprovechado. Comparar sus resultados actuales sobre fotografía y video; revisar detección, estabilidad temporal, contornos, valores iniciales y claridad de controles antes de elegir cambios. No asumir que necesita una reescritura completa.

Explorar modos de máscara adaptados a sus regiones detectadas y al movimiento, distinguiendo visualización de la máscara, aplicación de un efecto dentro de las regiones y recorte real de la fotografía. Validar inversión/desactivación, bordes, cobertura alfa, grupos, guardado, reapertura y exportación. Conservar los resultados de escenas anteriores. El alcance concreto se decide tras esa revisión; esta tarea no bloquea texto ni la exploración inicial de anillos.

**Cierre:** las familias seleccionadas pasan sus pruebas visuales, de libertad y composición; las candidatas pospuestas quedan identificadas sin presentarlas como entregas prometidas. Registrar el resultado de la revisión de Blob Tracking y qué mejoras o modos se integran o se aplazan.

## Fase 7 — Verificar el conjunto y cerrar V3

Expand Down
9 changes: 7 additions & 2 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"version-canary": "changeset version --snapshot canary",
"version-packages": "changeset version",
"start": "next start",
"test:composition": "bun tests/composition/run.mjs",
"typecheck": "tsgo --noEmit",
"typecheck:runtime": "bun run --cwd packages/shader-lab-react typecheck",
"typecheck:compare": "bun run typecheck:tsc && bun run typecheck",
Expand Down Expand Up @@ -84,6 +85,7 @@
"babel-plugin-react-compiler": "1.0.0",
"cross-env": "^10.1.0",
"drizzle-kit": "^0.31.10",
"playwright": "^1.63.0",
"postcss-preset-env": "^10.6.1",
"tailwindcss": "^4.1.18",
"typescript": "^5.9.3"
Expand Down
Loading
Loading