OpenGL CubeMap порядок лица и проблемы с выборкой - PullRequest
1 голос
/ 07 апреля 2019

У меня есть рендерер на основе SDL2 и OpenGL (профиль ядра 3.3), который дает мне ожидаемые результаты в отношении преобразований и текстур (2D).

Однако, когда я пытаюсь отобразитьВ скайбоксе используется кубическая карта, созданная из этих текстур (хотя я тоже пробовал другие), есть два шага в этом процессе, которые, похоже, не нужно выполнять ни одному другому учебнику или примеру, с которым я столкнулся, и я не могуобъясните:

1, при загрузке необходимо поменять местами верхнюю / нижнюю грани, т. е. верхняя грань загружается как GL_TEXTURE_CUBEMAP_NEGATIVE_Y, а нижняя - GL_TEXTURE_CUBEMAP_POSITIVE_Y;2. При выборке карты куба мне нужно инвертировать положения вершин вдоль y, но также вдоль z;

Без этого я получаю следующий результат:

enter image description here

(обратите внимание, что левая-нижняя-дальняя вершина была масштабирована на 0,8, чтобы уточнить, что моя система координат расположена правильно)

Изображениефайлы имеют правильные имена.

куб - это единственное рисование, которое я выполняю.

Если я удаляю [индексы] для любой из сторон, я получаю ожидаемые результаты (т.е. без обмена местами)/ mirroring).

Кажется, я получаю те же результаты с моими интегрированными и выделенными графическими процессорами.

Мои константы OpenGL из сгенерированного glLoadGen заголовка:

#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519

Код загрузки текстуры (почти такой же, как у урока LearnOpenGL ):

GLuint name;
glGenTextures(1, &name);
glBindTexture(GL_TEXTURE_CUBE_MAP, name);

glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR));

GLint target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
for (uint8_t i = 0; i < 6; ++i)
{
  glTexImage2D(target + i, 0, GL_RGB8, width, height, 0, GL_RGB,
    GL_UNSIGNED_BYTE, pixelData[i]));
}

Вершинный шейдер:

#version 330

precision mediump float;
uniform mat4 uModelViewProjection;
in vec3 aPosition;
out vec3 vTexCoord;

void main()
{
  vec4 position = uModelViewProjection * vec4(aPosition, 1.f);
  gl_Position = position.xyww;

  vTexCoord = aPosition;
}

Фрагментный шейдер:

#version 330

precision mediump float;
uniform samplerCube uTexture0;
in vec3 vTexCoord;
out vec4 FragColor;

void main()
{
  FragColor = texture(uTexture0, vTexCoord);
  // using textureCube() yields a compile error asking for #extension  GL_NV_shadow_samplers_cube : enable, but even with that, the issue perists.
}

Настройка сетки (полупсевдокод):

//    4----5
//   /|   /|
//  6----7 |
//  | |  | |
//  | 0--|-1
//  |/   |/
//  2----3
VertexType vertices[8] = {
  Vector3(-1.f, -1.f, -1.f) * .8f, // debug coordinate system
  Vector3(1.f, -1.f, -1.f),

  Vector3(-1.f, -1.f, 1.f),
  Vector3(1.f, -1.f, 1.f),

  Vector3(-1.f, 1.f, -1.f),
  Vector3(1.f, 1.f, -1.f),

  Vector3(-1.f, 1.f, 1.f),
  Vector3(1.f, 1.f, 1.f),
};

uint16_t indices[] = {
  4, 0, 5,
  0, 1, 5,

  6, 2, 4,
  2, 0, 4,

  7, 3, 6,
  3, 2, 6,

  5, 1, 7,
  1, 3, 7,

  0, 2, 1,
  2, 3, 1,

  5, 7, 4,
  7, 6, 4,
};

// create buffers & upload data

Рендеринг (псевдокод):

// -clear color & depth buffers;
// -set the model transform to a translation of -10 units along z; 
//   view transform is identity; projection is perspective with .25
//   radians vertical FOV, zNear of .1, zFar of 100.; viewport is full screen
// -set shader program;
// -bind texture (same name, same target as upon uploading);
// -enable backface culling only (no depth test / write);
// -draw the cube
// -glFlush() and swap buffers;

Чтона земле может быть причиной двух проблем, описанных выше?

1 Ответ

1 голос
/ 07 апреля 2019

Проблема вызвана отображением координат текстуры .str в кубическую карту:

Спецификация основного профиля API OpenGL 4.6, 8.13 Выбор текстуры карты куба, стр. 253 :

При выборке текстуры кубической карты координаты текстуры (s, t, r) обрабатываются как вектор направления (rx, ry, rz) исходящий из центра куба.Координата q игнорируется.Во время наложения текстуры интерполированный вектор направления для каждого фрагмента выбирает одно из двумерных изображений грани карты куба на основе направления координат наибольшей величины (направления главной оси).Если две или более координаты имеют одинаковую величину, реализация может определить правило для устранения этой ситуации.Правило должно быть детерминированным и зависеть только от (rx, ry, rz) .Столбец цели в таблице 8.19 объясняет, как направление главной оси отображается на двумерное изображение конкретной цели карты куба.Используя sc , tc и ma , определенные по направлению большой оси, как указано в таблице 8.19, обновленный (s, t) рассчитывается следующим образом:

s = 1/2 (sc / |m_a| + 1)

t = 1/2 (tc / |m_a| + 1)

Major Axis Direction|        Target             |sc |tc |ma |
--------------------+---------------------------+---+---+---+
       +rx          |TEXTURE_CUBE_MAP_POSITIVE_X|−rz|−ry| rx|
       −rx          |TEXTURE_CUBE_MAP_NEGATIVE_X| rz|−ry| rx|
       +ry          |TEXTURE_CUBE_MAP_POSITIVE_Y| rx| rz| ry|
       −ry          |TEXTURE_CUBE_MAP_NEGATIVE_Y| rx|−rz| ry|
       +rz          |TEXTURE_CUBE_MAP_POSITIVE_Z| rx|−ry| rz|
       −rz          |TEXTURE_CUBE_MAP_NEGATIVE_Z|−rx|−ry| rz|
--------------------+---------------------------+---+---+---+

Таблица 8.19: Выбор изображений карты куба на основе направления главной оси координат текстуры

Это означает, что боковые текстуры необходимо повернуть перед загрузкой в ​​сэмплер кубической карты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...