Туннельный шейдер (преобразованный из WebGL в OpenGL) — координаты текстуры не совпадают?

На прошлой неделе я пытался преобразовать классический демо-эффект туннеля из различных примеров WebGL в openFrameroks (используя шейдер OpenGL GLSL). После многих исследований, проб и ошибок и, в основном, после прочтения [этого всеобъемлющего урока] [1] и [и этого тоже] [2], я все еще не понимаю, почему не работает конвертированный шейдер. Похоже, это какая-то проблема с текстурными координатами, по крайней мере, я так думаю.

Насколько я понимаю принцип, вы получаете значения пикселей из текстуры, вычисляя угол и расстояние от центра и передавая их в качестве выходных данных. Но результаты сильно отличаются.
Вот результат из [примера ShaderToy] [3] и [вот пример] [4] из кода, с которым я начал экспериментировать. И вот что я получил в openFrameworks:
! [введите описание изображения здесь] [5] с этой текстурой, переданной в шейдер:
! [введите описание изображения здесь] [6] Похоже, что шейдер просто проходит через верхний ряд пикселей, потому что через некоторое время экран остается одного цвета (это как достижение конца туннеля). Я попытался использовать текстуру только с цветовым шумом, так как пиксели и цвет финальной стадии были ровно желтыми, как последний пиксель в верхней строке. Странный.
Надеюсь, кто-нибудь скажет мне, где проблема.

Вот testApp.cpp

void testApp::setup(){

texture.loadImage("koalaSQ.jpg"); // 512x512px
tunnel.load("tunnel.vert", "tunnel.frag");
projection.set(640, 480);
projection.setPosition(320, 240, 0);
projection.setResolution(2,2);
projection.mapTexCoordsFromTexture(texture.getTextureReference());

}

void testApp::draw(){
ofSetColor(255);

if (ofGetKeyPressed('g')) // used just for testing texture
{

ofBackground(0, 0, 0);
texture.bind();
projection.draw();
texture.unbind();

}else
{
ofBackground(0, 0, 0);
tunnel.begin();
tunnel.setUniform1f("timeE", time/1000);
tunnel.setUniform2f("resolution", 512,512);
tunnel.setUniformTexture("tex", texture.getTextureReference(), 0);
projection.draw();

tunnel.end();}

time = ofGetElapsedTimeMillis();

}

а вот и шейдеры:

 // vertex shader - simple pass-though with texcoodrs as output for fragent shader
#version 150
uniform mat4 modelViewProjectionMatrix;
in vec4 position;
in vec2 texcoord;
out vec2 texC;

void main()
{
gl_Position = modelViewProjectionMatrix * position;
texC = texcoord;
}
// ------------------------Fragent shader----------------------
#version 150
precision highp float;
uniform sampler2DRect tex;
uniform float timeE;
uniform vec2 resolution;
in vec2 texC;
out vec4 output;

void main(){

vec2 position = 2.0 * texC.xy / resolution.xy -1.0;
position.x *= resolution.x / resolution.y;

float a = atan(position.y, position.x);
float r = length(position);

vec2 uv = vec2(1/ r + (timeE*5), a/3.1416);
vec3 texSample = texture(tex, uv).xyz;
output = vec4(vec3(texSample), 1);
}

0

Решение

Есть много деталей, которые вы не указали (то есть, какие значения вы используете для texcoord). Тем не менее, я думаю, что я все еще могу объяснить, почему ваш код приводит к доступу только к нижней строке (вы можете думать о ней как о верхней строке, когда используете массив изображений сверху вниз в качестве данных изображения для glTexImage(), но технически это будет нижний ряд.)

Ты используешь uv как координаты при извлечении текстуры. И вы определяете uv.y быть atan(position.y, position.x)/3.1415, поскольку atan() вернет водку в [-pi, pi]Вы нормализуете координаты примерно до интервала [-1,1], Классическое пространство текстур OpenGL [0,1]где 0 будет нижний ряд и 1 верхний ряд. Тем не менее, вы используете sampler2DRectтак что вы используете текстуры прямоугольника. В этом случае координаты текс не нормализуются, а координаты пикселей [0,width] в горизонтальном направлении и [0,height] в вертикальном направлении.

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

2

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

Других решений пока нет …

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