zBuffer and Transparency

Neverday

Member
I'm having a problem with transparent textures in 3d mode. With d3d_set_zwriteenable set to true, transparent textures blot out textures below them, as if they were opaque. Setting it to false fixes the issue, but also prevents the model from clipping other models.

Most results from google suggest using draw_set_alpha_test, but it doesn't work well when a texture has partially transparent pixels.

My objects are ordered in standard isometric fashion. depth=-y (or rather since the view is angled 45 degrees, depth=x-y)

The camera is a separate object that has a depth of 1000000. Each billboard in my game has a draw event that looks something like this:
Code:
depth=x-y
d3d_set_culling(true)
d3d_set_hidden(true)                            
d3d_set_zwriteenable(true)
<draw>
 d3d_set_zwriteenable(false)
d3d_set_hidden(false)
d3d_set_culling(false)
tl;dr How do I fix this? Images below.

Plane cutting the player billboard in half


Player billboard cutting the plane in half.
(The player sprite cutoff at the bottom is normal and expected in this image)


Plane blotting out other billboards


Another angle. The plane is parallel with the ground (raised up a few z units), while the player is (normally) angled towards the camera.
(The player sprite cutoff at the bottom is normal and expected in this image)


Working almost as intended, with draw alpha test enabled, but you can notice the partially transparent pixels still blotting out the billboard underneath. (The player sprite cutoff at the bottom is normal and expected in this image)
 
as long as you draw things in order, from farthest from the camera, to nearest to the camera, you shouldn't need to use the zbuffer at all.

if you want to use alpha testing, you can try different reference values and you might get better results.
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
You probably want to use draw_set_alpha_test rather than zwriteenable. That is designed to solve your exact problem.
 

Neverday

Member
as long as you draw things in order, from farthest from the camera, to nearest to the camera, you shouldn't need to use the zbuffer at all.

if you want to use alpha testing, you can try different reference values and you might get better results.
But I do want to use the zBuffer, because there are some instances where I want the primitives to clip through each other. Unless there is a way to have them clip without it.

You probably want to use draw_set_alpha_test rather than zwriteenable. That is designed to solve your exact problem.
draw_set_alpha_test doesn't work. Partially transparent pixels still blot out things behind them.
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
There's also draw_set_alpha_test_ref_value for setting the "cutoff" range, but on objects with wide gradient-y objects as shown things will not work well.

Altering drawing order (so that the less-gradient-y grass is drawn after the circular blob) could help. If not, there are some shaders that could be adapted - people most commonly get this exact rendering issue (which by default occurs on any "raw" API) when trying to model trees with lots of overlapping semi-transparent branches.

As a more radical workaround, could render the game in several passes (using surfaces) - first render all auras and other "background" effects, and then render characters and geometry on top. This way you will not have to worry about the two clipping through each other.
 

icuurd12b42

TMC Founder
GMC Elder
just use the old method of drawing the thing in the right order... if your white ball appears over top of everything, make sure it draws last. if it needs to be between trees then you'll need to set the depth of everything according to the distance to the camera...
 
Top