I am trying to render vegetation without any visual flaws. So far I have one important problem.
I have billboard trees and canopy bushes which use vegetation textures with alpha values. That is the transparent part of the textures have value of 0 for alpha.
I do my rendering as follows :
alpha func = greater
alpha ref = 0.1f
tex env = replace
blending = off
My problem is that I see black halos around the tree texture. I suspect it has something to do with filtering since the width of the black halo changes as I drive in my database. Here is how it looks :
What do you think ?
Thanks in advance,
I assume that your tree texture is on a black background in the texture? In which case, you’re seeing the edge texels (the ones with alpha values of 1.0) in the midst of being interpolated with the neighbouring black texels (the ones with alpha values of 0.0), before the alpha test puts a sudden stop to it.
The solution is to either make the background of your tree texture the same colour as the tree edge, or raise your alpha test value until it looks ok (0.5 would give half black/half green colour at the edge, which doesn’t look as bad as black)
create your own mipmaps in a paint problem, problem is cause by mipmaps
eg alpha values alpha ref = 0.1f
say u have 2 pixels alpha values of 0.0 and 1.0 now in the lowest mipmap level only the second will be drawn, yet when u goto the next mipmap level (average filter)
u get (0.0+1.0)/2 = 0.5alpha thus this pixel will get drawn even though it contains half black now
Manually manipulating MIP maps won’t help entirely knackered is right.
MIP maps make this worse under minification but you always have filtering even with a magnification filter.
There are other pretty obvious approaches to this for example when you generate your texture make the RGB or the area surrounding the leaves match the leaf color.
A more complex one and it really applies to blended trees is to premultiply the RGB in the image by the alpha and use a different blend equation where you just add the RGB but this depends on teh content and circumstances.
The simplest solution is to flood fill the tree’s black area with a green tone that will try to hide the effect or perform a morphological image processing operation on the RGB components to bleed RGB channel colors under solid alpha into the RGB areas under zero alpha (this is the highest quality approach).
read this thread for a thorough discussion of the problem and possible solutions:
to bleed RGB channel colors under solid alpha into the RGB areas under zero alpha (this is the highest quality approach).
cheers i hadnt actually thought of that (just doing the floodfill with green until now), it wouldnt be to hard to implement as well
btw heres a method i use to keep the edges nice and smooth (ie alpha test either passes or fails)
float depth_val = clamp( 0.5 - diffuse_color.w, 0.0,1.0 );
gl_FragDepth = gl_FragCoord.z + depth_val;
You either fill all the black area with green; i e, smooth the edge colors out into the cut-out areas; or you turn to pre-multiplied alpha.
To draw with pre-multiplied alpha under OpenGL, you enable blending, and set the blend mode to GL_ONE, GL_ONE_MINUS_SRC_ALPHA.
If blending is a problem, then you can draw one pass with alpha ref value = 1.0, and alpha func greater or equal, without blending; then draw the second pass with alpha func less-than, and blending turned on. Whatever small issue you’ll have around the fringes will typically disappear in the noise with this method, although it means two passes over your geometry. Vegetation is typically fill-bound, not geometry bound, anyway.
knackered, zed, dorbie, OneSadCookie, jwatte, thanks for the hints. They helped me a lot.
Alpha blending wasn’t an option for me for this specific case, I couldn’t test hints related to alpha blending.
Floodfilling definitely improves the quality. I have also tried Floodfilling+bleeding but in my case ( where I have only a limited number of colors at the edges - a simple canopy tree texture ) there were no significant visual improvement with bleeding. And since bleeding requires manual working of the textures, I will stick with floodfliing method which produces acceptable results.