Альтернативные значения gl_FragColor из двух текстур в GLSL

#opengl #glsl #textures

#opengl #glsl #Текстуры

Вопрос:

У меня есть две текстуры, cloud и hill, каждая размером 512 x 512, и я намерен создать вывод gl_FragColor, который получит значения пикселей из предыдущих текстур. В этом случае я хочу получить 1-й пиксель в gl_FragColor из 1-го пикселя в 1-й текстуре, 2-й пиксель в gl_FragColor из 2-го пикселя во 2-й текстуре, 3-й пиксель в gl_FragColor из 3-го пикселя в 1-й текстуре и так далее. Вот мой фрагмент кода шейдера:

  uniform sampler2D tex0;
 uniform sampler2D tex1;

 void main() {
     vec4 cloud = texture2D(tex0, gl_TexCoord[0].st);
     vec4 hill = texture2D(tex1, gl_TexCoord[0].st);
     for (int i=0;i<512;i  ) {
       for (int j=0;j<512;j  ) {
            if ( j%2 == 0)
                gl_FragColor =  cloud;
            else
                gl_FragColor =  hill;
          }
     }
  }
  

Вот настройка текстурного блока:

 t1 = loadTexture("pY.raw", 512, 512);
t2 = loadTexture("pZ.raw", 512, 512);

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, t2);
glEnable(GL_TEXTURE_2D);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, t1);
glEnable(GL_TEXTURE_2D);
  

И вот единая настройка:
glUseProgram (программа);

 GLuint t1Location = glGetUniformLocation(program, "tex0");
GLuint t2Location = glGetUniformLocation(program, "tex1");

glUniform1i(t1Location, 0);
glUniform1i(t2Location, 1);
  

Проблема в том, что на выходе у программы получается только текстура hill, и я не знаю, как это исправить. Есть предложения?

Комментарии:

1. Опубликуйте свой текстурный модуль и единый установочный код.

2. Опубликовано в разделе вопросов ^^

3. И обе текстуры уже доступны в GLSL. Например, gl_FragColor = cloud; команда без if-условия выведет текстуру облака, в то время как gl_FragColor = hill; без if-условия будет выводить текстуру холма.

Ответ №1:

Вам не нужно выполнять никаких итераций в вашем шейдере. Пиксельный шейдер будет вызываться один раз для каждого пикселя в вашем объекте. Вместо этого используйте gl_TexCoord[0] для получения текущих координат текстуры. Ваш код должен выглядеть примерно так:

 uniform sampler2D tex0;
uniform sampler2D tex1;

void main()
{
    vec4 cloud = texture2D(tex0, gl_TexCoord[0].st);
    vec4 hill = texture2D(tex1, gl_TexCoord[0].st);

    if ( int(gl_TexCoord[0].x*512)%2 == 0)
        gl_FragColor =  cloud;
    else
        gl_FragColor =  hill;

    }
}
  

Это должно работать даже со старым opengl:

 #ifdef GL_ES
precision highp float;
#endif

uniform sampler2D tex0;
uniform sampler2D tex1;

void main(void)
{

    if((gl_FragCoord/32.0- vec4(ivec4(gl_FragCoord/32.0))).x<0.5)
        gl_FragColor = texture2D(tex0, gl_FragCoord.xy/512.0);
    else
        gl_FragColor = texture2D(tex1, gl_FragCoord.xy/512.0);
}
  

Вы можете попробовать это с WebGL по адресу:http://www.iquilezles.org/apps/shadertoy /

Комментарии:

1. Спасибо, я только что осознал этот момент. Тем не менее, я все еще получаю проблему: доступна только текстура hill. Я думаю, что предыдущий фрагмент шейдера для различения четных и нечетных координат не работает.

2. @snowball147 ты уверен, что твои шейдеры вообще работают? Вы проверяете ошибки компиляции? Работают ли какие-то тривиальные шейдеры?

3. да, шейдер работает. вот результат после применения предоставленного вами шейдера: скриншот . Интересно, что означает это условие: ` if((gl_FragCoord /32.0- vec4(ivec4 (gl_FragCoord / 32.0))).x<0.5)` и как я могу изменить это так, чтобы текстуры просто чередовались между нечетными и четными пикселями из разных текстур?

4. обновление, шейдер работает корректно, изменив условие if на if((gl_FragCoord/2.0 - vec4(ivec4(gl_FragCoord/2.0))).x<0.5) . Из-за моего плохого понимания в GLSL я не знаю, что означает это условие и почему gl_FragCoord.xy должен быть разделен на 512, но спасибо, я собираюсь узнать больше о gl_FragCoord. Спасибо, @Banthar! 🙂

5. (gl_FragCoord/2.0 - vec4(ivec4(gl_FragCoord/2.0))).x это просто другой способ сделать по модулю. Вы можете сделать то же самое с if(mod(gl_FragCoord.x,2.0)<1.0) . gl_FragCoord.xy разделяется на 512.0 потому texture2D что использует значения от 0.0 до 1.0 , а не фактические размеры текстуры. В зависимости от того, что вы делаете, вы можете захотеть заменить gl_FragCoord на gl_TexCoord[0] , вы увидите разницу при перемещении вашего объекта.