Dat klopt volgens mij niet helemaal wat je nu zegt. Doom gebruikt een raycasting techniek om de muren te renderen (inderdaad in verticale strips van 1 pixel breed). De z- (diepte-) waarden op de 4 hoeken van de muren werden bij de originele Doom volgens mij gewoon lineair geinterpoleerd over de strips
Nee, het is een raycaster zoals je zelf al zegt.
Er wordt dus helemaal niets geinterpoleerd over verschillende strips. Voor elke verticale beeldlijn wordt er een ray de wereld ingestuurd, die ergens op een muur terecht komt. Voor die ene ray wordt er dus een verticale beeldlijn getekend aan de hand van de z-waarde van het snijpunt met de muur en de eigenschappen van de muur (texture en coordinaten-offsets). De z-waarden over de hele beeldlijn zijn altijd exact identiek
omdat je niet naar boven en naar beneden kunt kijken. Die ene verticale beeldlijn heeft dan ook compleet niets van doen met de beeldlijn die ernaast staat, ookal wordt daarvoor dezelfde muur gerenderd. En juist door deze distinctie is perspectieve correctie niet nodig - je interpoleert immers nooit horizontaal over een muur.
Jij bent in de war met een polygon rasterizer die een polygoon op het scherm projecteert en tussen de hoekpunten gaat interpoleren. Dat werd pas met Quake gedaan (alwaar ze een instelbare subdivision scheme gebruikten om het nog enigszins perspectivisch correct weer te geven - default werd om de 16 (horizontale) pixels de texturecoordinaten gecorrigeerd adhv de juiste z-waarde).
Neem mijn
Javascript implementatie van Wolfenstein, die simpelweg de DOM gebruikt om te renderen. Het is perspectivisch correct, wat mogelijk is omdat ik alleen maar verticale lijnen van de textures hoef weer te geven. Ik hoef dus niet raar te roteren, laat staan dat de pixels die opgevraagd worden met ongelijke afstand uit elkaar liggen. Dit verandert zodra je naar boven en naar beneden zou kunnen kijken, waardoor het niet meer mogelijk wordt om dat met een DOM rendering methode te implementeren.
Anders gezegd: 'z' waarden lineair interpoleren over de edges van een polygoon is sowieso nooit correct.
Sowieso doet niemand dat. De 1/z waarde wordt geinterpoleerd bij polygon rasterizers, omdat je anders nooit correct een zbuffer kunt implementeren (dit komt door de projectie - een 3d (x, y, z) punt wordt naar 2d geprojecteerd als (x/z, y/z)). Waar het om gaat is dat je de texturecoordinaten niet zomaar kunt interpoleren, omdat ondertussen de diepte veranderd. De reden is omdat hoe verder de polygoon van je af geraakt, hoe groter de afstand wordt tussen de geprojecteerde texels op het scherm, en dus hoe sneller de texturecoordinaten veranderen. Dit is op te lossen door ipv u en v (de texturecoordinaten) juist u/z en v/z te interpoleren als je langs de edges van de polygoon loopt, en die tijdens de interpolatie van de huidige scanline weer te vermenigvuldigen met de huidige z. En aangezien je de huidige z aan het interpoleren bent als 1/z, moet je dus delen door 1/z. Die deling is relatief duur, wat de reden is dat dat in Quake nog niet per pixel werd gedaan.
[Reactie gewijzigd door .oisyn op 22 juli 2024 14:57]