Как я могу нарисовать плитку из тайловой карты текстуры в шейдере OpenGL?

Итак, у меня есть AtlasTexture, который содержит все тайлы, необходимые мне для рисования тайловой карты.

Прямо сейчас я пропускаю AtlasTexture через униформу, и идея состоит в том, чтобы изменить координату текстуры, чтобы выбрать только ту часть атласа, которая мне нужна.

Проблема в том, что я могу указать только фрагментный шейдер, чтобы вырезать текстуру из нулевого источника. Можно ли указать offsetX, чтобы сообщить шейдеру, где я хочу начать рисовать?

float vertices[] = {
    // aPosition     // aTextureCoordinate
    0.0f,   0.0f,    0.0f, 0.0f,
    100.0f, 0.0f,    1.0f, 0.0f,
    0.0f,   100.0f,  0.0f, 1.0f,
    100.0f, 100.0f,  1.0f, 1.0f,
};

uint32_t indices[] = {0, 1, 2, 2, 3, 1};

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

#version 330 core

layout(location = 0) in vec2 aPosition;
layout(location = 1) in vec2 aTextureCoordinate;
out vec2 textureCoordinate;

void main() {
    gl_Position = vec4( aPosition.x, aPosition.y, 1.0f, 1.0f);
    textureCoordinate = vec2(
    aTextureCoordinate.x / 3.0f, // This selects the first tile in the uAtlasTexture
    aTextureCoordinate.y
    );
}

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

#version 330 core

in vec2 textureCoordinate;
uniform sampler2D uAtlasTexture; // Has 3 tiles
out vec4 color;

void main() {
    color = texture(uAtlasTexture, textureCoordinate);
}

но как применить смещение? Я могу выбрать только часть текстуры слева

ellipticaldoor 21.12.2020 23:41
vec2(1.0/3.0 + aTextureCoordinate.x / 3.0f, aTextureCoordinate.y); выбирает вторую плитку. Используйте униформу вместо 1.0/3.0
Rabbid76 21.12.2020 23:43

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

Andrea 25.12.2020 14:47

спасибо @Andrea, да, все мои плитки одного размера. как я могу использовать текстуры массива?

ellipticaldoor 25.12.2020 19:40

@ellipticaldoor khronos.org/opengl/wiki/Array_Texture предоставляет обзор, хотя я уверен, что есть и другие ресурсы.

Andrea 26.12.2020 15:00
Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
660
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Используйте переменную Uniform для смещения. vec2(1.0/3.0 + aTextureCoordinate.x / 3.0f, aTextureCoordinate.y);' всегда вторая плитка. Вместо этого используйте юниформ-переменную для рисования разных частей и инициализируйте ее значением 1.0/3.0:

#version 330 core

layout(location = 0) in vec2 aPosition;
layout(location = 1) in vec2 aTextureCoordinate;
out vec2 textureCoordinate;

uniform float textureOffsetX;

void main() {
    gl_Position = vec4( aPosition.x, aPosition.y, 1.0f, 1.0f);
    textureCoordinate = vec2(
        textureOffsetX + aTextureCoordinate.x / 3.0f, 
        aTextureCoordinate.y
    );
}

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