Filtering of textures:
In texture mapping, we using filtering to smooth textures when they are displayed larger or smaller than they are. The most commonly used filtering method is the bilinear filtering. Bilinear filtering user bilinear interpolation, which is like linear interpolation but in the 2D coordinate space. Bilinear filtering performs this interpolation on four nearest texels of the current pixel. In our engine, we default to bilinear filtering, but we can also change it to no filtering (or nearest neighbor) if we need. Below you can see the difference between bilinear filtering and no filtering.
With filtering:
Without:
As you can observe in the image without filtering, the edges on the numbers are more pronounced when compared to the image with filtering.
Mipmaps:
Mipmaps are images which are the same as the texture image but with lower resolution. The height and width of each mipmap levels is half the previous level with the lowest level being a 1×1 image. Mipmaps increase rendering speed and help in reducing aliasing. Aliasing occurs due to reconstruction of a sampled image at the wrong resolution. Mipmaps reduce this by having a level at particular resolutions which help in reducing aliasing effects when viewed at that resolution.
With Mipmaps:
Without:
Having no mipmaps keeps the texture at the same resolution as the original image which results in the output not getting filtered and smoothed. Below you can see all the mipmap levels for the car texture.
Adding more detail to geometry with alpha channel:
We can make images sharper by discarding fragments which have alpha value that is less than a cutoff. We perform this check in the fragment shader and use the discard() hlsl function to perform this function.
Simple Animations:
Since UVs are just array locations in the texture, we can change how we access the array to achieve some simple animations. One simple animation is to create a flowing water texture which is only a texture, but we are sampling the texture according to time which makes it look like its flowing.
float2(cos(i_textureData_local.x + g_elapsedSecondCount_simulationTime), i_textureData_local.y);
The above line shows the code to achieve the above effect. We can perform this in both vertex and fragment shader, but I am performing it in the vertex shader as it is less expensive than doing it in fragment shader. Also to achieve this, we need the image to tile.
Another effect is having the image rotate around an axis.