Last updated on

Ruisfuncties: Value Noise, Perlin Noise en Fractale Ruis

ENNLESPT-BR


Een random number generator geeft ongecorreleerde waarden op nabijgelegen punten. Een ruisfunctie geeft juist samenhangende waarden: verplaats de invoer een klein stukje en de uitvoer verandert met een kleine hoeveelheid in plaats van naar een volledig nieuw getal te springen. Die ene eigenschap maakt ruis bruikbaar in graphics, want een glad veld kun je lezen als hoogte, dichtheid of kleur zonder dat het scheurt of flikkert terwijl je het samplet.

Drie namen duiken bijna altijd op als dit onderwerp ter sprake komt: value noise, Perlin noise en fractale ruis. Value noise en Perlin noise zijn basisfuncties die van elkaar verschillen in wat ze vóór de interpolatie op een raster opslaan. Fractale ruis is een compositieregel die een van beide basisfuncties over meerdere schalen stapelt. Die rollen uit elkaar houden is het belangrijkste doel van deze pagina.

Je bouwt het beeld op met drie interactieve velden en koppelt het daarna aan de knoppen die je echt bedient: seed, frequentie en octaven. De diepere wiskunde en de toepassingen staan in de gelinkte artikelen.

Value Noise: Willekeurige Waarden op een Raster

Value noise is de eenvoudigste versie van het idee. Leg een raster over de ruimte en geef elke rasterhoek een willekeurig getal. Om de ruis tussen de hoeken te lezen, meng je de hoekgetallen op basis van hoe dicht het samplepunt bij elke hoek ligt. In één dimensie is die menging

v(x)=(1−t) a+t b,t=fade(x−⌊x⌋)v(x) = (1 - t),a + t,b, \qquad t = \mathrm{fade}(x - \lfloor x \rfloor)

waarbij aa en bb de willekeurige waarden op de twee dichtstbijzijnde hoeken zijn. De functie fade\mathrm{fade} verzacht het gewicht, zodat het veld glad aansluit waar cellen elkaar raken; met een gewone lineaire menging verandert de helling abrupt en zie je knikken langs de celgrenzen. In twee dimensies wordt dezelfde bewerking twee keer uitgevoerd: eerst links en rechts mengen, daarna die twee resultaten van boven naar beneden mengen.

Het praktische gevolg is dat geen enkele waarde op zichzelf willekeurig is. Elk sample is een gewogen gemiddelde van de omringende hoeken, waardoor het veld daartussen glad en voorspelbaar is.

Het veld begint met één octaaf en toont dus pure value noise. Sleep ergens op de kaart om de probe te verplaatsen: het gestreepte kruis volgt, en de oranje curve eronder tekent het veld langs de probepositie, met een stip die de waarde direct onder de probe markeert. Sleep aan de frequentieschuif en de bulten kruipen dichter bij elkaar, want een hogere frequentie propt meer rastercellen in hetzelfde beeld; sleep de andere kant op en het veld rekt uit tot brede, golvende vormen. Sleep aan de seedschuif en de bulten herschikken zich zonder dat hun onderlinge afstand verandert, omdat de seed de hoekgetallen herschrijft terwijl het raster blijft liggen. Het ronde profiel is het werk van de gladde fade; een knik in die curve zou een knik in het hele veld betekenen.

Value noise is makkelijk te beredeneren, en dat is tegelijk de beperking. De opgeslagen data zit op de hoeken, dus elke cel heeft zijn eigen lokale vorm, en het veld kan overkomen als ronde bulten die op een raster zijn gerangschikt. Voor zachte effecten is dat prima. Voor belichting, geometrie of alles wat van dichtbij wordt bekeken, kan het raster zichtbaar beginnen te worden.

Perlin Noise: Richtingen in Plaats van Waarden

Perlin noise houdt het raster en de gladde menging en verandert alleen de data op de hoeken. Een hoek bij value noise slaat een getal op; een hoek bij Perlin noise slaat een richting op. Om het veld te lezen meet je hoe sterk de richting van elke hoek overeenkomt met de offset van die hoek naar het samplepunt, via een inproduct:

ci=gi⋅(p−pi)c_i = \mathbf{g}_i \cdot (\mathbf{p} - \mathbf{p}_i)

Hier is gi\mathbf{g}_i de richting die op hoek ii is opgeslagen, en p−pi\mathbf{p} - \mathbf{p}_i de vector van die hoek naar het sample. Een hoek waarvan de richting naar het sample wijst, draagt positief bij; een hoek die ervan af wijst, draagt negatief bij. Als je die bijdragen met dezelfde fade-curve mengt, krijg je een glad veld waarvan de lokale vorm uit de omringende richtingen komt in plaats van uit opgeslagen hoogtes.

Daarom wordt Perlin noise ook wel gradient noise genoemd. De naam beschrijft de opgeslagen data, niet hoe het resultaat eruitziet. Ken Perlin introduceerde de functie in An Image Synthesizer en verfijnde haar later in Improving Noise, grotendeels om artefacten op de celgrenzen weg te nemen.

Beide demo’s starten met dezelfde frequentie, seed en octaven, dus het enige verschil is de opgeslagen hoekdata. Sleep de probe over de Perlin-kaart en vergelijk het profiel met dat van value noise: Perlin noise ruilt de ronde, celgecentreerde bulten in voor langgerekte ruggen en dalen die over celgrenzen heen lopen, waardoor het raster veel moeilijker te herkennen is. De frequentie bepaalt nog steeds de featuregrootte, de seed herschikt de features nog steeds zonder ze te verkleinen of te vergroten, en de octaafschuif voegt nog steeds detail bovenop toe.

Value Noise versus Perlin Noise

Beide functies zitten op hetzelfde raster, mengen met dezelfde fade-curve en reageren op dezelfde knoppen. Het verschil zit volledig in wat er vóór de menging gebeurt.

Value noise Perlin noise
Opgeslagen op elke hoek Eén willekeurig getal Eén richting (een gradient)
Wat een sample gebruikt De hoekwaarde zelf Inproduct van de gradient en de offset
Visueel karakter Ronde bulten uitgelijnd op cellen Stromende ruggen die cellen overschrijden
Goede standaard voor Zachte variatie op lage frequentie Velden die belichting of geometrie aansturen

Value noise is vaak het betere eerste veld voor zachte variatie, zoals wolkendichtheid of een brede terreinbasis, omdat het eenvoudig te implementeren en makkelijk te voorspellen is. Perlin noise is de betere standaard wanneer het veld belichting of geometrie aanstuurt, omdat het raster minder snel zichtbaar wordt. Geen van beide is een strikte verbetering van de andere; de juiste keuze hangt ervan af of je de eenvoudigst mogelijke menging wilt of een coherente lokale structuur.

Fractale Ruis: Detail Opbouwen met Octaven

Een enkel ruisveld heeft één featuregrootte. Echte oppervlakken hebben dat zelden. Een berg heeft tegelijk brede ruggen, kleinere geulen en fijn grind. Fractale ruis krijgt die bandbreedte door meerdere kopieën van een basisruis op te tellen, elk met een hogere frequentie en een lagere amplitude. Elke kopie is een octaaf:

F(p)=∑i=0N−1ai n(fip)F(p) = \sum_{i=0}^{N-1} a_i, n(f_i p)

Hier is nn de basisruis, die value noise of Perlin noise kan zijn, NN het aantal octaven, fif_i de frequentie van octaaf ii, en aia_i de amplitude daarvan. In de gangbare opzet wordt de frequentie van het ene naar het volgende octaaf met een constante factor vermenigvuldigd, en de amplitude met een constante factor kleiner dan één:

fi=f0λi,ai=a0gif_i = f_0 \lambda^i, \qquad a_i = a_0 g^i

De frequentiefactor λ\lambda heet lacunarity en de amplitudefactor gg heet gain, al tonen veel tools ze als naamloze schuiven. Het eerste octaaf draagt de brede vorm. Elk later octaaf scherpt die vorm op een kleinere schaal aan, en omdat de amplitude kleiner is, verfijnt het de vorm in plaats van hem te vervangen.

Het fractale veld begint met vijf octaven. Sleep de octaafschuif naar één en de fijne lagen vallen weg, waardoor één basisveld overblijft; schuif weer omhoog en de grote vormen blijven op hun plek terwijl er kleinere bulten bovenop verzamelen, en het profiel krijgt fijne wiebeltjes. Duw de octaven naar de bovenkant van het bereik en het profiel krijgt steeds fijnere textuur, al is elke toegevoegde laag half zo sterk als de vorige, zodat de brede vorm de controle houdt. De afweging is makkelijker te lezen in het profiel dan te beoordelen in de kleurenkaart.

Hoe Octaven Zich Opstapelen tot Detail

De octaafsom is makkelijker te lezen als de lagen apart zichtbaar zijn. De ladder hieronder zet één octaaf op elke rij, van de laagste frequentie onderaan tot de hoogste bovenaan, en tekent de gewogen som langs de onderste baan.

Sleep de probe naar links en rechts en de oranje lijn houdt in elke rij dezelfde horizontale positie, zodat je één locatie van grof naar fijn kunt lezen. De onderste rijen bewegen langzaam over de breedte en dragen de grote vorm. De bovenste rijen oscilleren meerdere keren en voegen de textuur toe. De donkere curve onderaan is de gewogen som, en dat is wat het uiteindelijke veld samplet. Sleep de amplitudekolom omhoog of omlaag om de gain te veranderen, de snelheid waarmee het gewicht van elk octaaf krimpt. Verhoog de gain en de fijne rijen gaan concurreren met de grove, waardoor de gecombineerde curve van gestructureerd naar schokkerig verandert; verlaag hem en de fijne rijen verdwijnen bijna volledig, met een schone maar vlakke vorm als resultaat. Klik op een rij om in te stellen hoeveel octaven bijdragen, waarbij de rij die je aanklikt en elke bredere rij eronder actief blijven. De frequentieverhouding tussen de rijen blijft vast op twee, dus elke rij bestrijkt twee keer zoveel detail als de rij eronder.

Wat het resultaat fractaal maakt, is het herschalen en herwegen over de rijen, dus de basisrij kan value noise of Perlin noise zijn en het recept blijft gelden. In die zin is fractale ruis een compositieregel en geen basisfunctie. De gelaagde structuur komt ook overeen met hoe natuurlijke oppervlakken er vaak uitzien, een idee dat voor terrein, wolken en muziek is uitgewerkt in Random Fractals: Self-Affinity in Noise, Music, Mountains, and Clouds.

Wat Seed, Frequentie en Octaven Aansturen

De drie knoppen in de demo’s veranderen allemaal het beeld, waardoor je ze makkelijk door elkaar haalt. Ze grijpen op verschillende delen van de pipeline aan.

Seed verandert de willekeurige getallen. Als een hoek wordt gevuld door een hashfunctie van zijn integer coördinaten en de seed, dan herschrijft een andere seed elke hoek terwijl het raster, de menging en de featuregrootte ongemoeid blijven. Gebruik het om een andere ordening te krijgen die nog steeds exact reproduceerbaar is, want dezelfde seed levert altijd hetzelfde veld op. Daarmee is seed een hulpmiddel voor reproduceerbaarheid en herordening, niet voor stijl.

Frequentie herschaalt de invoercoördinaten vóór het samplen, in het eenvoudigste geval n(fx,fy)n(fx, fy). Als ff stijgt, passen er meer rastercellen in dezelfde ruimte, dus worden features kleiner en het veld drukker. Verlaag je ff, dan rekt het veld uit tot bredere, rustigere vormen. Frequentie verplaatst het hele patroon naar een andere schaal; het voegt geen nieuw detail toe.

Octaven bepaalt hoeveel geschaalde kopieën worden opgeteld. Eén octaaf geeft één schaal, en elk toegevoegd octaaf draagt fijnere structuur bij met lagere sterkte. Octaven voegen detail toe bovenop de vorm die je al hebt, in plaats van die te herschalen.

Juist door de drie rollen gescheiden te houden, kun je een veld doelgericht afstemmen. Als een patroon een andere ordening nodig heeft, verander je de seed. Als het grotere of kleinere features nodig heeft, verander je de frequentie. Als het meer textuur nodig heeft zonder de algemene vorm te verliezen, voeg je octaven toe.

Waar Ruisfuncties Opduiken

Ruis is een signaalbron, en meestal voedt die iets anders. In terrein wordt een ruisveld dat op elk rasterpunt wordt gesamplet een heightmap, en een meshing-stap verandert die heightmap in grond. In wolken en rook stuurt het veld de dichtheid aan. In rendering verstoort ruis oppervlaktenormalen, kleuren en materiaaleigenschappen, zodat grote vlakke gebieden niet meer vlak ogen, en het kan geometrie verplaatsen om rotsen, schors en wateroppervlakken te bouwen.

Hetzelfde veld dient ook als masker. Een ruiswaarde op een drempel afkappen levert onregelmatige vlekken op, wat een snelle manier is om gras te strooien, een kustlijn te breken of een materiaal te variëren zonder elke grens met de hand te tekenen. Omdat het veld een functie is en geen opgeslagen afbeelding, blijft het masker scherp op elk zoomniveau.

De tabel hieronder koppelt veelvoorkomende doelen aan de knop die ze aanpakt en aan het artikel dat het spoor vervolgt.

Doel Knop waarnaar je grijpt Lees verder
De ordening veranderen zonder de featuregrootte te wijzigen Seed De demo’s hierboven
Features breder of smaller maken Frequentie De demo’s hierboven
Textuur toevoegen met behoud van de brede vorm Octaven De octaaf-ladder hierboven
Een ruishoogte omzetten in grond Frequentie plus een meshing-stap Heightmap to mesh
Een bestaande vorm vervormen met ruis Gesampled veld plus verplaatsing Signed distance fields
Ruis per pixel samplen tijdens rendering Veldkosten en aantal octaven Ray marching
Ruis op de GPU evalueren Shader-sampling en aantal octaven Vertex- en fragmentshaders

In veldgebaseerde workflows is het aantal octaven net zo belangrijk voor de kosten als voor het uiterlijk, want elk extra octaaf is weer een extra sampling-pass. Die kosten zijn de reden dat de meeste productievelden een klein aantal zorgvuldig gewogen octaven gebruiken, in plaats van lagen te stapelen tot de vorm verdwijnt in korreligheid.

Samenvatting

Value noise, Perlin noise en fractale ruis lossen verschillende problemen op. Value noise plaatst willekeurige getallen op een raster en mengt ze, wat de duidelijkste manier is om te zien waar de structuur vandaan komt. Perlin noise houdt het raster maar slaat op elke hoek een richting op, zodat het veld lokale oriëntatie krijgt en het raster niet meer zichtbaar is. Fractale ruis neemt een van beide en stapelt die over octaven, zodat één signaal brede vorm en fijn detail tegelijk draagt.

Die verschillen verklaren hoe de demo’s reageren. Frequentie verandert de schaal van het basisveld. Seed verandert de ordening en verder niets. Octaven voegen detail toe bovenop de vorm die je al hebt. Zodra de drie rollen gescheiden zijn, vallen de wiskunde en de visuals samen, en wordt het afstemmen van een ruisveld een bewuste keuze in plaats van een zoektocht.