PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Bestimmung von Texturkoordinaten


aths
2004-11-09, 01:23:42
Weiß jemand, ob die Texturkoordinaten pixelweise berechnet werden? Möglich wäre ja auch, sie nur pro Quad zu berechnen und für die anderen Pixel im Quad mit dem Nachbarquad zu interpolieren.

micki
2004-11-09, 08:54:04
Weiß jemand, ob die Texturkoordinaten pixelweise berechnet werden? Möglich wäre ja auch, sie nur pro Quad zu berechnen und für die anderen Pixel im Quad mit dem Nachbarquad zu interpolieren.
ob man nun die coordinate per pixel berechnet, oder für ein quad und dann nochmal interpoliert zwischen zwei quads
würde das nicht ein und das selbe am ende ergeben?

möglich wäre aber wohl beides, da man ja zwischen zwei quads linear interpolieren könnte, wäre vielleicht der rechenaufwand kleiner.
aber müßte in diesem fall nicht für ein poly mit (0,0|1,1|0,1) nicht nur ein und der selbe texel ausgelesen werden?

MfG
micki

aths
2004-11-09, 12:15:38
ob man nun die coordinate per pixel berechnet, oder für ein quad und dann nochmal interpoliert zwischen zwei quads
würde das nicht ein und das selbe am ende ergeben?Nein, sonst bräuchte man es nur pro Vertex tun und könnte es übers ganze Polygon interpolieren.

RLZ
2004-11-09, 14:34:33
So ganz versteh ich die Frage nicht ganz...
Texturkoordinaten werden normalerweise für die meisten Sachen im Vertexshader für die Eckpunkte berechnet und die Zwischenwerte interpoliert für den Fragmentshader.
Allerdings kann man im Fragmentshader die Texturkoordinaten auch noch ändern, wie zb bei Offsetmapping notwendig. Man könnte sie dort auch komplett neu berechnen.
Was meinst du jetzt mit Quads? Die internen Verarbeitungsquads der Grafikkarten?
Kann sein, dass die Interpolation da irgendwie drin realisiert wird. Möglich wärs wohl schon...

aths
2004-11-09, 14:40:47
So ganz versteh ich die Frage nicht ganz...
Texturkoordinaten werden normalerweise für die meisten Sachen im Vertexshader für die Eckpunkte berechnet und die Zwischenwerte interpoliert für den Fragmentshader.
Allerdings kann man im Fragmentshader die Texturkoordinaten auch noch ändern, wie zb bei Offsetmapping notwendig. Man könnte sie dort auch komplett neu berechnen.Ja, aber die Interpolation der Koordinaten muss ja der perspektivischen Verzerrung Rechnung tragen. Da wird nicht einfach nur linear interpoliert.
Was meinst du jetzt mit Quads? Die internen Verarbeitungsquads der Grafikkarten?Ja.

RLZ
2004-11-09, 15:04:58
Ja, aber die Interpolation der Koordinaten muss ja der perspektivischen Verzerrung Rechnung tragen. Da wird nicht einfach nur linear interpoliert.

*lösch*
Natürlich geht die perspektive Verzerrung mit ein.
Ist nur eine Frage, ob man das vernünftig verrechnen kann.
Ich denke eher es wird pixelweise bestimmt. Der Rechenaufwand ist ja recht klein und könnte eigentlich durch entsprechende Einheiten gemacht werden.
Ob die da jetzt noch Optimierungen in ihren Quads drin sind wird man aber wohl weder merken oder bestimmen können....

ScottManDeath
2004-11-09, 16:42:40
Es wird perspektivisch korrekt interpoliert und zwar nach folgender Formel (Aus der OpenGL 2.0 Spec, § 3.5, Seite 109):

micki
2004-11-10, 08:46:12
Nein, sonst bräuchte man es nur pro Vertex tun und könnte es übers ganze Polygon interpolieren.
pro vertex muss man nichts interpolieren, in den vertices sind die texturcoordinaten schon definiert.

MfG
micki

aths
2004-11-10, 10:14:19
pro vertex muss man nichts interpolieren, in den vertices sind die texturcoordinaten schon definiert.Ich weiß. Meine Frage bezog sich darauf, ob stückweise lineare Interpolation gemacht wird, oder nicht. Man bräuchte in jedem Fall (rein für die TC) noch immer das Quad rechts und darunter, was bei kleinen Dreiecken ungünstig ist (auch wenn die Quads dann nicht gerendert werden belastet das erst mal den Quadcache) aber könnte halt für 75% aller Pixel die TC rein mit einem LERP bestimmen.

micki
2004-11-10, 10:30:08
Ich weiß.
du hast aber gesagt, das man es pro vertex machen könnte ;)

Meine Frage bezog sich darauf, ob stückweise lineare Interpolation gemacht wird, oder nicht. Man bräuchte in jedem Fall (rein für die TC) noch immer das Quad rechts und darunter, was bei kleinen Dreiecken ungünstig ist (auch wenn die Quads dann nicht gerendert werden belastet das erst mal den Quadcache) aber könnte halt für 75% aller Pixel die TC rein mit einem LERP bestimmen.
Ich denke mir, da müßte man das mal hand nachprüfen. ich könnte mir aber vorstellen, dass die logic dafür viel aufwendiger wäre als, pro pixel das perspektivisch korrekt zu machen.

bei softwarerasterizern wird jedenfalls meißt nur alle 8-32pixel ein perspektivisch korrekter texturwert ausgerechnet und dazwischen linear interpoliert. (bei Q2 waren es immer 8pixel wenn ich mich recht entsinne).

MfG
micki

aths
2004-11-10, 17:32:00
du hast aber gesagt, das man es pro vertex machen könnte ;)Ja, aber gemeint hatte ich, dass man die Daten eh pro Vertex hat, und man die nicht einfach (einfach = linear) interpolieren kann.

bei softwarerasterizern wird jedenfalls meißt nur alle 8-32pixel ein perspektivisch korrekter texturwert ausgerechnet und dazwischen linear interpoliert. (bei Q2 waren es immer 8pixel wenn ich mich recht entsinne).Das war übrigens der Hintergrund meiner Frage: Unter Umständen wähle ich für meine Diplomarbeit, die ich irgendwann schreiben muss (noch ist es nicht akut) einen Rasterizer schreiben. Will nämlich verschiedene Filterverfahren austesten. Dabei sollte die Implementierung den Gegegebenheiten einer Grafikkarte möglichst nahe kommen, so müsste ich mit Quads arbeiten und quadweise anhand der TC-Differenzen das LOD bestimmen.

Vedek Bareil
2004-11-10, 18:07:09
ömm... ich dachte immer, der Standard-Ansatz in der 3D-Grafik sieht so aus, daß man für jeden Bildschirm-Pixel ein Urbild bzw. die Lage des Pixelmittelpunktes im Texturraum (also auf dem jeweiligen Polygon) berechnet. Und daß darauf alle möglichen Filtertechnologien (von bilinear bis anisotrop) aufbauen. Hast du das in deinem Filter-Artikel nicht selbst so beschrieben? Zumindest im Anisotrop-Abschnitt war eine Grafik zu sehen, die sehr nach einem Pixelurbild im Texturraum aussah.

Deswegen weiß ich nicht, ob ich deine Frage so ganz verstanden habe... meinst du vielleicht, daß man die Lagebestimmung des Pixelmittelpunkts im Texturraum nur für diejenigen Pixel durchführt, in denen Vertices liegen, und die Lage der übrigen Pixelmittelpunkte durch Interpolation?

In dem Fall sollten deine Geometriekenntnisse aber doch wohl ausreichen um zu wissen, daß die Interpolation dann auf gar keinen Fall linear sein kann, wenn man perpektivische Korrektheit haben will ;)

micki
2004-11-10, 18:29:24
dass man nicht jeden pixel perspektivisch richtig interpoliert sondern nur an jedem quad, ist seine vermutung einer optimierung. und sogar wenn man, wie schon erwähnt, alle 16pixel nur perspektivisch korrekt interpoliert, merkt man das eigentlich kaum.

MfG
micki

Demirug
2004-11-10, 19:35:12
aths, der Zugriff auf den Nachbarquad ist hochkritisch weil man nicht sicher weiss wo dieser Quad liegt. In diesem Zusammenhang erinnere ich an den Kernelwalker von nVidia und die Tatsache das vor den Pixelprozessoren in der Regel ein Dispatcher liegt welcher die Quads auf die Pipes verteilt.

Ein übliches Verfahren zum Berechnen der texturekoordinaten wäre folgendens.

1. Man berechnet für den oberen rechten Punkt des Quads T, S und W. (Die dafür notwendigen Daten werden vom Trisetup ermittelt)
2. Die 3 fehlenden Punkte werden durch addieren der Deltas bestimmt.
3. Für alle 4 W Werte wird der Kehrwert bestimmt.
4. Alle T und S Werte werden mit den entsprechenden W Kehrwerten multipliziert.

micki
2004-11-10, 19:45:05
1. Man berechnet für den oberen rechten Punkt des Quads T, S und W. (Die dafür notwendigen Daten werden vom Trisetup ermittelt)
nicht den oberen linken punkt?
normalerweise wird doch von links nach rechts interpoliert, dementsprechend müßte man sonst die deltas für die horizontale abziehen :questionmark:



3. Für alle 4 W Werte wird der Kehrwert bestimmt.

eigentlich müßte doch schon mit dem kehrwert interpoliert werden, da sonst w nicht perspektivisch korrekt wäre?
dementsprechend müßte ein mul reichen, lieg ich falsch?

MfG
micki

Demirug
2004-11-10, 20:38:42
nicht den oberen linken punkt?
normalerweise wird doch von links nach rechts interpoliert, dementsprechend müßte man sonst die deltas für die horizontale abziehen :questionmark:

Im Prinzip kann man jeden Punkt nehmen. Man muss nur die Schaltkreise für das ergänzen des Quads entsprechend auslegen.

eigentlich müßte doch schon mit dem kehrwert interpoliert werden, da sonst w nicht perspektivisch korrekt wäre?
dementsprechend müßte ein mul reichen, lieg ich falsch?

MfG
micki

w ist ja gleich 1/z und die perspektive muss ja auf Basis von Z bestimmt werden. Z ist aber nun mal leider nicht mehr linear. Deswegen W und dann der Kehrwert.

micki
2004-11-10, 21:27:26
Im Prinzip kann man jeden Punkt nehmen. Man muss nur die Schaltkreise für das ergänzen des Quads entsprechend auslegen.



w ist ja gleich 1/z und die perspektive muss ja auf Basis von Z bestimmt werden. Z ist aber nun mal leider nicht mehr linear. Deswegen W und dann der Kehrwert.
linear interpoliert wird mit t/z und s/z.
wenn w=1/z ist
dann muss nicht mit dem kehrwert von w, sondern von z, also mit w selbst multipliziert werden, damit mit man perspektivisch korrekte t und s werte bekommt.

MfG
micki

Demirug
2004-11-10, 22:44:15
linear interpoliert wird mit t/z und s/z.
wenn w=1/z ist
dann muss nicht mit dem kehrwert von w, sondern von z, also mit w selbst multipliziert werden, damit mit man perspektivisch korrekte t und s werte bekommt.

MfG
micki

Ich sehe wo unser Verständnissproblem liegt.

Ich bin natürlich von folgenden ausgegangen:

Wir wollen u/z ; v/z

W = 1/z
T = u*W
S = v*W

Da man im Screenspace interpoliert muss man T und S und nicht u und v interpolieren (die kann man nur im 3 Raum interpolieren). Ich habe hier auch noch irgendwo die Formeln rumliegen die das begründen.

Coda
2004-11-10, 23:42:50
Aths verstehe ich deine Frage richtig, das du meinst nVidia könnte den perspective Divide nur pro Quad anstatt pro Pixel ausführen?

Ich denke das würde keiner merken, vielleicht machen sie's vielleicht auch nicht, schwer zu sagen.

http://home.arcor.de/aexorzist/cube2.png
2x2 Blöcke

http://home.arcor.de/aexorzist/cube16.png
16x16 Blöcke

Jeweils linear interpoliertes 1/z. Bei größeren Blöcken sieht man's also deutlich, aber bei 2x2 wird's wirklich nicht auffallen.

micki
2004-11-11, 00:21:15
Ich sehe wo unser Verständnissproblem liegt.

Ich bin natürlich von folgenden ausgegangen:

Wir wollen u/z ; v/z

W = 1/z
T = u*W
S = v*W

Da man im Screenspace interpoliert muss man T und S und nicht u und v interpolieren (die kann man nur im 3 Raum interpolieren). Ich habe hier auch noch irgendwo die Formeln rumliegen die das begründen.
ich hab gedacht dass du mit t und s die texturcoordinatenbezeichnung von oGL meinst.
naja,

also eigentlich muss man u/z und v/z interpolieren, dazu natürlich 1/z und pro pixel rechnet man dann u'/(1/z') und v'/(1/z')

um mal mit verständlichereren worten zu reden als mit meinen ;) "tricks of the 3d game programming gurus" von LaMothe zu zittieren s.1227:
[quote]
1.During entry/initialization, we need to compute the texture coordinates u/z and v/z and interpolate them as 1/z
2.In the inner loop of the rasterizer, we need to compute the real u,z texture coordinates. this is accomplished by dividing (1/z) into our linearly corret (u/z) and (v/z) values to arrive at the perspective correct (u,v) values at which to sample the texture map.

phu

MfG
micki

hmm... ich glaube ich hatte mich oben bei deinem punkt4 verlesen ;)

aths
2004-11-11, 10:49:06
Aths verstehe ich deine Frage richtig, das du meinst nVidia könnte den perspective Divide nur pro Quad anstatt pro Pixel ausführen?

Ich denke das würde keiner merken, vielleicht machen sie's vielleicht auch nicht, schwer zu sagen.Das LOD gibts ja nur pro Quad, insofern wäre es nicht schlimm, auch die TC nur pro Quad korrekt zu berechnen. Das war mein Gedankengang. Aber wenn ich das richtig sehe, erfordert die perspektivisch korrekte Interpolation pro Pixel dann nur einige MULs, das sollte vom Aufwand her vertretbar sein. Allerdings wird ja vermutlich mit FP32 gerechnet, und bei 16 Pixelpipes bräuchte man dann doch gleich eine Menge FP32-MULs.

Coda
2004-11-11, 17:14:22
Das war mein Gedankengang. Aber wenn ich das richtig sehe, erfordert die perspektivisch korrekte Interpolation pro Pixel dann nur einige MULs
Nein Divs, bzw RCP+MUL, das is deutlich teurer.
Der Trick in Quake 1 und 2 war ja auch das man das RCP nur alle 8 pixel berechnet hat und dann linear interpolierte.

zeckensack
2004-11-13, 10:22:35
w!=z ...

Die Interpolation selbst ist nicht so teuer. Zwei (Vektor-)Mulitplikationen pro Quad, um 1/w "einzupflegen", für den Rest reichen Additionen.

Coda
2004-11-13, 12:40:12
Man interpoliert 1/w, u/w und v/w über das Polygon, weil das linear im Screenspace ist.

Pro Pixel muss man dann aber wieder w = 1/(1/w) rechnen und damit dann u/w und v/w multiplizieren. Dann hat man perspektivisch korrektes Texturemapping.

Wie du da nur mit Additionen und Muls hinkommen willst weiß ich nicht?

zeckensack
2004-11-13, 17:06:06
Wie du da nur mit Additionen und Muls hinkommen willst weiß ich nicht?Es ist ein Trick :)
Erstmal das:Man interpoliert 1/w, u/w und v/w über das Polygon, weil das linear im Screenspace ist.Das ist das wichtigste.
Es gibt eine affine Abbildung von (x;y) nach (s/w;t/w;p/w;q/w). Und die ist auch bekannt, sonst würde die Texturkoordinateninterpolation überhaupt nicht funktionieren.

Formel ahoi:
T'(x;y)=T0+x*DeltaTx+y*DeltaTy
Dabei sind T0, DeltaTx und DeltaTy pro Dreieck konstante Vektoren, und T'(x;y) ein Zwischenergebnis, Ich möchte das mal als die "lineare Texturkoordinate" ("perspektivisch falsch") für das Fragment an der Stelle (x;y) bezeichnen.

Da das ganze bis hierhin noch linear ist, kann man auch stückeln:
T'(x+n;y+m)=T'(x;y)+n*DeltaTx+m*DeltaTy

Insbesondere möchte ich auf die Möglichkeit hinweisen, nur für den Mittelpunkt eines Quads eine "vernünftige" Interpolation durchzuführen, und für die vier Fragmente des Quads dann noch DeltaTx/2 und DeltaTy/2 zu subtrahieren oder zu addieren. Division durch zwei ist bekanntermaßen trivial :)

Um jetzt von der perspektivisch falschen auf eine (eingermaßen ...) perspektivisch korrekte Interpolation zu kommen, muss man nur einmal pro Quad 1/(interpoliertes w) ausrechnen (vorzugsweise ebenfalls für den Mittelpunkt des Quads), und bevor man addiert/subtrahiert, die Delta-Vektoren mit diesem Skalar multiplizieren.

=>
T0(quad) sei gegeben
oow(quad) ebenfalls

=>
T(-1;1):=T0(quad)-oow(quad)*DeltaTx/2+oow(quad)*DeltaTy/2
T(1;1):=T0(quad)+oow(quad)*DeltaTx/2+oow(quad)*DeltaTy/2
T(-1;-1):=T0(quad)-oow(quad)*DeltaTx/2-oow(quad)*DeltaTy/2
T(1;-1):=T0(quad)+oow(quad)*DeltaTx/2-oow(quad)*DeltaTy/2

<=>
Dtx':=oow(quad)*DeltaTx/2
Dty':=oow(quad)*DeltaTy/2
T(-1;1):=T0(quad)-Dtx'+Dty'
T(1;1):=T0(quad)+Dtx'+Dty'
T(-1;-1):=T0(quad)-Dtx'-Dty'
T(1;-1):=T0(quad)+Dtx'-Dty'

Und dafür braucht man die zwei Vektormultiplikationen, von denen ich sprach :)

€:
Die "perfekte" Alternative kostet vier RCPs und vier Vektormultiplikationen pro Quad. Geiz ist geil X-D

micki
2004-11-13, 17:18:00
und für die vier Fragmente des Quads dann noch DeltaTx/2 und DeltaTy/2 zu subtrahieren oder zu addieren. Division durch zwei ist bekanntermaßen trivial :[quote]
ist das nicht eh eine konstante? das muss man nur einmal pro hline machen,oder?

[QUOTE=zeckensack]
Um jetzt von der perspektivisch falschen auf eine (eingermaßen ...) perspektivisch korrekte Interpolation zu kommen, muss man nur einmal pro Quad 1/(interpoliertes w) ausrechnen (vorzugsweise ebenfalls für den Mittelpunkt des Quads), und bevor man addiert/subtrahiert, die Delta-Vektoren mit diesem Skalar multiplizieren.

"der trick" war ja eigentlich die frage von aths, ob man das nur einmal pro quad macht auf der hardware oder doch pro pixel dividiert
dass das in software meißtens eh nur alle 8-32 macht, das wurde schon genannt ;)

und soviele multiplikationen ;)

MfG
micki

Coda
2004-11-13, 19:18:13
Zeckensack: Wir reden anneinander vorbei :D

Du hast genau das gleiche erzählt wie ich früher, oder zumindest ähnlich.

zeckensack
2004-11-13, 19:32:23
Zeckensack: Wir reden anneinander vorbei :D

Du hast genau das gleiche erzählt wie ich früher, oder zumindest ähnlich.In der Tat. Du hast ja ausdrücklich "perspective divide" geschrieben :)

Ich bezog mich ursprünglich auf aths' Gedankengang:Das LOD gibts ja nur pro Quad, insofern wäre es nicht schlimm, auch die TC nur pro Quad korrekt zu berechnen.
<...>
Aber wenn ich das richtig sehe, erfordert die perspektivisch korrekte Interpolation pro Pixel dann nur einige MULs, das sollte vom Aufwand her vertretbar sein. Allerdings wird ja vermutlich mit FP32 gerechnet, und bei 16 Pixelpipes bräuchte man dann doch gleich eine Menge FP32-MULs.... dabei geht's eben noch einfacher :)