Z-Fighting peace talks

Post a reply

This question is a means of preventing automated form submissions by spambots.
:D :) :( :o :shock: :? 8) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen:

BBCode is ON
[img] is ON
[flash] is OFF
[url] is ON
Smilies are ON

Topic review

Expand view Topic review: Z-Fighting peace talks

Re: Z-Fighting peace talks

by Gunter » Wed Nov 23, 2016 12:58 am

But you will not see much of it in FvF any more!

... er.. actually, I did find another spot I need to fix -- I hadn't adjusted "trains" which is another type of moving thing....

Re: Z-Fighting peace talks

by gulliver-trans » Tue Nov 22, 2016 9:35 am

Here's Z-fighting in e4m5 (Hell's Atrium):


Who's on top? Nobody knows.

This is in QuakeSpasm. Turns out it did NOT happen in DarkPlaces.

So yeah. Same thing as those BSP ammo boxes. 2 surfaces, overlapping. Diagonal lines. The whole nine yards.

Re: Z-Fighting peace talks

by teknoskillz » Tue Nov 22, 2016 2:20 am

I think I understand it now. I was trying to show Gull that door / wall that comes down on e1m2 that lets out the knights, as the lip sometimes would show some lines in it, but was not able to get it to show.

I did see the effect I was looking for there on e1m6 where a megahealth which is a BSP model is sharing the same max coordinate as a box of Rockets, also a BSP model:


Does this look like the same thing?

Re: Z-Fighting peace talks

by Gunter » Sun Nov 20, 2016 6:39 pm

Oh, I would assume Darkplaces does fix it. Darkplaces really rejiggered a lot of visual things.

Try some non-Darkpalces (and non-software) engine and look at:

1. the lift in the water leading to the exit on e2m2

2. the door that slides open at the start of e4m5

Those are a couple of the worst examples. They are quite ugly. It happens because the derpy mappers caused the surface of an entity to be perfectly aligned with one of the map surfaces, and 3D versions of Quake can't figure out which one it wants to show you....

Re: Z-Fighting peace talks

by teknoskillz » Sat Nov 19, 2016 4:29 pm

Heh I'll be danged if I can figure out what is trying to be fixed here...unless in Darkplaces the eng fixes it?

Z-Fighting peace talks

by Gunter » Sat Nov 12, 2016 10:05 pm

Last edit: 11=13=2016
1:03 PM -- altered the logic to catch "door lifts."
3:06 PM -- added check for vertical secret doors

So here are the fixes I am currently implementing to eliminate z-fighting in Quake, mod-side. I seem to be constantly tweaking stuff to try and refine it, to achieve no z-fighting but also no negative side-effects (or as few as possible).

I suppose the correct way to do this would be addressing each instance individually, but apparently there are a LOT of them. This guy on Quakeone says he addressed over 60 instances: http://quakeone.com/forums/quake-mod-re ... -beta.html

Of course, altering each map itself is a very non-ideal solution, and rather difficult to implement as well.

I guess I should point out that I'm only looking at DM mode -- there are many many more doors and weird things in Single-Player mode, which is probably where the vast majority of those 60+ instances are. Trying to make some logic that would address all those without lots of side-effects would be... impossible, heh. They certainly could be fixed easily in QuakeC, but it would require the "correct" method of altering each instance specifically. But I'm not really attempting to fix single-player Quake -- DM mode is all you see online.... Though maybe if I had the full list of all the z-fighting locations, I'd look at addressing them.... It wouldn't really be that difficult; just a couple lines of code for each instance. Hm, I wonder if that guy who fixed all the maps has a list of all the locations he fixed? heh

Ok, so first off....


Code: Select all

void () func_plat =
   // anti-z-fighting hack
   // plats are elevators, so just make sure they are above floor level.
   self.origin_z = self.origin_z + 0.15;

This one is simple -- just make sure an elevator is not flush with the floor. This fixes the lift leading to the top level of e2m3. I don't know if there are any other places like that.... Maybe this it unnecessary, and the only place I need to adjust a plat is on e2m3? On the other hand, this should be a completely safe fix. I can't foresee any side effects resulting from moving the base origin of all plats 0.15 units upward. Now, WinQuake (or old DOS Quake) would actually have that lift become non-visible when it's at floor level... GLquake, of course, causes the ugly z-fighting. If I were looking to emulate software Quake, I should move plats down instead of up, but I think it looks better with the lift being visible from the start instead of just springing out of the floor.


Code: Select all

void () func_wall =


   setmodel(self, self.model);
	//anti-z-fighting hack
	// wall entities shall be moved perpendicular to their wide side
	// these are often "exit" signs lined up with nearby walls
	// +x is good on e2m2, but -x is good on e2m3 & e2m5
	if (self.size_x > self.size_y) self.origin_y = self.origin_y - 0.15;
	else if (self.size_x < self.size_y) self.origin_x = self.origin_x - 0.15;};
Like it says.... these are the "exit" walls which sometimes have problems like at the end of e2m2, e2m3, and e2m5. Also some scattered random things that mostly don't need to be aligned with walls. This fix must be after the setmodel(), because it needs to read the size. Shifting the wall forward or back will fix the z-fighting for exit walls.... Unfortunately there is no way to determine which is the front side of the wall, so I just pick a direction and move it that way (-x is good for 2/3 cases where I see this -- and these may be the only walls that even need adjusted?). There is also a func_wall in the corner of e3m4 in DM mode, where there's a button in SP mode.... That should not be moved, but it is the same width as length, so it has no "wide side" so it won't be moved here. Otherwise, this fix should be very safe.


Code: Select all

void () fd_secret_use =


   // anti-z-fighting hack
   // if it's a vertical secret door, move it less far down
   if (self.spawnflags & SECRET_1ST_DOWN) self.dest1 = self.dest1 + (v_up * 0.15);
   // slide it a tad less far into the wall to avoid potential z-fighting
   self.dest2 = (v_forward * -0.15) + (self.dest1) + (v_forward * (self.t_length));
   //self.dest2 = (self.dest1) + (v_forward * (self.t_length));

   SUB_CalcMove(self.dest1, self.speed, fd_secret_move1);
   sound(self, CHAN_VOICE, self.noise2, ATTN_NORM, ATTN_NORM);
Secret doors move in 2 directions (moving in/out, then sliding sideways) so they have no problems with z-fighting on their long side, but they can settle into position so that their thin side is flush with a wall (like the secret at the start of e2m3). I have them move LESS far into the wall, because I think it looks better than to have the door just vanish completely into the wall.... Again, Software Quake would have it be invisible. This is a FAIRLY safe fix -- I just found that in e4m4, at the secret in the dark hall where the knights come out, then you go on the lift to the Quad secret, there's a secret door there (which normally causes z-fighting). With me now moving it not completely into the wall, if you are under it on the lift in the corner, it will hit you in the head and block the lift, heh. So, being that there is a minor negative impact, I may change to moving the secret doors into the wall completely.... I just really prefer the aesthetics of the door not just vanishing into the wall oddly. Also I added a check for vertical moving secret doors, for things like the Pent secret on e2m1, which need their height adjusted.

Regular doors get much more complex....
Here's my current (often changing) code:


Code: Select all

void () func_door =


   if (!(self.dmg)) {
      self.dmg = 2;
   // anti-z-fighting hack
   // these are vertical moving doors/bars and (sometimes secret) lifts 
	if (self.movedir == '0 0 -1' || self.movedir == '0 0 1') {
	// if they move upward and are wider than 32 on both sides they are most likely lifts. 
	// need to alter origin completely; don't want them making strange moves while ridden.
	// sink them into the floor a tad in case they are on floor plane (some secret lifts)
	// many also flagged to "start open" so let's try this to catch lifts and similar:
		if ((self.size_x >= 32 && self.size_y >= 32) || self.spawnflags & DOOR_START_OPEN) { 
			self.origin_z = self.origin_z - 0.15; 
			// the following will almost never be needed for lifts, but there is a tiny 
			// place on back corner of fat water lift on e2m6.... Meh. 
			if (self.size_x > self.size_y) self.origin_y = self.origin_y - 0.15;
			else if (self.size_x < self.size_y) self.origin_x = self.origin_x - 0.15;	
	// for other vert doors, only move a tad perpendicular to wide side, so as to not 
	// increase the gap they are blocking which can allow players to slip through bars.
	// let's do this only if it's a slow door. regular speed doors may flicker
	// during move, but they won't be moving long. handle them like non-vert doors (safer).
	// if it's not a lift & it moves downward, forget it. sinking in floor = no z-fighting
		else if (self.speed * 3 < self.size_z && self.movedir_z == 1) {
			if (self.size_x > self.size_y) self.origin_y = self.origin_y - 0.15;
			// -x hides exit bars in wall e2m7
			else if (self.size_x < self.size_y) self.origin_x = self.origin_x - 0.15;	
		setorigin(self, self.origin);
   self.pos1 = self.origin;

The first part fixes the lift (which is actually a door) on e1m1 where you have to shoot the earth button. It will sink all other door lifts a tiny amount as well, in case there are any other places like this (there's one on e2m3 by the mega H secret). That part is pretty safe -- can't really see any side effects from moving all lifts down a tiny amount, other than, in some places (e2m2 on the right after first entering the castle), making a teeny tiny crack in the floor that you really have to look hard to see.

THEN I have to start looking at other vertical-moving doors.... Of which there are a wide variety. One bad one is the bars at the exit of e2m7. This code catches it because it's so slow moving (upward). It's tricky changing the origin of doors, because that can cause cracks in the wall, which can be more noticeable... so that's why I'm trying to narrow down what I move here (since this fix can be less "safe"). Normal door speed is 100 -- those bars move at 30. I compare the speed * 3 to the height of the door to determine if it's going to take a long time to move (giving lots of time to see potential ugly z-fighting).

For all doors not adjusted there, we go to:


Code: Select all

void () door_hit_top =
   // anti-z-fighting hack. just slightly alter door's position after the end of 
   // its move to be sure it's not perfectly aligned with floor or wall.
   // lifts & slow vert doors doors don't need this - they are completely repositioned. 
   // but we will do this for non-lift, non-slow vert doors, if they move upward
   if ( (self.movedir_z != -1 && self.movedir_z != 1) || ( (self.size_x < 32 || self.size_y < 32) && self.speed * 3 >= self.size_z && self.movedir_z == 1 ) ) {
	// move them perpendicular to wide side, and down a bit for ones that slide along floor
	   if (self.size_x > self.size_y) {
		   // -x is good for end doors on e1m2
		   setorigin(self, self.origin - '0 0.15 0.15');
		else if (self.size_x < self.size_y) {
			// -y good for knight door at start of e4m5
			setorigin(self, self.origin - '0.15 0 0.15');
		// if they dont have a wide side they are probably 
		// a flat side-sliding floor door that does't need any adjustment

So I check for the doors I haven't already adjusted, and simply move them slightly AFTER they have reached their normal end position. The downward adjustment gets rid of the top of the gate you can see in the room behind the big spike & zombie pit in e1m3.

Waiting to move the door until after it's moved (usually into a wall) is pretty safe. But you will still see flickering WHILE the door is moving, if it has z issues. But yeah, as long as they aren't big slow doors, the flickering won't last very long.

One issue that could possibly arise is that, since the door will be moving back toward it's original position (door_hit_top just means it's fully "open"), there will be some sideways movement since I altered it, and if you are pressing against the long side of a door as it's sliding closed, you could get hurt and trigger the "door blocked" stuff....

Previously I was altering the open position of the door from the start, which looked much nicer (no flickering), but due to there being the tiny forward movement, when a player was pressing against a door as it opened, the above situation would happen.... It's much less likely anyone is pressing against a door that is closing, so I don't think this will be an issue. If it does turn out to be an issue, I can just reposition the door prior to closing it. Also, this adjustment could cause issues if it's actually a "door lift" with soemthing riding on it... so hopefully I've narrowed it down to not adjust those.

But I think I've pretty much got things working well with only very minor side-effects. In theory. Since I have no idea where all 60+ instances of z-fighting occur, I just have to try to use logic that SHOULD catch them all, and hopefully not cause unwanted effects for everything else.

If you see any entities z-fighting, or acting in a strange manner, or possessing crack, report it to your local FvF authority immediately!