Search code examples
openglglslshadervertex-shader

GLSL offsetting multitexture


How can I do something like this in GLSL shaders?

vec2 attribute texture_sky;
vec2 attribute texture_floor;

if(texture_sky) gl_position = position+Xoffset;
else gl_position = position; 

I want to move one texture over the other. Is it possible to do with the vertex shaders?


Solution

  • What I type up there is a pseudo code: not the actual code. More explanation; Let's say i have two textures(2 images bind as textures) overlap each other. I want to display one texture with X+0.5 displacement while the other remain constant. The problem I am facing is distinguishing two textures in the Shader code.

    That is not something you can do using a vertex shader by itself.

    You might apply an offset to the texture coordinates in a vertex shader, but you certainly would not change the vertex position. The whole idea of multi-texturing is to apply multiple textures at once, avoiding the need to draw two different copies of your polygon.

    Before hardware had the capability of sampling multiple textures in a single pass (Riva TNT), you actually did have to draw each polygon multiple times and blend the results in order to apply multiple textures. These days you just use a fragment shader and call it a day because OpenGL 3.0 requires all hardware support a minimum of 16 simultaneous textures.

    Very roughly, the psuedo-code would look like this:

      Vertex Shader:

    #version 110
    
    // Input texture coordinates (from vertex buffer)
    attribute vec2 texture_sky;
    attribute vec2 texture_floor;
    
    // Output texture coordinates (to fragment shader)
    varying vec2 sky_tc;
    varying vec2 floor_tc;
    
    // Your offset
    uniform vec2 Xoffset;
    
    void main (void) {
      sky_tc   = texture_sky + Xoffset;
      floor_tc = texture_floor;
    
      gl_Position = ...;
    }
    

      Fragment Shader:

    #version 110
    
    // Input texture coordinates (from vertex shader)
    varying vec2 sky_tc;
    varying vec2 floor_tc;
    
    // Samplers
    uniform sampler2D sky_tex;
    uniform sampler2D floor_tex;
    
    void main (void) {
      vec4 sky   = texture2D (sky_tex,   sky_tc);
      vec4 floor = texture2D (floor_tex, floor_tc);
    
      //
      // You have to blend these, so pick one of the following...
      //
    
      // Additive Blending (GL_ONE, GL_ONE):
      gl_FragColor = sky + floor;
    
      // or
    
      // Alpha Blending (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA):
      gl_FragColor = mix (sky, floor, sky.a);
    }