Mapy świetlne Half-Life 2 BSP

10

Piszę przeglądarkę BSP dla projektu uniwersyteckiego. Do tej pory mam poprawnie załadowaną główną geometrię, a PVS działa.

Teraz próbuję zastosować lightmapy, ale wydaje mi się, że nie mogę poprawnie wyliczyć współrzędnych tekstury dla lightmap.

Zgodnie z tutaj: 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.
}

Pierwsza tablica pływaków to w zasadzie dwa wektory, które przedstawiają orientację i skalowanie tekstury podczas renderowania na geometrii świata. Dwa wektory s i t są mapowaniem kierunków od lewej do prawej i od dołu do góry w przestrzeni współrzędnych piksela tekstury na świecie. Każdy wektor ma składową x, yiz z plus przesunięcie, które jest „przesunięciem” tekstury w tym kierunku w stosunku do świata. Długość wektorów reprezentuje skalowanie tekstury w każdym kierunku.

Współrzędne 2D (u, v) piksela tekstury (lub texela) są odwzorowywane na współrzędne świata (x, y, z) punktu na twarzy przez:

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

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

(tj. iloczyn iloczynu wektorów z wierzchołkiem plus przesunięcie w tym kierunku. Gdzie tvA, B to textureVecs [A] [B].

Ponadto, po obliczeniu (u, v), aby przekonwertować je na współrzędne tekstury, które wyślesz na kartę graficzną, podziel u i v odpowiednio przez szerokość i wysokość tekstury.

Więc wykonuję obliczenia w następujący sposób. Weź iloczyn punktowy wierzchołka i wektora lightmap (lightmapVecs [0] [0], lightmapVecs 0 , lightmapVecs [0] [2]) dodaj przesunięcie (lightmapVecs [0] [3]), odejmij minuty i podziel wynik według szerokości / wysokości.

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);

Jednak wygląda to tak: mapy świetlne

Oto przykładowe obliczenie dla współrzędnej tekstury „t” dla jednego wierzchołka.

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

Zatem iloczyn skalarny to -1408

(-1408 + 0 - 9) / 14

t = -101.21

To wydaje się dalekie.

terryhau
źródło
Jeśli możesz opublikować link do zdjęcia w komentarzach, ktoś może go dla Ciebie edytować.
Kaczka komunistyczna
Dzięki. Mam kilka głosów, więc mogę teraz publikować zdjęcia. :)
terryhau
Dlaczego dzielisz przez 14? Czy rozmiar twojej lightmapy jest naprawdę „14”? Większość lightmap ma moc 2 ...
PatrickB

Odpowiedzi:

0

W końcu doszedłem do wniosku, że źle odczytałem dane. Cały powyższy kod jest poprawny.

terryhau
źródło
0

Powinieneś znormalizować wektory przed obliczeniem iloczynu kropkowego.

fabiański
źródło