Написать в текстуру GLSL

Я хочу иметь возможность (во фрагментном шейдере) добавить одну текстуру к другой. Прямо сейчас у меня есть проективное текстурирование и я хочу остановиться на этом.

Вот что у меня так далеко:

Я также рисую видоискатель, вдоль которого сине-серое тестовое изображение проецируется на геометрию, которая находится в постоянном вращении.

Мой вершинный шейдер:

    ProjTexCoord = ProjectorMatrix * ModelTransform * raw_pos;

Мой фрагментный шейдер:

vec4 diffuse = texture(texture1, vs_st);
vec4 projTexColor = textureProj(texture2, ProjTexCoord);
vec4 shaded = diffuse; // max(intensity * diffuse, ambient); -- no shadows for now
if (ProjTexCoord[0] > 0.0 ||
ProjTexCoord[1] > 0.0 ||
ProjTexCoord[0] < ProjTexCoord[2] ||
ProjTexCoord[1] < ProjTexCoord[2]){
diffuse = shaded;
}else if(dot(n, projector_aim) < 0 ){
diffuse = projTexColor;
}else{
diffuse = shaded;
}

Чего я хочу добиться:

Например, когда пользователь нажимает кнопку, я хочу, чтобы сине-серая текстура была написано серая текстура на сфере и вращается с этим. Представьте, что это своего рода «фотографирование» или рисование поверх сферы, так что сине-серая текстура вращается вместе со сферой после нажатия кнопки.

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

Как я могу добиться этого технически? Какой метод наиболее универсален? Предложения очень приветствуются, пожалуйста, дайте мне знать, если вам нужно больше кода.

2

Решение

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

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

Я бы начал с создания текстуры, содержащей положение объекта каждого текселя в вашей серой текстуре. Это имеет ключевое значение, так что когда вы нажимаете, вы можете рендерить на свою серую текстуру (используя FBO) и знать, где находится каждый тексель в вашем текущем представлении или в представлении вашей проективной текстуры. Могут быть граничные случаи, когда один и тот же бит текстуры появляется в нескольких треугольниках. Вы можете сделать это, отрисовав сферу в серую текстуру, используя координаты текстуры в качестве позиций вершин. Вам, вероятно, понадобится текстура с плавающей запятой для этого, и следующее изображение, вероятно, не является отображением текстуры сферы, но подойдет для демонстрации: P.

введите описание изображения здесь

Поэтому, когда вы нажимаете, вы рендерите полноэкранный квад на свою серую текстуру с включенным альфа-смешением. Используя позиции пространства объектов серой текстуры, каждый фрагмент вычисляет позицию пространства изображения в проекции синей текстуры. Откажитесь от фрагментов, которые находятся за пределами текстуры, и сэмплируйте / смешайте с теми, которые находятся внутри.

введите описание изображения здесь

2

Другие решения

Я думаю, что вы слишком усложняете вещи.

  • Запись в текстуры внутри классических шейдеров (то есть не вычислительных шейдеров) реализована только для новейшего аппаратного обеспечения и самых последних версий и расширений OpenGL.
  • Это может быть очень медленно, если используется неправильно. Это так просто представить конвейерные лапы и точки синхронизации CPU-GPU
  • Пиксельный шейдер может стать ужасно медленным, неразрешимым беспорядком ветвей и выборок текстур.
  • И весь этот беспорядок будет сделан для каждого пикселя каждый кадр

Решение: ПОЦЕЛУЙ

  • Просто обновите текстуру на стороне процессора.
  • Пишите в текстуру, заменяя ее части желаемым содержимым
  • Обновление необходимо выполнять только один раз и только тогда, когда вам это нужно. Данные сохраняются до тех пор, пока вы их не перезапишите (даже не один раз за кадр, а только один раз за запрос на изменение)
  • Пиксельный шейдер — просто мертвый мозг: нет разветвлений, одна текстура
  • Чтобы получить целевые пиксели, используйте функцию выбора лучей (она понадобится в любом случае для любой нетривиальной интерактивной программы 3D-графики)

Постскриптум «Все должно быть сделано как можно проще, но не проще». Альберт Эйнштейн.

0

По вопросам рекламы [email protected]