У меня есть две текстуры с разными координатами и размеры в моем шейдере фрагмента:
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
: это видеопоток, полный экран, размер 1080x1920. -
u_currentTexture
: это может быть любое изображение размером 469x833 (меньше, но одинаковое соотношение).
Чтобы сделать это простым, на данный момент я не хочу смешивать что-либо, но просто показываю пиксели 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 есть offset: рендеринговое изображение в верхнем левом углу - это то, что мы видим в верхнем правом углу... Я не могу найти способ исправить это.
Как я могу изменить свои шейдеры, чтобы исправить это смещение, зная, что текстуры имеют разные размеры и координаты?
ИЗМЕНИТЬ 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);
Я понимаю, что вы пытаетесь сделать, я думаю, что это сработало бы, если бы координаты точки и текстуры вершин были одинаковыми для обеих текстур, но... они нет. У вас есть идея, как его исправить?