# La emulsión física de película (PELÍCULA)

> El revelado físico de Tórculo: stocks y copias, el laboratorio, el navegador y Resolve, todos desde la misma ficha.

URL: https://torculo.joseluissaorin.com/referencia/emulsion · Revisado: 2026-10-16 · English: https://torculo.joseluissaorin.com/en/reference.md

Fuente: emulsion/README.md (generada al construir la web).


El modelo físico de la película de Tórculo: la luz de la escena expone las tres capas de
un negativo según sus sensibilidades espectrales, las capas forman tinte según sus curvas
características (con la interimagen entre ellas), el negativo se positiva sobre una copia
(o se escanea, o un inversible se proyecta), la copia se proyecta y se ve. El grano son
nubes de tinte en densidad, por capa; la halación es la luz que rebota en la base y vuelve
a exponer la capa roja. Los datos de cada stock salen de sus hojas técnicas públicas,
digitalizadas con su página y su gráfica (`canon/peliculas/`).

La **gelatina Saorín** (nuestra .cube) sigue siendo la llave de la casa: con
`gelatina Saorín` la película hace su trabajo (color de capas y tintes, latitud, grano,
halación) y su escala de grises vuelve a la escala de vídeo sobre la que se hizo la
gelatina, que pone el contraste y el color al final. Lo neutro de la película entra neutro
en la gelatina: una carta de grises revelada con película y gelatina da exactamente lo que
daba la gelatina sola; lo que cambia es todo lo demás. `gelatina Saorín delante` la pone
delante del objetivo, como un filtro de gelatina.

## Dónde se usa

| Dónde | Cómo |
|---|---|
| Pliego `.mesa` | `PELÍCULA Vision3 500T · copia 2383 · 35 mm · gelatina Saorín` (preámbulo) |
| Metraje | `REVELADO de la casa · desde s-log3` y, si se quiere película, la línea `PELÍCULA …` |
| Python (Tórculo) | `m.config.post = [m.Papel(), m.Pelicula("vision3-500t", copia="2383", formato="16")]` |
| Laboratorio | `python3 -m torculo_emulsion revela vision3-500t -e rodaje.mov -s copia.mov --entrada auto` |
| Navegador | `python3 -m torculo_emulsion web` → http://localhost:8765 (WebGPU; el vídeo no sale del ordenador) |
| Resolve | `python3 -m torculo_emulsion cube …` (LUT 65³ de color) y `… dctl …` (color y grano) |

Todo lee la misma **ficha** (`torculo_emulsion/ficha.py`): el WGSL entero
(`materias/shaders/emulsion.wgsl` y `emulsion_entrada.wgsl`), el grafo de pasadas y los
números del stock. El render de Tórculo (`grafo.rs` del fork), `materia revela` (crate
`materias`, `src/grafo.rs`) y la página (`web/grafo.js`) son tres anfitriones del mismo
grafo; ninguno sabe nada de películas.

## Órdenes

```sh
cd ~/Developer/torculo/emulsion
python3 -m torculo_emulsion lista                       # stocks, copias y looks
python3 -m torculo_emulsion ficha portra-400 -o p.json  # la ficha
python3 -m torculo_emulsion cube vision3-500t --copia 2383 --entrada logc3 -o 5219.cube
python3 -m torculo_emulsion dctl vision3-500t --gelatina Saorín --entrada s-log3 -o 5219.dctl
~/Developer/torculo/tools/pesado python3 -m torculo_emulsion revela vision3-500t \
    --look cine-de-noche -e rodaje.mov -s revelado.mov --codec prores   # --entrada auto lee los metadatos
python3 -m torculo_emulsion web
```

Ajustes (los de Osmo y los físicos): `--exposicion` (pasos), `--luz` (K de la luz de la
escena; por defecto la del equilibrio del stock), `--temperatura` y `--tinte` (puntos de
positivadora), `--contraste` (revelado del negativo), `--saturacion` (interimagen),
`--lift` (pre-velado de la copia), `--gamma` (revelado de la copia), `--brillo` (puntos),
`--grano`, `--tamano-grano`, `--halacion`, `--difusion`, `--bleach 0..1`, `--cruzado`,
`--formato 8|super8|16|super16|35|65|135|120|4x5`, `--copia 2383|2393|escaneo|directo`,
`--look NOMBRE`.

## Entradas de cámara

`torculo_emulsion/entradas.py`: ARRI LogC3 (por EI) y LogC4, S-Log3 y S-Log2, Canon Log,
Log 2 y Log 3, RED Log3G10, Blackmagic Film Gen 5, V-Log, F-Log y F-Log2, N-Log, L-Log,
D-Log, Apple Log, I-Log, ACEScct y ACEScc, DaVinci Intermediate, Rec.709, sRGB y lineal,
con sus gamas a Rec.709 lineal. Fórmulas de los libros blancos de cada fabricante, probadas
contra sus valores publicados (`pruebas/test_entradas.py`). `entradas.detecta(ruta)` lee
los metadatos (XML de Sony, etiquetas del fabricante, la característica de transferencia).
Las curvas esperan el código de 10 bits / 1023 tal como lo graba la cámara: `materia
revela --codigos 1` lee el vídeo sin estirar el rango de vídeo (salvo L-Log).

## Pruebas y medidas

- `pruebas/test_modelo.py`: las curvas que reproduce el modelo frente a las de cada hoja,
  en los nudos de su tabla: 0,02 D como máximo en las hojas vectoriales y 0,03 D en las
  raster (el trazo digitalizado es de ±0,02 D). La carta gris sale neutra en la copia; la
  500T de día sin filtro sale azul; el bleach bypass hunde los negros y sube el contraste
  con el gris en su sitio.
- `pruebas/gpu_vs_ref.py` (y la prueba con `TORCULO_PRUEBAS_GPU=1`): la GPU frente a la
  referencia de Python, sin grano ni halación: menos de 1 nivel de 8 bits de error máximo
  sin gelatina; con gelatina, p99,9 por debajo de 1 nivel (máximo 6, en unos pocos
  píxeles de la sombra más honda: la .cube va en medios flotantes en la GPU).
- Rendimiento (M4 Max, `materia revela --mide`, 4K, cadena entera con grano y halación):
  unos 17 ms por fotograma en todos los formatos (57 a 60 fps). Sin grano, 8 ms. En el
  motor de Tórculo, 240 fotogramas 4K con película, gelatina y ProRes: 5,5 s (44 fps de
  punta a punta, codificación incluida).
- `pruebas/hoja.py`: las hojas comparativas en `~/Movies/emulsion-demo/`.

## Lo que es modelo y no dato

Está escrito en cada sitio; en resumen: los densitómetros Status A y M son gaussianas
con sus picos publicados; las luces (escena, positivadora, proyector) son cuerpos negros;
la máscara de los negativos de color es una máscara ideal parcial (0,8); la interimagen
es una matriz con 0,12 fuera de la diagonal; la halación y la irradiación son parámetros
del modelo (con antihalo, el rebote es pequeño; sin él, como en CineStill, grande); el
proceso cruzado no tiene curva publicada y es una aproximación; un inversible se proyecta
con un filtro de corrección que deja la carta gris neutra. Los tintes de las hojas que no
los publican se toman prestados (escrito en `prestado`). La granularidad sale de las
curvas RMS de la hoja (Kodak de cine), de su RMS difusa o de su Print Grain Index
(RMS ≈ 0,3·PGI, aproximación).

## Licencia y marcas

Código MIT/Apache, como Tórculo. No se ha copiado código ni datos de agx-emulsion
(GPL-3) ni de otras simulaciones: los datos son digitalizaciones propias de las hojas
técnicas públicas (los PDF no se incluyen) y las fórmulas, de los documentos de cada
fabricante.

Kodak, Vision3, Vision2, EXR, Eastman, Portra, Ektar, Gold, UltraMax, Ektachrome, Tri-X,
T-MAX y Double-X son marcas de Eastman Kodak Company o de Kodak Alaris; Fujifilm, Eterna,
Reala, Velvia, Provia, Superia, Fujicolor, Neopan y Acros, de FUJIFILM Corporation;
Ilford, HP5, FP4, Delta, Pan F y XP2, de HARMAN technology; CineStill, de CineStill Film.
Tórculo no tiene relación con ninguna de ellas ni cuenta con su respaldo: sus nombres se
usan solo para decir qué hoja técnica se ha emulado.
