Texture edges are moving when camera is moved - c++

The textures look good as long as the camera remains in a fixed position and rotation. However, when the camera is moving or rotating, (partial) lines appear between textures. I think it has to do something with subpixel correction. The texel is switching between the previous and the next one.
For my textures I use:
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
The same problem appears when using GL_NEAREST.
The fragment shader uses simple texture lookups:
color = texture( textureID, UV );
Or maybe this is an aliasing problem?
Edit - image
Edit - UV image: same problem
Edit Normals as colors
It looks like the depth is not sorted well.
I am using perspective projection.

Related

Texture Aliasing problem while rendering large chunks: OpenGL

Texture rendering is good without any texture error when the world size is small, but when it increased to some extend then it shows texture error. tried several texture mapping techniques but none helped(or may be I am doing it wrong)
The issue is similar with shadow acne but it not shadow acne(That i am sure), as I haven't implemented any shadow mapping yet.
Don't know how to solve this one, any help would be appreciated(or what i am doing wrong).
(Attaching the shader code for reference)
out vec4 FragColor;
in vec2 ChunkTexCoords;
uniform sampler2D sampler;
void main() {
FragColor = texture(sampler, ChunkTexCoords);
if(FragColor.a == 0) discard;
}
Texture parameters
glTexParameteri(
GL_TEXTURE_2D,
GL_TEXTURE_WRAP_S,
GL_CLAMP_TO_EDGE
);
glTexParameteri(
GL_TEXTURE_2D,
GL_TEXTURE_WRAP_T,
GL_CLAMP_TO_EDGE
);
glTexParameteri(
GL_TEXTURE_2D,
GL_TEXTURE_MIN_FILTER,
GL_NEAREST
);
glTexParameteri(
GL_TEXTURE_2D,
GL_TEXTURE_MAG_FILTER,
GL_NEAREST
);
Your texture minification filter is nearest neighbor box sampling. As soon as the sampling frequency falls below half the highest spatial frequency in your texture (the so called Nyquist frequency) you're going to get sampling aliasing artifacts.
The solution: Create complete set of mipmap levels that are properly low pass filtered.

Implementing GL_REPEAT on shader

I'm trying to implement GL_REPEAT on glsl. I wrote something using the mod function but there's a problem where the two textures combine. Could you explain why it doesn't work right?
in main:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
my shader code looks like this:
in vec2 TextureCoord;
float yCoord = mod(TextureCoord.y + 0.5, 1.0);
emission = texture(material.emission,vec2(TextureCoord.x, yCoord)).rgb;
//result
vec3 result = emission;
FragColor = vec4(result, 1.0f);
The wrap mode is honored during texture filtering. You set the GL_LINEAR filter mode, hence it will always use a 2x2 texel footprint. If that footprint happens to be at the border, the selected wrap mode will apply to selecting each individual texel. In your case, if you get near the border, you told it to filter into the textrue border color, which a filter with GL_REPEAT wrap mode never would have done, it would have used the texel data from the opposing border instead.
So if you want to re-implement that manually in the shader, you must also implement the texel selection and the filtering itself. Since you also use mipmapping, doing so will be quite complex, and slow.

Texture getting pixelated instead of blurry

I have created a simple OpenGL application.
When zooming into a textured quad, the texture becomes pixelated instead of blurry. I would guess that is due to missing mipmaps?
I create my texture like this:
glGenTextures(1, &mTexture);
glBindTexture(GL_TEXTURE_2D, mTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
And I update it from a PBO like this:
glBindTexture(GL_TEXTURE_2D, mTexture);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, mPboIds[mPboIndex]);
glTexSubImage2D(
GL_TEXTURE_2D,
0, 0, 0,
frame->GetWidth(),
frame->GetHeight(),
GL_RGB,
GL_UNSIGNED_BYTE,
0);
I thought that GL_TEXTURE_MAG_FILTER and GL_TEXTURE_MIN_FILTER would tell OpenGL to generate the mipmaps. Ain't that the case?
How can I enable mipmap generation for my texture?
The magnification filter is used when you increase the zoom on a texture, and can have two values:
GL_NEAREST - Returns the value of the texture element that is nearest (in Manhattan distance) to the specified texture coordinates.
GL_LINEAR - Returns the weighted average of the texture elements that are closest to the specified texture coordinates. These can include items wrapped or repeated from other parts of a texture, depending on the values of GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T, and on the exact mapping.
In your case, you are use the wrong magnification filter. It must be GL_LINEAR to minimize the pixelated effect.
MipMaps, for the other hand is used when you want to decrease the zoom and want to get a smooth transition when the texture start to become too far away from the viewer. To get more information about MipMaps, you can look at glTexParameter manual pages, at section GL_TEXTURE_MIN_FILTER, and how to generate in glGenerateMipmap manual page.

OpenGL changing/reloading textures

glDeleteTextures(total, &Item::texture[0]);
glGenTextures(total, &Item::texture[0]);
Iteration for all images, total;
glBindTexture( GL_TEXTURE_2D, Item::texture[i] );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, t.width(), t.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, t.bits() );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
Tries to reload the textures, however it does not. Textures stay the same, unchanged. Any ideas how this could/should be handled? For clarity, I'm trying to reload a texture with a new one, preferably without changing the number of the texture (since there can be a lot of changes).
I'm working with Qt, C++. The code above is in a static function in a seperate GLwidget.
Any chance you're bound to the wrong rendering context, or no rendering context at all, when you're making these calls?

OpenGL - Copy texture from screen smaller than that screen

I'm trying to capture the screen to a texture with a lower resolution than the screen itself (to render back onto the screen and create a blur/bloom effect), and it doesn't work quite well. I understand mipmaps can be used to do this, but I just can't get the correct sequence of commands to work.
My current code:
width=1024;
height=1024;
glGenTextures(1, &texture);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, width, height, 0);
// code for rendering the screen back on goes here
You can't capture and downfilter in one go. You have to capture the full screen to a larger texture first, then mipmaps should be created if auto-create mipmaps are enabled, then you can render one using that texture again, makig sure you adjust the mipmap level suitably.
However, that will look ugly, as the auto mipmapgeneration usually uses a box filter.
What I'd do is to set up some FBOs (Frame Buffer Objects) and GLSL shaders instead. That gives you finer control over all steps:
create the original image in a texture
apply some nice gaussian low-pass filtering
blend the filtering with the original image to the frame buffer