Last updated on

Hoe je een Gesigneerd Afstandsveld Berekent uit een Mesh

ENNLESPT-BR


Een gesampled gesigneerd afstandsveld is een vooraf berekend raster van afstandssamples dat een vorm vertegenwoordigt waarvoor geen compacte afstandsformule bestaat. Driehoeksmeshes zijn de meest voorkomende bron: personages, gescande modellen, levelgeometrie en letterglyphs komen allemaal binnen als lijsten van vertices en vlakken in plaats van als vergelijkingen. Sampling maakt van die mesh een veld dat je overal in de ruimte kunt opvragen.

Dit artikel bouwt voort op de analytische gesigneerde afstandsvelden-tutorial en gaat ervan uit dat de tekensconventie bekend is: negatief binnen, nul op het oppervlak, positief buiten. Hier verandert de vraag van “wat is de formule” naar “hoe bereken en bewaar ik de afstanden überhaupt”.

Waarom een Mesh Geen Gesloten-Vorm-SDF Heeft

Een analytische SDF werkt omdat de vorm structuur heeft die de formule kan benutten. Een bol wordt gedefinieerd door een middelpunt en een straal, dus de afstand tot het oppervlak is de afstand tot het middelpunt min de straal. Een doos wordt gedefinieerd door halve afmetingen, dus de afstand volgt uit een paar geklemde componenten. De formule geldt overal in de ruimte en kost een handvol rekenkundige bewerkingen.

Een driehoeksmesh biedt zo’n snelkoppeling niet. Het is een willekeurige verzameling driehoeken zonder gedeeld middelpunt, gedeelde as of parameterisatie, dus geen enkele uitdrukking geeft de afstand tot het dichtstbijzijnde oppervlak. Je kunt wel een gesloten-vorm-afstand van een punt tot één driehoek opschrijven: projecteer het punt op het vlak van de driehoek en klem het binnen de driehoek, en de lengte van dat verschil is de afstand. De moeilijkheid zit in het woord dichtstbijzijnde. De echte afstand is het minimum over alle driehoeken, en dat minimum vinden vereist een zoektocht. De binnen-en-buiten-test voegt daar een tweede globale vraag aan toe die geen enkele per-driehoek-formule alleen kan beantwoorden.

Dat gat vult sampling. Het evalueert de dure zoektocht op een eindige reeks rasterpunten, slaat de antwoorden op en laat interpolatie de rest doen.

De Mesh-naar-SDF Sampling-Pipeline

Een mesh omzetten naar een gesigneerd afstandsveld wordt vaak het voxeliseren van de mesh genoemd, omdat de uitvoer een volume van cellen (voxels) is die elk een afstandswaarde bevatten. De pipeline heeft vier stappen.

1. Plaats een Raster over de Mesh

Begin met de bounding box van de mesh en voeg een kleine marge toe zodat het veld buiten het oppervlak positief kan worden. Kies dan een resolutie, het aantal samples langs elke as. Het raster wordt de representatie: na het samplen gaan queries naar dit raster en raken ze de driehoeken nooit meer aan. Resolutie is de belangrijkste nauwkeurigheidsknop en de belangrijkste geheugenkost, en de volgende sectie maakt die afweging concreet.

2. Vind de Afstand tot de Dichtstbijzijnde Driehoek

Bereken voor elk rasterpunt p\mathbf{p} de afstand tot elke kandidaat-driehoek en houd de kleinste. De afstand tot één driehoek tt is de afstand tot het dichtstbijzijnde punt erop:

dt(p)=∥p−ct(p)∥d_t(\mathbf{p}) = |\mathbf{p} - \mathbf{c}_t(\mathbf{p})|

waarbij ct(p)\mathbf{c}_t(\mathbf{p}) het dichtstbijzijnde punt op driehoek tt is. Dat dichtstbijzijnde punt ligt in de driehoek, op een van zijn randen of op een hoekpunt, en dezelfde projectie en clamping behandelen alle drie de gevallen. De niet-gesigneerde mesh-afstand is het minimum over de driehoeken:

dsurface(p)=min⁡tdt(p)d_{\text{surface}}(\mathbf{p}) = \min_t d_t(\mathbf{p})

Elke driehoek voor elk sample testen is correct maar traag, dus productie-pipelines versnellen de zoektocht met een bounding volume hierarchy of een ruimtelijk raster dat verre driehoeken vroeg uitsluit. Een andere aanpak schrijft de ruwe afstand alleen nabij het oppervlak en plant die daarna door het raster met een distance transform-sweep, die hetzelfde resultaat in een andere volgorde bereikt.

3. Bepaal aan Welke Kant Elk Sample Ligt

De afstand alleen geeft de grootte, en het teken vereist een binnen-en-buiten-test. Voor een waterdichte mesh werpt de standaardmethode een straal vanaf het sample en telt hoeveel driehoeken die kruist: een oneven aantal betekent binnen, een even aantal betekent buiten. Een winding number-test is robuuster wanneer driehoeken overlappen of de mesh kleine defecten heeft, en het generalized winding number breidt dit uit naar meshes die niet perfect gesloten zijn. Een goedkopere optie voor waterdichte meshes vult het buitenste gebied vanuit de rastergrens (flood fill) en markeert alles wat de vulling niet bereikt als binnen.

Deze stap is waar mesh-SDF’s het vaakst misgaan. Als de mesh gaten, dubbele vlakken of inconsistente winding heeft, klapt het teken om bij het defect en ontwikkelt het gesamplede veld binnenstebuiten-patronen. Goede implementaties controleren de waterdichtheid voordat ze samplen, of vallen terug op een winding number-test die de onvolkomenheid tolereert.

4. Sla de Samples Op en Interpoleer

Sla de gesigneerde samples op in een 3D-textuur of een platte array. Tijdens runtime leest een query de acht omliggende samples en mengt ze met trilineaire interpolatie. Het resultaat is een benaderde afstand die continu blijft over celgrenzen heen en goedkoop genoeg is voor een shader.

Inside Outside Surface

De visualisatie toont dezelfde vier stappen in 2D, waar de mesh een polygoon is en het dichtstbijzijnde element een rand in plaats van een driehoek. Druk op play om het raster in scanline-volgorde te doorlopen: elk sample vindt zijn dichtstbijzijnde rand en noteert een gesigneerde afstand, rood binnen, blauw buiten en wit op de grens. Zet het gereconstrueerde veld aan om bilineaire interpolatie de gaten tussen samples te zien vullen, en vergelijk de gestippelde polygoonomtrek met de gekleurde nulcontour. Bij lage resolutie rondt de contour hoeken af en klipt dunne details weg; resolutie verhogen trekt de gereconstrueerde grens terug naar de echte randen.

Resolutie, Geheugen en Ontbrekend Detail

De rastergrootte groeit snel met de resolutie. Het verdubbelen van het aantal samples per as vermenigvuldigt het aantal samples met 4 in 2D en met 8 in 3D. Een 128³-raster bevat ongeveer 2 miljoen samples, terwijl een 256³-raster meer dan 16 miljoen samples bevat. Bij twee bytes per sample is een 256³-veld ongeveer 32 MB, en bij vier bytes is het 64 MB, nog vóór enige compressie.

Die kost koopt nauwkeurigheid, en hoeken zijn de lastigste plek om die te besteden. De echte afstand verandert abrupt van richting over de bissectrice van een hoek, terwijl trilineaire interpolatie alleen een glad mengsel van de omliggende samples kan produceren, dus rondt de gereconstrueerde nulcontour de hoek af. Hetzelfde effect laat details die dunner zijn dan een voxel volledig uit het veld verdwijnen. Resolutie verhogen verkleint beide fouten, maar de verbetering is geleidelijk en nooit exact.

Twee standaardtrucs verlagen de kost in plaats van de fout. Een narrow band slaat samples alleen op binnen enkele cellen van het oppervlak en slaat het uniforme inwendige en uitwendige over, waar de afstand voorspelbaar is. Sparse opslag en run-length-encoding comprimeren daarna de grote lege gebieden. Beide houden het querygedrag hetzelfde terwijl ze het geheugen verkleinen dat een volledig raster nodig zou hebben.

Werken met een Gesampled Veld

Zodra een veld is gesampled, voedt het dezelfde downstream pipeline als een analytische SDF. CSG-operaties gebruiken scalaire waarden, dus unie, doorsnede en aftrekking werken ongewijzigd op gesamplede velden. Oppervlaktenormalen komen nog steeds uit eindige verschillen tussen naburige samples, en ray marching stapt nog steeds door het veld.

Het belangrijkste praktische verschil is stapveiligheid. Een analytische SDF overschat de afstand tot het oppervlak nooit, wat sphere tracing veilig maakt met stappen gelijk aan de veldwaarde. Trilineaire interpolatie behoudt die garantie niet: de geïnterpoleerde waarde kan de echte afstand tussen samples overschrijden, vooral nabij hoeken. Ray marchers behandelen een gesampled veld als een conservatieve ondergrens, verbreden hun veiligheidsmarges en gebruiken een kleinere stapvermenigvuldiger.

Mesh-Afstandsvelden in Productie

Unreal Engine 5 samplet statische driehoeksmeshes naar sparse voxel grids en gebruikt de resulterende mesh-afstandsvelden voor afstandsveld-schaduwen, ambient occlusion en collisievragen. De voorberekening gebeurt offline tijdens het maken van content, dus de runtimekost bestaat uit rasteropzoekingen en interpolatie. Fysica-engines vertrouwen op dezelfde representatie voor collisies tussen complexe meshes, vaak op een grovere resolutie die ruimtelijke nauwkeurigheid inruilt voor snelheid en die elke frame opnieuw kan worden opgebouwd voor vervormbare objecten.

De 2D-voorloper van deze pipeline is Valve’s weergave van tekst met gesigneerde afstandsvelden. Glyph-contouren worden eenmalig in een afstandstextuur gesampled, en hardware-bilineaire filtering reconstrueert scherpe, anti-aliased randen bij elke vergroting. De mesh-naar-SDF-pipeline in dit artikel is de 3D-versie van hetzelfde idee.

Wanneer de mesh elke frame verandert, kan het samplen van een raster te traag zijn. Een runtime-alternatief evalueert de afstand tot de dichtstbijzijnde driehoek rechtstreeks vanuit een bounding volume hierarchy bij elke query, waarbij het vooraf berekenen wordt ingeruild voor een verse zoektocht. Vooraf berekende rasters blijven de betere keuze wanneer de geometrie statisch is en queries frequent zijn.

Voorbij Uniforme Rasters

Twee uitbreidingen pakken de beperkingen van een uniform raster aan.

Adaptief gesamplede afstandsvelden (ADF’s) vervangen het raster door een octree die dicht samplet nabij oppervlaktekenmerken en spaarzaam in vlakke gebieden, wat geheugen bespaart en detail behoudt. De afweging is doorloop: queries navigeren door een boom in plaats van een platte array te indexeren, wat moeilijker te versnellen is op fixed-function GPU-hardware.

Multi-channel gesigneerde afstandsvelden (MSDF’s) slaan afstanden naar meerdere nabije randen per cel op, met extra kanalen in een textuur. Interpolatie neemt het minimum over de kanalen, wat de scherpe hoeken behoudt die een single-channel veld afrondt, tegen drie tot vier keer zoveel geheugen. MSDF’s zijn standaard in hoogwaardige tekstweergave en komen veel voor bij vectorgraphics op GPU’s.

Beide bouwen op hetzelfde sampling-principe: sample de echte afstand, sla hem op en reconstrueer hem tijdens runtime.