Повторите текстуру кубической карты на грани куба с помощью OpenGL

Можно ли сделать так, чтобы текстура кубической карты (GL_TEXTURE_CUBE_MAP_POSITIVE_X...) повторялась на данной грани с помощью OpenGL?

У меня есть простой единичный куб с 24 вершинами, центрированными вокруг начала координат (xyz между (-0,5, -0,5, -0,5) и (0,5, 0,5, 0,5)). Среди его атрибутов изначально я установил координаты uvw в положение xyz во фрагментном шейдере, как это было сделано в кубической карте обучающий курс Learnopengl.com. Очевидно, я также пытался установить отдельные uvw-координаты со значениями, равными масштабу, но текстура не повторялась ни на одной грани куба, как видно из показанного ниже (я нарисовал uvw-координаты во фрагментном шейдере):

Повторите текстуру кубической карты на грани куба с помощью OpenGL

высота (координата y верхних пикселей) = 3,5 на изображении выше, поэтому, установив v = 3,5 для вершины вверху, я ожидаю, что градиент будет повторяться по вертикали (что не так).

Если это невозможно, единственный способ исправить это — назначить 2D-текстуру с пользовательскими координатами uv для каждой вершины, верно?

Почему вы используете текстуру кубической карты на кубе?

Nicol Bolas 06.05.2022 22:45

Сначала я думал о том, чтобы на каждую грань нанести разную текстуру.

Hakim 06.05.2022 23:25

@Hakim, тогда вам нужна текстура массива.

Yakov Galka 07.05.2022 00:05

@YakovGalka В итоге я использовал 2D-текстуру с 2D-координатами UV (думаю, кубические карты не предназначены для того, что я думал сделать). Буду признателен, если у кого-нибудь есть ссылка, подтверждающая мои сомнения, чтобы я мог закрыть эту тему.

Hakim 07.05.2022 12:40
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
4
35
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Нет, для кубических карт нельзя использовать обертку с помощью GL_REPEAT. Вероятно, вам следует взглянуть на альтернативы, которые люди предложили в комментариях..

Причина этого в том, что координаты, которые вы передаете сэмплеру кубической карты, интерпретируются как направление. Длина этого направления игнорируется. Вы можете думать об этом так, как если бы vec3, используемый для выборки, нормализовался, поэтому перенос никогда не произойдет.

Если по какой-либо причине вам нужно использовать кубическую карту, вы можете изменить направление выборки в шейдере.

vec3 tweakSampleDirForReapeat(vec3 dir, float repeatScale)
{
    for(int i = 0; i < 3; i++) {
        float d = abs(dir[i]);
        if (abs(d) >= 0.5) // skip dominant direction (assuming a coordinate in a unit cube centered at the origin)
            continue;
        d += 0.5; // transform from [-0.5, +0.5] range to [0, 1]
        d *= repeatScale; // transform from [0, 1] range to [0, repeatScale]
        d = fract(d); // wrap [0, repeatScale] to multiple [0, 1] ranges
        d -= 0.5; // transform from [0, 1] range to [-0.5, +0.5]
        dir[i] = d;
    }
    return dir;
}

Отказ от ответственности: этот код должен работать, но я на самом деле его не пробовал.

Этот код можно адаптировать для поддержки различных масштабов repearScales для каждой грани.

Обновлено: Я попытаюсь объяснить, что делает этот код.

Представьте, что у нас есть точка, лежащая на грани +X куба.

Мы пытаемся изменить местоположение этой синей точки. Мы пока не знаем, где именно разместить эту точку. Но эта точка будет в том же лице.

В этом случае значение X равно +0,5. Остальные координаты (Y и Z) будут иметь значения меньше 0,5 по абсолютной величине.

Вот что мы проверяем, если:

if (abs(d) >= 0.5) // skip dominant direction
    continue;

Таким образом, в основном, если X равно -0,5 или +0,5, мы не хотим изменять X, чтобы сохранить его на той же грани.

Мы изменим только Y и Z.

Теперь давайте посмотрим на куб с другой точки зрения. Теперь мы видим лицо +X, обращенное к нам.

С этой точки зрения мы можем ясно видеть, что Y и Z оба <0,5 (по абсолютной величине), так как точка находится внутри прямоугольника.

Теперь добавим текстуру.

По умолчанию мы получаем целую текстуру, нанесенную на лицо.

Но мы хотели бы что-то вроде этого.

Вот что пытается сделать это преобразование:

d += 0.5; // transform from [-0.5, +0.5] range to [0, 1]
d *= repeatScale; // transform from [0, 1] range to [0, repeatScale]
d = fract(d); // wrap [0, repeatScale] to multiple [0, 1] ranges
d -= 0.5; // transform from [0, 1] range to [-0.5, +0.5]

Я рекомендую вам пройти алгоритм с несколькими примерами, используя бумагу и карандаш. Я уверен, что вы в конечном итоге поймете это, это просто вопрос времени. Удачи!

Вопрос викторины: что будет «repeatScale» для предыдущего изображения?

Спасибо, а не могли бы вы уточнить, что делает этот шейдер? Я понимаю, что означают функции, но не смысл

Hakim 07.05.2022 14:53

@Hakim Я исправил код, добавил несколько комментариев и немного объяснений.

tuket 07.05.2022 17:15

Другие вопросы по теме