Bomen laten groeien

Ik heb onlangs geëxperimenteerd met procedurele boomgroei. De methode die ik gebruik is gebaseerd op Self-organizing tree models for image synthesis door Palubicki et al. (SIGGRAPH 2009).

Het idee is prachtig simpel: knoppen concurreren om licht, de boom verdeelt een groeiresource over hen, en de succesvolle knoppen produceren nieuwe scheuten. Deze scheuten veranderen op hun beurt het beschikbare licht voor de volgende ronde. De vorm van de kruin ontstaat uit deze feedbackloop.

Hieronder volgt een beknopte analyse, inclusief visualisaties van mijn implementatie.

Eén seizoen per keer

Het basisbouwsteen is een metameer: een internodium (een kort stukje stam), een blad en de knoppen op de bovenste knoop. Een terminale knop zet een as voort, terwijl axillaire knoppen zijtakken kunnen starten.

Elke iteratie vertegenwoordigt één groeiseizoen:

  1. Meet het beschikbare licht voor elke knop.
  2. Sommeer dit licht van de toppen naar de wortel.
  3. Verdeel een proportionele groeiresource terug omhoog door de boom.
  4. Laat scheuten groeien uit de knoppen die voldoende resource ontvangen.
  5. Verwijder slecht verlichte takken en laat slapende knoppen verouderen.

(Afbeelding: Dezelfde zaadwaarde die groeit van seizoen 2 tot 30. De camera en schaal blijven constant.)

Waar is het licht?

Een manier om de beschikbaarheid van licht te benaderen is via een voxelgrid. Elke knop voegt schaduw toe aan een uitbreidende piramide van voxels eronder, waarbij de bijdrage afneemt naarmate de diepte toeneemt. Bijdragen van alle knoppen tellen op, waardoor het binnenste van de boom natuurlijk donkerder wordt naarmate de boom groeit.

Elke knop leest twee zaken uit dit grid: een waarde voor beschikbaar licht $Q$, en een richting $\mathbf{V}$ naar de minst beschaduwde naburige voxel binnen zijn perceptieconus.

(Afbeelding: Links: een verticale doorsnede door het schaduwgrid. Rechts: licht per knop. Cyaanblauwe knoppen zijn goed belicht. Oranje knoppen zijn beschaduwd.)

Het paper ondersteunt daarnaast space colonization: vul een envelop met markeerpunten, laat knoppen concurreren om nabijgelegen markers en verwijder markers zodra de groei hun ruimte inneemt. Hetzelfde groeimechanisme, maar een andere manier om te bepalen waar groei mogelijk is.

Wie mag er groeien?

Lichtwaarden worden eerst gesommeerd naar beneden via de vertakkingsstructuur. Bij de basis wordt de totale $Q{base}$ een groeiresource $v = \alpha Q{base}$. Deze resource reist terug omhoog en splitst bij elk vertakkingspunt.

(Afbeelding: Links: geaccumuleerd licht dat naar beneden stroomt. Rechts: resource die omhoog stroomt. Oranje stippen markeren knoppen die genoeg ontvangen om te groeien.)

In het uitgebreide Borchert-Honda model ontvangt de hoofdaansluiting:

$$vm = v \frac{\lambda Qm}{\lambda Qm + (1-\lambda)Ql}$$

De zijtak ontvangt de rest. Bij $\lambda = 0,5$ volgt de resource het licht. Hogere waarden bevoordelen de hoofdas. Lagere waarden bevoordelen de zijtakken.

Deze kleine afwijking heeft een verrassend groot effect:

(Afbeelding: Links: lambda=0,46, een uitgespreide kruin. Rechts: lambda=0,56, een dominante hoofdas.)

Een knop die minder dan één eenheid ontvangt, blijft latent. Anders produceert hij een scheut van $\lfloor v \rfloor$ metameren, onderworpen aan een geconfigureerde limiet. Nieuwe metameren krijgen hun eigen knoppen, en het proces herhaalt zich.

Welke richting?

Elk nieuw segment volgt een genormaliseerde gewogen som van zijn vorige richting, de lichtzoekende richting $\mathbf{V}$, een opwaarts of neerwaarts tropisme en een hoeveelheid ruis. Een horizontale component kan ervoor zorgen dat zijtakken zich verspreiden in platte lagen.

De plaatsing van knoppen rond de stam (phyllotaxis) biedt een andere belangrijke controle. Spiraalvormige arrangementen, tegenovergestelde paren en jaarlijkse kransen produceren zeer verschillende vertakkingspatronen. Het frame wordt via parallel transport langs de scheut geleid, zodat de rangschikking coherent blijft terwijl de tak buigt.

(Afbeelding: Zes phyllotaxis-patronen, gezien langs de as van de scheut. Nummers identificeren opeenvolgende knopen.)

Takken laten vallen en omtrek toevoegen

Met het schaduwmodel wordt een zijtak afgestoten wanneer het licht dat wordt verzameld door het onderliggende takkenstelsel, gedeeld door het aantal metameren, onder een drempelwaarde zakt. Jonge takken krijgen een gratieperiode. Anders zou de binnenkruin constant stervende twijgjes blijven accumuleren.

(Afbeelding: Dezelfde zaadwaarde, zonder afstoting (links) en met afstoting (rechts). Zelfreiniging verandert ook het beschikbare licht voor daaropvolgende groei.)

De dikte van de takken wordt daarna berekend met een pijpmodel:

$$r{parent}^{n} = \sumi r_i^{n}$$

Men begint met een vaste straal bij de toppen en accumuleert deze richting de wortel. Voor $n=2$ blijft het dwarsdoorsnede-oppervlak bij splitsingen behouden. Hogere exponenten zorgen voor slankere stammen. Afgestoten takken dragen nog steeds bij aan de omtrek onder hen; het verliezen van een tak zorgt er dus niet voor dat de stam krimpt.

Breedte en passieve doorbuiging (sag) worden berekend op basis van het gegroeide skelet en hebben geen invloed op de groei zelf.

Van takken naar gebladerte

Het skelet wordt een schors-mesh door buizen langs de assen te trekken. Voor het gebladerte gebruik ik twig spray cards: elke kaart toont een klein twijgje met enkele bladeren, gebruikmakend van varianten uit een procedureel getekende atlas.

(Afbeelding: De twijg-atlas en de kaarten die deze dragen. Elke kaart vervangt een hele cluster bladeren.)

Het blenden van de normalen van de kaarten richting een ellipsoïde rond de kruin helpt om het gebladerte als een volume te laten schaduwen. Lagere detailniveaus behouden minder en grotere kaarten en vereenvoudigen de schors. Op afstand nemen baked directional impostors het over.

Bonus: Bosrendering

De gegroeide boom kan ook worden gebakken in depth-field views voor bosrendering. De onderstaande afbeelding gebruikt vele instanties van één gebakken linde, met variatie in grootte. De representatie van het bos en de belichting verdienen overigens een apart bericht.

(Afbeelding: Eén gegroeide boom, geïnstantieerd als een bos met behulp van gebakken depth-field views.)