Смешайте две текстуры с разными координатами и размерами в одном и том же шейдере

У меня есть две текстуры с разными координатами и размерами в моем шейдере фрагмента:

varying highp vec2 v_currentTextureCoords; varying highp vec2 v_backgroundTextureCoords; uniform sampler2D u_currentTexture; uniform sampler2D u_backgroundTexture; void main() { vec4 currentColor = texture2D(u_currentTexture, v_currentTextureCoords); vec4 backgroundColor = texture2D(u_backgroundTexture, v_backgroundTextureCoords); gl_FragColor = backgroundColor; } 

Вот соответствующий вершинный шейдер:

 attribute vec4 a_position; attribute vec2 a_currentTextureCoords; attribute vec2 a_backgroundTextureCoords; varying vec2 v_currentTextureCoords; varying vec2 v_backgroundTextureCoords; void main() { gl_Position = a_position; v_currentTextureCoords = a_currentTextureCoords; v_backgroundTextureCoords = a_backgroundTextureCoords; } 

Эти шейдеры отвечают за рендеринг u_currentTexture .

EDIT: обновленная почта с моим реальным приложением (приложение для Android) и проблема.

Как вы можете прочитать выше, две текстуры:

  • u_backgroundTexture : это видеопоток, полный экран, размер 1080×1920
  • u_currentTexture : это может быть любое изображение, размер 469×833 ( меньшее, но одинаковое соотношение ).

Чтобы сделать это простым, на данный момент я не хочу ничего смешать , но просто u_backgroundTexture пиксели u_backgroundTexture в шейдерной программе u_currentTexture .

Скриншот приложения - текстура не масштабируется

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

Я хочу отображать пиксели, которые находятся «позади» u_currentTexture (те, что у u_backgroundTexture ), поэтому, в конце концов, никто даже не заметил бы, есть две текстуры.

Но поскольку текстуры имеют разные размеры и координаты , это не дает никакого результата вообще (на данный момент это то, что вы видите выше).

Затем, в моем шейдере фрагментов, мне удалось « масштабировать » текстуру, поэтому изображение в верхнем левом углу имеет тот же «зум», что и фоновое изображение:

Скриншот приложения - текстура масштабирована

Для этого я изменил свой шейдер фрагмента:

 varying highp vec2 v_currentTextureCoords; varying highp vec2 v_backgroundTextureCoords; uniform sampler2D u_currentTexture; uniform sampler2D u_backgroundTexture; uniform vec2 u_scaleRatio; // Notice here void main() { vec4 currentColor = texture2D(u_currentTexture, v_currentTextureCoords); vec4 backgroundColor = texture2D(u_backgroundTexture, v_backgroundTextureCoords * u_scaleRatio); // And here gl_FragColor = backgroundColor; } 

Я установил u_scaleRatio в своей программе с glUniform2fv() . Значения в основном (псевдокод):

 u_scaleRatio = vec2(currentTextureWidth / backgroundTextureWidth, currentTextureHeight / backgroundTextureHeight); 

Как вы можете видеть, он почти работает, но похоже, что есть смещение по оси X: рендеринг изображения в верхнем левом углу – это то, что мы видим в верхнем правом углу … Я не могу найти способ Чтобы исправить это.

Как я могу изменить свои шейдеры, чтобы исправить это смещение, зная, что текстуры имеют разные размеры и координаты?

EDIT 2:

Чтобы ответить на комментарий ниже, это скриншот с

 vec4 backgroundColor = texture2D(u_backgroundTexture, v_currentTextureCoords); 

Скриншот приложения

и с:

 vec4 backgroundColor = texture2D(u_backgroundTexture, v_currentTextureCoords * u_scaleRatio); 

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

EDIT 3: ответить на этот ответ , вот скриншот с:

 uniform vec2 texelSize; // (1.0/windowResolution.x, 1.0/windowResolution.y) vec2 uv = gl_FragCoord.xy * texelSize; vec4 backgroundColor = texture2D(u_backgroundTexture, uv); 

Я понимаю, что вы пытаетесь сделать, я думаю, что это сработало бы, если бы координаты точки и текстуры вершин были одинаковыми для обеих текстур, но … это не так. У вас есть идея, как это исправить?

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

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

 uniform vec2 texelSize; // (1.0/windowResolution.x, 1.0/windowResolution.y) vec2 uv = gl_FragCoord.xy * texelSize; vec4 backgroundColor = texture2D(u_backgroundTexture, uv); 

Встроенная переменная gl_FragCoord.xy "содержит значения относительной координаты окна (x, y, z, 1 / w) для фрагмента" ( https://www.opengl.org/sdk/docs/man/html/gl_FragCoord .xhtml ). Поскольку вам в основном нужны координаты текстуры фрагмента, как если бы они были частью полноэкранного квадроцикла, это должно дать вам ожидаемые результаты. Вам нужно только передать относительный размер полноэкранного текселя как однородного (смотрите в комментариях для расчета).