Half-Life 2 BSP Lightmaps

10

Я пишу BSP Viewer для университетского проекта. Пока что основная геометрия загружена правильно, а PVS работает.

Сейчас я пытаюсь применить световые карты, но я не могу получить правильные координаты текстуры для световых карт.

Согласно здесь: 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.
}

Первый массив с плавающей точкой - это, по сути, два вектора, которые представляют, как текстура ориентируется и масштабируется при визуализации в геометрии мира. Два вектора, s и t, являются отображением направлений слева направо и снизу вверх в координатном пространстве пикселей текстуры на мир. Каждый вектор имеет компоненты x, y и z плюс смещение, которое является «сдвигом» текстуры в этом направлении относительно мира. Длина векторов представляет масштабирование текстуры в каждом направлении.

2D координаты (u, v) пикселя текстуры (или текселя) отображаются на мировые координаты (x, y, z) точки на грани с помощью:

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

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

(т.е.. Точечное произведение векторов с вершиной плюс смещение в этом направлении. Где tvA, B - textureVecs [A] [B].

Кроме того, после вычисления (u, v), чтобы преобразовать их в координаты текстуры, которые вы отправите на свою видеокарту, разделите u и v на ширину и высоту текстуры соответственно.

Поэтому я делаю расчет следующим образом. Возьмите скалярное произведение вершины и вектор карты освещения (lightmapVecs [0] [0], lightmapVecs 0 , lightmapVecs [0] [2]), добавьте смещение (lightmapVecs [0] [3]), вычтите мин и разделите результат по ширине / высоте.

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

Однако в конечном итоге это выглядит так: лайтмапы

Вот пример расчета для координаты текстуры 't' для одной вершины.

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

Таким образом, скалярное произведение равно -1408

(-1408 + 0 - 9) / 14

t = -101.21

Это кажется далеко.

terryhau
источник
Если вы можете разместить ссылку на изображение в комментариях, кто-то может отредактировать его для вас.
Коммунистическая утка
Спасибо. У меня есть несколько голосов, поэтому я могу публиковать фотографии прямо сейчас. :)
terryhau
Почему ты делишь на 14? Размер вашей карты освещения действительно "14"? Большинство лайтмапов имеют
степень

Ответы:

0

В конце концов я понял, что я неправильно читал данные. Весь код выше верен.

terryhau
источник
0

Вы должны нормализовать векторы, прежде чем вычислять скалярное произведение.

Fabian
источник