Half-Life 2 BSP Lightmaps

10

Ich schreibe einen BSP-Viewer für ein Universitätsprojekt. Bisher habe ich die Hauptgeometrie richtig geladen und das PVS funktioniert.

Jetzt versuche ich, die Lightmaps anzuwenden, aber ich kann die Texturkoordinaten für die Lightmaps scheinbar nicht richtig berechnen.

Laut hier: http://developer.valvesoftware.com/wiki/The_Source_Engine_BSP_File_Format

struct texinfo_t
{
    float textureVecs[2][4];  // [s/t][xyz offset]
    float lightmapVecs[2][4]; // [s/t][xyz offset] - length is in units of texels/area
    int flags;                // miptex flags overrides
    int texdata;               // Pointer to texture name, size, etc.
}

Das erste Array von Floats besteht im Wesentlichen aus zwei Vektoren, die darstellen, wie die Textur beim Rendern auf der Weltgeometrie ausgerichtet und skaliert wird. Die beiden Vektoren s und t sind die Abbildung der Richtungen von links nach rechts und von unten nach oben im Koordinatenraum der Texturpixel auf die Welt. Jeder Vektor hat eine x-, y- und z-Komponente sowie einen Versatz, der die "Verschiebung" der Textur in diese Richtung relativ zur Welt darstellt. Die Länge der Vektoren repräsentiert die Skalierung der Textur in jeder Richtung.

Die 2D-Koordinaten (u, v) eines Texturpixels (oder Texels) werden auf die Weltkoordinaten (x, y, z) eines Punktes auf einer Fläche abgebildet, indem:

u = tv0,0 * x + tv0,1 * y + tv0,2 * z + tv0,3

v = tv1,0 * x + tv1,1 * y + tv1,2 * z + tv1,3

(dh das Punktprodukt der Vektoren mit dem Scheitelpunkt plus dem Versatz in dieser Richtung. Wobei tvA, B texturVecs [A] [B] ist.

Teilen Sie nach der Berechnung von (u, v) u und v durch die Breite bzw. Höhe der Textur, um sie in Texturkoordinaten umzuwandeln, die Sie an Ihre Grafikkarte senden würden.

Also mache ich die Berechnung wie folgt. Nehmen Sie das Punktprodukt des Scheitelpunkts und des Lightmap-Vektors (lightmapVecs [0] [0], lightmapVecs 0 , lightmapVecs [0] [2]), addieren Sie den Offset (lightmapVecs [0] [3]), subtrahieren Sie die Minuten und dividieren Sie das Ergebnis durch die Breite / Höhe.

float s = Vector3f.dot(v, new Vector3f(lightmapVecs[0][0], lightmapVecs[0][1], lightmapVecs[0][2])) + lightmapVecs[0][3] - f.LightmapTextureMinsInLuxels[0];
float t = Vector3f.dot(v, new Vector3f(lightmapVecs[1][0], lightmapVecs[1][1], lightmapVecs[1][2])) + lightmapVecs[1][3] - f.LightmapTextureMinsInLuxels[1];
s /= (f.LightmapTextureSizeInLuxels[0] + 1);
t /= (f.LightmapTextureSizeInLuxels[1] + 1);

Am Ende sieht es jedoch so aus: Lichtkarten

Hier ist eine Beispielberechnung für die Texturkoordinate 't' für einen Scheitelpunkt.

vertex = 352.0, -144.00027, -224.0
lightmap vector = -4, 0, 0
lightmap offset = 0
lightmap mins = 9
lightmap height = 14

Das Punktprodukt ist also -1408

(-1408 + 0 - 9) / 14

t = -101.21

Das scheint weit weg zu sein.

Terryhau
quelle
Wenn Sie einen Bildlink in den Kommentaren veröffentlichen können, kann ihn jemand für Sie bearbeiten.
Die kommunistische Ente
Vielen Dank. Ich habe ein paar Abstimmungen, damit ich jetzt Bilder posten kann. :)
Terryhau
Warum dividierst du durch 14? Ist die Größe Ihrer Lightmap wirklich "14"? Die meisten Lichtkarten sind Potenzen von 2 ...
PatrickB

Antworten:

0

Ich habe schließlich herausgefunden, dass ich die Daten falsch gelesen habe. Der gesamte obige Code ist korrekt.

Terryhau
quelle
0

Sie sollten die Vektoren normalisieren, bevor Sie das Punktprodukt berechnen.

Fabian
quelle