Cartes lumineuses Half-Life 2 BSP

10

J'écris une visionneuse BSP pour un projet universitaire. Jusqu'à présent, la géométrie principale est correctement chargée et le PVS fonctionne.

Maintenant j'essaie d'appliquer les lightmaps, mais je n'arrive pas à obtenir les coordonnées de texture pour les lightmaps calculées correctement.

Selon ici: 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.
}

Le premier tableau de flottants est essentiellement deux vecteurs qui représentent comment la texture est orientée et mise à l'échelle lorsqu'elle est rendue sur la géométrie du monde. Les deux vecteurs, s et t, sont le mappage des directions de gauche à droite et de bas en haut dans l'espace de coordonnées des pixels de texture, sur le monde. Chaque vecteur a une composante x, y et z, plus un décalage qui est le "décalage" de la texture dans cette direction par rapport au monde. La longueur des vecteurs représente l'échelle de la texture dans chaque direction.

Les coordonnées 2D (u, v) d'un pixel de texture (ou texel) sont mappées aux coordonnées universelles (x, y, z) d'un point sur une face par:

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

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

(ie. Le produit scalaire des vecteurs avec le sommet plus le décalage dans cette direction. Où tvA, B est textureVecs [A] [B].

De plus, après avoir calculé (u, v), pour les convertir en coordonnées de texture que vous enverriez à votre carte graphique, divisez respectivement u et v par la largeur et la hauteur de la texture.

Je fais donc le calcul comme suit. Prenez le produit scalaire du sommet et du vecteur lightmap (lightmapVecs [0] [0], lightmapVecs 0 , lightmapVecs [0] [2]) ajoutez le décalage (lightmapVecs [0] [3]), soustrayez les minutes et divisez le résultat par la largeur / hauteur.

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

Cependant, cela finit par ressembler à ceci: cartes lumineuses

Voici un exemple de calcul pour la coordonnée de texture 't' pour un sommet.

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

Donc, le produit scalaire est -1408

(-1408 + 0 - 9) / 14

t = -101.21

Cela semble loin.

terryhau
la source
Si vous pouvez publier un lien d'image dans les commentaires, quelqu'un peut le modifier pour vous.
Le canard communiste
Merci. J'ai obtenu quelques votes pour que je puisse publier des photos maintenant. :)
terryhau
Pourquoi divisez-vous par 14? La taille de votre lightmap est-elle vraiment "14"? La plupart des lightmaps sont des puissances de 2 ...
PatrickB

Réponses:

0

J'ai finalement compris que je lisais mal les données. Tout le code ci-dessus est correct.

terryhau
la source
0

Vous devez normaliser les vecteurs avant de calculer le produit scalaire.

Fabien
la source