Возможно ли, что очень мелкие частицы исчезнут, когда я использую RTT?

Я разработал более 20 мобильных приложений с использованием OpenGL ES 2.0. Однако я пытаюсь сделать средство визуализации для использования моих приложений в OSX, поэтому теперь я использую OpenGL v3.3 с GLSL v130. Вчера я столкнулся с проблемой, что я не могу использовать текстуру (RTT), которую я рисовал частицами на Off-Screen FBO с размером GL_LINES 1.0 (это максимальное значение в OpenGL 3.3, почему??)

Когда я нарисовал геометрию на FBO Off Screen и использовал ее в качестве текстуры на экране, я смог это увидеть, а также, если я рисую мелкие частицы на экране, я могу ясно видеть их, но если я попытаюсь нарисовать эту частицу линии и попробовать использовать его как текстуру на главном экране я вижу только черную текстуру.

Я уже проверил ОШИБКИ GL и вернулся к статусу FBO и параметрам смешивания GL, но я все еще пытаюсь решить эту проблему.

У кого-нибудь есть идея решить эту проблему?

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

// AFTER generate and bind FBO, generate RTT 
StarTexture fboTex;
fboTex.texture_width = texture_width;
fboTex.texture_height = texture_height;
glGenTextures(1, &fboTex.texture_id);
glBindTexture(GL_TEXTURE_2D,fboTex.texture_id);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture_width, texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboTex.texture_id, 0);

а это отрисовка частиц на BACK FBO

glUniformMatrix4fv( h_Uniforms[UNIFORMS_PROJECTION], 1, GL_FALSE, g_proxtrans.s);
glBindBuffer(GL_ARRAY_BUFFER, h_VBO[VBO_PARTICLE]);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec3)*ParticleNumTotal*2, &p_particle_lc_xy[0]);
glVertexAttribPointer(h_Attributes[ATTRIBUTES_POSITION], 3, GL_FLOAT, 0, 0,0);
glEnableVertexAttribArray(h_Attributes[ATTRIBUTES_POSITION]);


glBindBuffer(GL_ARRAY_BUFFER, h_VBO[VBO_COLOR]);
glVertexAttribPointer(h_Attributes[ATTRIBUTES_COLOR], 4, GL_FLOAT, 0, 0,0);
glEnableVertexAttribArray(h_Attributes[ATTRIBUTES_COLOR]);

glLineWidth(Thickness); // 1.0 because it is maxium

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, h_VBO[VBO_INDEX_OFF1]);
glDrawElements(GL_LINES, 400, GL_UNSIGNED_INT, 0); // 200 lines

и когда я рисую это на главном экране

glClearColor(0.0, 0.0, 0.0, 1.0);
glClear( GL_COLOR_BUFFER_BIT);

starfbo->bindingVAO1();

glViewport(0, 0, ogl_Width, ogl_Height);
glUseProgram(h_Shader_Program[Shader_Program_FINAL]);

glBindBuffer(GL_ARRAY_BUFFER, h_VBO[VBO_TEXCOORD2]);
glVertexAttribPointer(h_Attributes[ATTRIBUTES_UV2], 2, GL_FLOAT, 0, 0,0);
glEnableVertexAttribArray(h_Attributes[ATTRIBUTES_UV2]);

glBindBuffer(GL_ARRAY_BUFFER, h_VBO[VBO_SQCOORD2]);
glVertexAttribPointer(h_Attributes[ATTRIBUTES_POSITION3], 2, GL_FLOAT, 0, 0,0 );
glEnableVertexAttribArray(h_Attributes[ATTRIBUTES_POSITION3]);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, h_VBO[VBO_INDEX_ON]);
glDrawElements(GL_TRIANGLES,sizeof(squareIndices)/sizeof(squareIndices[0]), GL_UNSIGNED_INT ,(void*)0);

  glUniformMatrix4fv( h_Uniforms[UNIFORMS_PROJECTION], 1, GL_FALSE, g_proxtrans.s);


glBindBuffer(GL_ARRAY_BUFFER, h_VBO[VBO_PARTICLE]);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec3)*ParticleNumTotal*2, &p_particle_lc_xy[0]);
glVertexAttribPointer(h_Attributes[ATTRIBUTES_POSITION], 3, GL_FLOAT, 0, 0,0);
glEnableVertexAttribArray(h_Attributes[ATTRIBUTES_POSITION]);


glBindBuffer(GL_ARRAY_BUFFER, h_VBO[VBO_COLOR]);
glVertexAttribPointer(h_Attributes[ATTRIBUTES_COLOR], 4, GL_FLOAT, 0, 0,0);
glEnableVertexAttribArray(h_Attributes[ATTRIBUTES_COLOR]);

glLineWidth(Thickness);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, h_VBO[VBO_INDEX_OFF1]);
glDrawElements(GL_LINES, 400, GL_UNSIGNED_INT, 0);

person Sung    schedule 05.09.2014    source источник
comment
В качестве эксперимента вы можете попробовать очистить FBO чем-то другим, кроме черного. Это покажет вам, успешно ли используется текстура в качестве цели рендеринга и работает ли выборка из нее во время вашего второго прохода рендеринга.   -  person Reto Koradi    schedule 05.09.2014
comment
@Reto Koradi Как я уже говорил, FBO успешно используется, но частицы исчезают.   -  person Sung    schedule 05.09.2014


Ответы (2)


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

Представьте крайний случай. Скажем, вы визуализируете несколько тонких линий в текстуру размером 1000x1000, освещая очень небольшую часть от общего числа 1 000 000 пикселей. Теперь вы накладываете эту текстуру на четырехугольник размером 10x10 пикселей при отображении. Фрагментный шейдер вызывается один раз для каждого пикселя (при условии отсутствия MSAA), что составляет 100 вызовов шейдера. Каждый из этих 100 вызовов создает образец текстуры. С линейной выборкой и без мип-мэппинга он будет считывать 4 текселя для каждой операции выборки. Всего при рендеринге полигона считывается 100 * 4 = 400 текселей. Вполне вероятно, что чтение этих 400 текселей из общего числа 1 000 000 полностью пропустит все линии, которые вы визуализировали в текстуре.

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

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

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

person Reto Koradi    schedule 05.09.2014

glDrawElements(GL_LINES, 400, GL_UNSIGNED_INT, 0);

GL_UNSIGNED_INT нельзя использовать в OpenGL ES по сравнению с OpenGL. Как ни странно, это работает для IOS, но не для Android.

Параметр должен быть GL_UNSIGNED_BYTE или GL_UNSIGNED_SHORT в OpenGL ES.

person Sung    schedule 18.01.2017