Skip to content
Pipfold

The hard edges in the felt were not the gradient

· design · game

The felt in the tray gets a dark seam towards the edge. That is faked ambient occlusion: where floor and wall meet, less light arrives. Without that seam the floor does not lie inside the box, it is stuck onto it.

The seam was there. And with it a line that had no business being there.

Close-up of the left corner of the tray. At the foot of the wall a dark band lies on the felt, ending inwards at a straight, sharply drawn line parallel to the wall — beyond it the felt lightens again.
beforeThe dark band ends at an edge instead of fading out — exactly where the seam is meant to vanish. Both shots are the ash set with blue felt; the same line stands on the green maple, just less plainly.
The same corner after the change: the darkening at the wall fades evenly inwards, with no line and no visible transition.
afterOne surface across the whole tray, darkness from the distance to the edge. Nothing stops any more.

Round one: the kink in the gradient

There was a doubled edge on the left of the felt. The suspicion was obvious and turned out to be half right — it was two things on top of each other:

The seam’s gradient had a stop at 35 % and therefore a kink in its slope. The eye reads a kink as a line, even when the curve is continuous. On top of that the left cheek cast its shadow with a hard edge onto the felt. On the right there is no shadow — which is why only one edge stood there.

Fixed: the gradient is now computed as a power curve, the seam is weaker and quieter (0.32 → 0.17), shadow_blur from 2.2 to 3.4.

While we were at it, something else came up: GIER_QUER and GIER_HOCH were set to a few degrees. That was meant as “then it reads as a body” — but in frame the box stood askew with no visible reason. Set to 0. Head-on it is also narrower, the camera fit gets closer, and the flaps are noticeably larger. Portrait especially.

The line was still there.

Round two: in the wrong place

Both changes were right and both stay. Neither was the cause.

That is the most uncomfortable position when hunting a bug: you change something that genuinely needed improving, the picture genuinely gets better — and the fault remains. For two rounds that was read as “not enough yet” instead of “wrong place”.

Found by switching it off

Eventually the seam was turned off completely and rendered once. Without it, the felt was clean.

That shrank the pool of suspects from “everything that draws the felt” to “the seam” — and the cause turned out to sit in a line nobody had designed anything in:

BaseMaterial3D.texture_repeat defaults to on.

At the fading edge of the seam quad, the linear filter samples across the texture boundary back onto the first row — which is fully opaque. That produces a razor-sharp line parallel to the wall, exactly where the seam is meant to vanish.

No gradient helps against that. The gradient is right; at the edge it is simply not read to the end but started over. texture_repeat = false now applies to all four surfaces with alpha.

And then the seam was still the wrong way round

Measuring afterwards produced the second bug, and that one is more fundamental.

The seam consisted of four rotated quads, each with a gradient across the quad’s height. On the sides, full opacity sat not at the wall but at the inner end. And because a quad simply stops there, an edge stood exactly at that point in the middle of the felt.

A pixel section across the tray settled it. Measured from the wall inwards:

51  →  36  →  jump to 66

A seam gets darker towards the wall. This one got lighter. You do not see that in an image with wood grain, a vignette and three lights — you only see that “something is off”. In a row of three numbers you see it instantly.

The fix was to delete the problem

Instead of rotating four quads the right way round: one PlaneMesh across the whole tray, whose darkness is computed from the distance to the edge in world coordinates.

Nothing can be the wrong way round any more, the corners no longer double up, and there is no fading quad edge for a texture boundary to bleed into. The first bug in this entry is thereby gone structurally too, not merely switched off.

Rejected: rotating the four quads correctly. That would have been one line and would have worked. But it would have kept a construction with two right and six wrong ways to lay the same surface — and in which the corners are doubly covered because two quads overlap there. A construction in which the mistake cannot be stated any more is better than a corrected mistake.

Two rules out of one afternoon

If a change improves the picture and does not fix the fault, it was the wrong place. Not “not enough yet”. Two rounds went into not making that distinction.

And: switching an effect off is faster than understanding it. The felt was clean the moment the seam was gone — and that settled in ten seconds where to keep looking. Before that, the list of suspects was as long as the material definition.

← Devlog