0
votes

I have this basic shader, though I ran into some trouble which really bugs me!

I'm applying the texture using the fragment shader though however I move or rotate the camera, the texture on the face will always be facing the camera (I've added a GIF image as an example).

gif

So as you can see on the image above the texture keeps facing the camera, also if I move away of closer it will keep its scale.

I'm trying to achive that I can move around and the texture will keep it's position, rotation and scale according to the face and vertices, and not according to the camera as it is doing now.

Here is the desired result, though using the deprecated methods glVertex2f and the glTexCoord2f which is the same result I want though through shaders, I guess my problem is calculating the correct UV coordinates on the texture.

desired result
(source: gyazo.com)

Important I want to achive this using shaders so I can make/calculate changes into the colors of the actual texture. (For instance make it a black and white).

Here is my current Vertex & Fragment Shader Code.

Vertex Shader Code

void main() {
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

Fragment Shader Code

uniform vec2 size;
uniform sampler2D texture;

void main() {
    gl_FragColor = texture2D(texture, gl_FragCoord.xy / size.xy);
}

The uniform vec2 size; within the fragment shader, is the width and height of the face itself where the texture is applied on. The uniform sampler2D texture; is of course the grass texture itself.

1

1 Answers

2
votes

It does that because that is whay you've programmed. You derive the texcoords directly from the coordinates of the fragment. If you want the texture to "stick to the geometry", you need to define a mapping between your geometry and texture space. Usually, this is done through a 2D texture coordinate attribute per vertex - just as the fixed function pipeline did with the glTexCoord2f() you mentioned.

In your specific case, (assuming the host program still specifies texcoords the same deprectaed way you are using for vertex positions with gl_Vertex), you could let the GL interpolate the texcoords per fragment and use these to access the texture in the fragment shader:

Vertex Shader Code

varying vec2 vTexCoord;

void main() {
    vTexCoord = gl_MultiTexCoord0.st;
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

Fragment Shader Code

uniform sampler2D texture;
varying vec2 vTexCoord;

void main() {
    gl_FragColor = texture2D(texture, vTexCoord);
}

I would suggest to switch to generic vertex attributen, and more modern GLSL versions, though.