На прошлой неделе я пытался преобразовать классический демонстрационный эффект туннеля из различных примеров 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);
}
highp
во фрагментном шейдере. Вам необходимо проверить наличие определения препроцессора:GL_FRAGMENT_PRECISION_HIGH
перед объявлением чего-либоhighp
во фрагментном шейдере. В противном случае этот шейдер не сможет скомпилировать на некоторых аппаратных / программных реализациях. - person Andon M. Coleman   schedule 17.11.2013GL_FRAGMENT_PRECISION_HIGH
и остальные различия между WebGL и OpenGL, так как это может пригодиться позже :) - person sphere42   schedule 18.11.2013