Ruisfuncties: Value Noise, Perlin Noise en Fractale Ruis

EN NL


Ruisfuncties zetten ruwe willekeur om in structuur die je kunt afstemmen, reproduceren en stapelen. Daarom kom je ze overal tegen in procedurele graphics: terrein, wolken, water, vuur, maskers, oppervlaktestructuur en elk systeem dat variatie nodig heeft zonder duidelijke herhaling. Het doel is niet alleen dat de output natuurlijk oogt. Het doel is dat de functie een controleerbare relatie heeft tussen positie en waarde, zodat je schaal, ordening of detail kunt aanpassen zonder het hele effect opnieuw te ontwerpen.

Drie termen verschijnen meestal als eerste: value noise, Perlin noise en fractale ruis. Ze hangen samen, maar het zijn niet dezelfde dingen. Value noise interpoleert willekeurige scalaire waarden op een lattice. Perlin noise verandert de lattice-data naar gradients en interpoleert vervolgens de daaruit ontstane invloed. Fractale ruis is een compositieregel die meerdere octaven van een basisruis stapelt om detail over meerdere schalen te maken.

De eerste visual hieronder begint met het eenvoudigste van die drie ideeën: één basisruisveld en de manier waarop frequentie de zichtbare schaal verandert.

Value Noise Als Interpolatie

Value Noise Generator

Interactive map with seed, frequency, and octaves controls.

Value noise begint met een lattice en kent aan elk latticepunt één willekeurige scalair toe. In één dimensie ziet de eenvoudigste vorm er zo uit:

v(x)=(1t)a+tbv(x) = (1 - t)a + tb

met t=s(xi)t = s(x - i).

Hier zijn a en b de willekeurige waarden op de twee dichtstbijzijnde latticepunten, i is de integer celindex, en s(.) is een soepele fade-functie die een ruwe coördinaat omzet in een zachte interpolatiegewicht. In twee dimensies wordt dat bilineaire interpolatie over vier hoeken. Het samplepunt blendt eerst links en rechts, en daarna die tussenresultaten van boven naar beneden.

v(x,y)=lerp(lerp(v00,v10,u),lerp(v01,v11,u),w)v(x,y) = \mathrm{lerp}\big(\mathrm{lerp}(v_{00}, v_{10}, u), \mathrm{lerp}(v_{01}, v_{11}, u), w\big)

met u=s(xx0)u = s(x - x_0) en w=s(yy0)w = s(y - y_0). De waarde op het punt is dus niet willekeurig in de directe zin. Het is een gewogen combinatie van nabije latticewaarden.

Dat is de kernintuïtie om op te letten in de generator. Als de frequentie stijgt, gebeurt de interpolatie over een kleinere ruimtelijke afstand, waardoor dezelfde noise-functie kleinere en dichter op elkaar liggende heuvels en dalen laat zien. Als de seed verandert, blijft de interpolatieregel gelijk maar veranderen de hoekwaarden, dus de ordening verandert zonder dat de schaal van de kenmerken verandert. En als het aantal octaven stijgt, is de generator niet langer één geïnterpoleerd veld; het wordt een som van velden op verschillende schalen.

Het belangrijkste mathematische detail is dat de gladheid uit de interpolatiecurve komt, niet uit de willekeurige getallen zelf. Als de fade-curve lineair is, krijg je zichtbare knikken waar cellen samenkomen. Als de fade-curve soepel is, zijn de overgangen zachter en is het veld bruikbaarder voor grafisch werk. Daarom is value noise vaak de eerste noise-functie die mensen leren: de implementatie is direct genoeg om goed op de wiskunde te passen.

Value noise is nuttig, maar heeft een eigen karakter. De opgeslagen data zit op de hoeken, dus het raster kan nog steeds zichtbaar zijn als je het patroon nauwkeurig bekijkt of als het veld licht of geometrie aanstuurt. Dat maakt het een goede basis, maar niet altijd de beste eindvorm wanneer je meer directionele lokale structuur nodig hebt.

Perlin Noise Verandert De Lattice-Data

Perlin Noise Generator

Interactive map with seed, frequency, and octaves controls.

Perlin noise houdt dezelfde lattice- en interpolatiestructuur, maar verandert wat er op elke hoek wordt opgeslagen. In plaats van een scalair slaat elke hoek een gradientvector op. Op samplepositie pp is de hoekbijdrage het inproduct tussen de gradient op de hoek en de offset van die hoek naar pp:

ci(p)=gi(ppi)c_i(p) = g_i \cdot (p - p_i)

De uiteindelijke waarde wordt vervolgens opgebouwd door die hoekbijdragen over de cel te interpoleren. Het veld is dus nog steeds glad, maar de gladheid komt nu uit directionele invloed in plaats van uit het mengen van opgeslagen hoogtes.

Dat verschil is belangrijk omdat gradients lokale duw of trek coderen. Als het samplepunt dicht bij een hoek ligt waarvan de gradient naar het punt toe wijst, is het inproduct positief. Als de gradient van het punt af wijst, is het negatief. Daardoor voelt het veld meestal coherenter aan dan value noise, omdat de informatie op elke hoek directioneel is en niet alleen scalair.

Er is ook een belangrijke continuïteitsreden waarom Perlin noise zo invloedrijk werd. De soepele fade-curve zorgt ervoor dat de interpolatie geen zichtbare naden op de latticegrenzen introduceert. In de praktijk betekent dat dat het veld herhaald kan worden gesampled zonder duidelijke celranden in het resultaat. De verbeterde Perlin-formulering staat beschreven in Improving Noise, en de oorspronkelijke procedural-texture-context in An Image Synthesizer.

Je kunt de wiskunde van Perlin noise lezen als een tweestapsproces:

  1. Meet hoe elke gradient zich tot het samplepunt verhoudt via een inproduct.
  2. Interpoleer die lokale invloeden met dezelfde soort fade-curve als bij value noise.

Daarom heet Perlin noise vaak gradient noise. De term identificeert de opgeslagen lattice-data, en dat is precies het onderdeel dat verandert. Het zichtbare effect is niet alleen “gladdere random textuur”; het is een andere lokale veldstructuur.

Perlin noise is ook de plek waar schaalbediening duidelijker begint mee te spelen. Als de frequentie te laag is, veranderen de gradients te langzaam en lees je het veld als brede golving. Als de frequentie te hoog is, wordt de structuur compact en druk. De onderliggende vergelijking blijft hetzelfde, maar de coördinaattransformatie pfpp \mapsto f p verandert het zichtbare resultaat sterk.

Fractale Ruis Voegt Octaven Toe

Fractal Noise Generator

Interactive map with seed, frequency, and octaves controls.

Fractale ruis is geen aparte basisformule. Het is een som van lagen, meestal geschreven als een octaafstapel:

F(p)=a0n(f0p)+a1n(f1p)++aN1n(fN1p)F(p) = a_0 n(f_0 p) + a_1 n(f_1 p) + \cdots + a_{N-1} n(f_{N-1} p)

Hier is nn de basisruisfunctie, NN het aantal octaven, fif_i de frequentie van octaaf ii, en aia_i de amplitude daarvan. In de gangbare fBm-opzet groeit de frequentie met een constante factor per octaaf en zakt de amplitude met een constante factor:

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

Hier is λ\lambda de lacunarity en gg de gain. Die compacte notatie beschrijft het hele idee van fractale stapeling: brede structuur komt uit de laagfrequente lagen, en fijnere details komen uit de hogerfrequente lagen die minder sterk bijdragen.

Het visuele resultaat is makkelijk te begrijpen als je de formule zo leest. Het eerste octaaf zet de grote vorm neer. Het tweede octaaf verfijnt die vorm. De latere octaven blijven detail toevoegen, maar hun lagere amplitude voorkomt dat ze de vorm overheersen. Daarom voelt fractale ruis natuurlijk aan: echte oppervlakken hebben vaak structuur op meerdere schalen, niet op slechts één.

De belangrijke praktische waarschuwing is dat meer octaven niet automatisch beter zijn. Als de amplitude niet snel genoeg afneemt, gaan de fijne lagen concurreren met de brede lagen en wordt het resultaat ruisachtig in plaats van gestructureerd. Als de afname te sterk is, voegen de latere octaven te weinig toe om nog uit te maken. De laddervisualisatie hieronder maakt dat afwegingspunt duidelijker zichtbaar.

Octaafstapeling Als Ladder

+

De ladder maakt de octaafsom visueel hiërarchisch. Elke rij is één octaaf, en elk octaaf heeft een andere frequentie en amplitude. De onderste rijen leveren de breedste vorm, terwijl de bovenste rijen die vorm op kleinere schalen aanscherpen of ruw maken. Dat is de visuele betekenis van de vergelijking hierboven: elke term is een aparte schaalband, en het eindsignaal is hun gewogen som.

De regelaars in de ladder passen bij de symbolen in de formule. Octaves verandert NN, het aantal lagen in de som. Lacunarity verandert λ\lambda, en bepaalt hoe snel de frequentie van het ene octaaf naar het volgende stijgt. Gain verandert gg, en bepaalt hoe snel de amplitude afneemt. De sleepbare probe is nuttig omdat hij één ruimtelijke positie over elke rij uitlijnt, zodat je hetzelfde punt op meerdere schalen tegelijk kunt lezen.

De onderste track is de gesommeerde output. Dat is het belangrijkste om te vergelijken. Als de bovenste rijen de gecombineerde vorm beter leesbaar maken, doen ze nuttig werk. Als ze alleen korreligheid toevoegen, zijn ze voorbij het punt van afnemend rendement. Het artikel Random Fractals: Self-Affinity in Noise, Music, Mountains, and Clouds is een goed conceptueel referentiepunt voor waarom multi-scale structuur vaak natuurlijker oogt dan een veld op één schaal.

De ladder maakt ook duidelijk waarom fractale ruis een compositieregel is en geen nieuwe primitive. De basisruis kan value noise of Perlin noise zijn. Wat het resultaat fractaal maakt, is niet alleen de specifieke basiskeuze, maar het herhaald schalen en herwegen over de octaven heen. Dat onderscheid is makkelijk te missen als je alleen naar een enkel eindbeeld kijkt.

Seed, Frequentie En Octaven Zijn Verschillende Knoppen

Ruisbediening is makkelijk te verwarren, omdat alle regelaars het beeld veranderen, maar ze doen dat op verschillende manieren. De schoonste scheiding is:

n(x,y;seed,f,N)n(x, y; seed, f, N)

Hier verandert seedseed de pseudo-willekeurige ordening, ff de inputschaal, en NN het aantal lagen. Die compacte notatie verbergt de implementatiedetails, maar is nuttig omdat het de rol van elke regelaar expliciet maakt.

Seed verandert de hash-input. Als een latticepunt wordt toegewezen via een hashfunctie h(i,j,seed)h(i, j, seed), dan verandert een andere seed de hoekdata zonder de interpolatieregel te veranderen. Daarom gaat seed over reproduceerbaarheid en herordening, niet over featuregrootte.

Frequency herschaalt de coördinaten vóór het samplen. De eenvoudigste vorm is n(fx,fy)n(fx, fy). Als ff stijgt, wordt het patroon in wereldruimte gecomprimeerd, zodat hetzelfde domein meer variatie bevat. Als ff daalt, wordt het patroon uitgerekt en leest het veld rustiger en breder.

Octaves verandert het aantal gesommeerde lagen. Met andere woorden: het verandert de lengte van de reeks in de octaafvergelijking. Het is geen stijlknop en ook geen helderheidsknop. Het is een hiërarchieknoop. Daarom is het zo effectief voor terrein- en wolkenwerk, waar het doel vaak is om brede vorm plus fijne breuk te krijgen zonder de oorspronkelijke vorm te verliezen.

Als die rollen gescheiden zijn, worden de downstream-toepassingen makkelijker te begrijpen. Als je een heightmap bouwt, vertelt frequentie je hoe breed de heuvels zijn voordat het oppervlak wordt gemesht. Als je een signed distance field verstoort, kan dezelfde basisruis het oppervlak vervormen zonder de signed-distance-structuur kapot te maken. Als je ruis in een shader evalueert, beïnvloedt het aantal octaven direct de kosten, omdat elke extra laag een extra sample-pass toevoegt. Die downstream-onderwerpen sluiten direct aan op heightmap to mesh, signed distance fields en vertex en fragment shaders in de grafische pipeline.

Een Praktische Leesvolgorde

De nuttigste manier om de drie technieken te lezen is om de pipeline in volgorde te houden. Begin met één basisveld. Value noise is de eenvoudigste versie van dat idee: willekeurige scalars op latticepunten, soepel geïnterpoleerd. Perlin noise behoudt het lattice, maar verandert de hoekdata naar gradients, zodat het lokale veld directioneel is in plaats van puur scalair. Fractale ruis stapelt daarna één van die basisvelden over meerdere schalen, zodat het eindresultaat zowel vorm als textuur behoudt.

Die volgorde is bewust. Je begint niet met octaven. Je begint met de schaal van het basisveld. Als die schaal verkeerd is, maken octaven de fout alleen maar ingewikkelder. Als de basisschaal goed is, zijn octaven juist het onderdeel dat het patroon geloofwaardige rijkdom geeft.

Dezelfde pipeline-logica is waarom de terminologie ertoe doet. Als een regelaar de pseudo-willekeurige ordening verandert, is het een seed-regelaar. Als een regelaar de afstand tussen kenmerken verandert, is het een frequentieregelaar. Als een regelaar bepaalt hoeveel schalen aanwezig zijn, is het een octave-regelaar. Als die drie rollen gescheiden zijn, vallen de wiskunde en de visuals beter samen in plaats van dat ze tegen elkaar in werken.

Samenvatting

Value noise, Perlin noise en fractale ruis hangen samen, maar zijn niet uitwisselbaar. Value noise interpoleert willekeurige scalairen op de hoeken van het lattice. Perlin noise interpoleert gradient-invloed. Fractale ruis somt meerdere octaven op zodat één signaal tegelijk brede structuur en fijn detail kan beschrijven.

De visualisaties hierboven zijn bedoeld om die verschillen concreet te houden. De noise-generatoren laten zien hoe frequentie, seed en octaven het zichtbare veld beïnvloeden. De ladder laat zien hoe de octaafsom een hiërarchie opbouwt in plaats van één enkele laag. De wiskunde legt uit waarom die veranderingen ertoe doen: andere opgeslagen hoekdata, andere coördinatenschalen en andere octaafgewichten produceren verschillende soorten structuur.

Dat is de belangrijkste les om mee te nemen wanneer ruis een input wordt voor een grotere pipeline, vooral bij ray marching en andere veldgebaseerde render-workflows.