Tips removing jagged edges and artifacts in frame

Started by
2 comments, last by Hashbrown 5 years, 9 months ago

I've found two particular visual issues in my renders and can't seem to find a way to solve it. Just to setup some context: floors, walls and roof all use diffuse, specular and normal maps. Oh and all three are tiled in the fragment shader. If you don't mind, take a look at the video below:

 

If you look at the roof area of the room, the pixels morph depending on the camera movement (light source is not moving):  looks horrible :( I've also noticed that the less I tile the roof, the less morphing and dots you see.

Also, if you check out the floor, you'll notice these strange artifacts around the lines of the floor. In fact, I'll show you a zoomed in picture (click for a larger view):

Screen_Shot_2018-07-15_at_6.03.43_PM.png

I'm no sure what to do. I've checked if my video card supports anti-aliasing:


function antialiasSamples () {
    const antialias = gl.getContextAttributes().antialias;
    return gl.getParameter(gl.SAMPLES);
}

...and it does, supports 8 samples. 

I also have a post processing pass, but I'm blitting the frame buffer and using a multisample texture (8 samples):


static toMultisample (input, output) {

    gl.bindFramebuffer(gl.READ_FRAMEBUFFER, input.buffer);
    gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, output.buffer);

    gl.blitFramebuffer(

        0, 0, input.width,  input.height, 
        0, 0, output.width, output.height, 
        gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT,  
        gl.NEAREST
    );

    gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
    gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
}

...and this definitely works, yet still I get the same jagged edges and artifacts in the floor.

I even added a feature to my textures which I honestly don't understand very well:


const ext = (
    gl.getExtension('EXT_texture_filter_anisotropic') ||
    gl.getExtension('MOZ_EXT_texture_filter_anisotropic') ||
    gl.getExtension('WEBKIT_EXT_texture_filter_anisotropic')
);

if (ext) {     
    const max = gl.getParameter(ext.MAX_TEXTURE_MAX_ANISOTROPY_EXT);
    gl.texParameterf(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY_EXT, max);
}

... still not much difference. Are there any tips some of you can offer me to remove these issues? Below I'll share some information about my rendering pipeline and even share my shaders. Thank you very much for reading.

Shader Pastebin Links: 
VERTEX SHADER
FRAGMENT SHADER

  • WebGL2
  • There's only one point light in the scene  at vec3(0.0, 3.0, 2.0)
  • Textures are tiled in the fragment shader (vec2 uvs = fract(uvcoords).xy * uvtile)
  • Mipmapping on for all textures

--------

By the way, I thought I'd share a video of a closer look at objects with normal mapping. So you all have an idea of how it's working so far. I'm moving the light left and right btw.

 

Advertisement

Anisotropic Filtering is what you are looking for: https://en.wikipedia.org/wiki/Anisotropic_filtering

Basically what is happening is that your mips are causing artifacts when blended with the original texture. The mips are scaled squarely but your view distorts them in a rectangle fashion.

So what Anisotropic Filtering will do is make rectangular mips that align with the view and allows for this kind of distortion. It is a very cheap trick to fix problems like this.

 

Personally in my games I don't even allow players to turn it off. Because it has very little impact on it's own. Instead I allow players to switch to shaders that use less textures as the Anisotropic Filtering's performance hit is directly proportional to the amount of textures used in a shader.

3 hours ago, Scouting Ninja said:

Anisotropic Filtering is what you are looking for: https://en.wikipedia.org/wiki/Anisotropic_filtering

Basically what is happening is that your mips are causing artifacts when blended with the original texture. The mips are scaled squarely but your view distorts them in a rectangle fashion.

So what Anisotropic Filtering will do is make rectangular mips that align with the view and allows for this kind of distortion. It is a very cheap trick to fix problems like this.

 

Personally in my games I don't even allow players to turn it off. Because it has very little impact on it's own. Instead I allow players to switch to shaders that use less textures as the Anisotropic Filtering's performance hit is directly proportional to the amount of textures used in a shader.

Scouting Ninja, thanks a lot! That was exactly what's going on. I had no idea what Anisotropic Filtering does, now I know. I had to set this first: 


minfilter = gl.LINEAR_MIPMAP_LINEAR;
magfilter = gl.LINEAR

and of course:


const max = gl.getParameter(ext.MAX_TEXTURE_MAX_ANISOTROPY_EXT);
gl.texParameterf(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY_EXT, max);

Now my frames are rendering very nicely:

Screen_Shot_2018-07-15_at_10.19.27_PM.pn

For those of you looking for more details on how to do this on WebGL or OpenGL ES, you check out this tutorial. It's a very brief but informative article.


Thanks again Ninja!

 

This topic is closed to new replies.

Advertisement