Skip to content

Commit 5b14c03

Browse files
committed
Use polygon offset to fix z-fighting for overlay tiles
1 parent dfd7628 commit 5b14c03

File tree

4 files changed

+49
-23
lines changed

4 files changed

+49
-23
lines changed

src/client/mapblock_mesh.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,16 @@ MapBlockMesh::MapBlockMesh(Client *client, MeshMakeData *data, v3s16 camera_offs
702702
tex.MinFilter = video::ETMINF_NEAREST_MIPMAP_NEAREST;
703703
tex.MagFilter = video::ETMAGF_NEAREST;
704704
});
705+
/*
706+
* The second layer is for overlays, but uses the same vertex positions
707+
* as the first, which quickly leads to z-fighting.
708+
* To fix this we can offset the polygons in the direction of the camera.
709+
* This only affects the depth buffer and leads to no visual gaps in geometry.
710+
*/
711+
if (layer == 1) {
712+
material.PolygonOffsetSlopeScale = -1;
713+
material.PolygonOffsetDepthBias = -1;
714+
}
705715

706716
{
707717
material.MaterialType = m_shdrsrc->getShaderInfo(

src/client/tile.h

+5
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ struct FrameSpec
5050
video::ITexture *texture = nullptr;
5151
};
5252

53+
/**
54+
* We have two tile layers:
55+
* layer 0 = base
56+
* layer 1 = overlay
57+
*/
5358
#define MAX_TILE_LAYERS 2
5459

5560
//! Defines a layer of a tile.

src/client/wieldmesh.cpp

+34-12
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,18 @@
2727
#define MIN_EXTRUSION_MESH_RESOLUTION 16
2828
#define MAX_EXTRUSION_MESH_RESOLUTION 512
2929

30+
/*!
31+
* Applies overlays, textures and optionally materials to the given mesh and
32+
* extracts tile colors for colorization.
33+
* \param mattype overrides the buffer's material type, but can also
34+
* be NULL to leave the original material.
35+
* \param colors returns the colors of the mesh buffers in the mesh.
36+
*/
37+
static void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f,
38+
bool set_material, const video::E_MATERIAL_TYPE *mattype,
39+
std::vector<ItemPartColor> *colors, bool apply_scale = false);
40+
41+
3042
static scene::IMesh *createExtrusionMesh(int resolution_x, int resolution_y)
3143
{
3244
const f32 r = 0.5;
@@ -317,25 +329,32 @@ static scene::SMesh *createSpecialNodeMesh(Client *client, MapNode n,
317329

318330
colors->clear();
319331
scene::SMesh *mesh = new scene::SMesh();
320-
for (auto &prebuffers : collector.prebuffers)
332+
for (int layer = 0; layer < MAX_TILE_LAYERS; layer++) {
333+
auto &prebuffers = collector.prebuffers[layer];
321334
for (PreMeshBuffer &p : prebuffers) {
322335
if (p.layer.material_flags & MATERIAL_FLAG_ANIMATION) {
323336
const FrameSpec &frame = (*p.layer.frames)[0];
324337
p.layer.texture = frame.texture;
325338
}
326-
for (video::S3DVertex &v : p.vertices) {
339+
for (video::S3DVertex &v : p.vertices)
327340
v.Color.setAlpha(255);
328-
}
329-
scene::SMeshBuffer *buf = new scene::SMeshBuffer();
330-
buf->Material.setTexture(0, p.layer.texture);
331-
p.layer.applyMaterialOptions(buf->Material);
332-
mesh->addMeshBuffer(buf);
341+
342+
auto buf = make_irr<scene::SMeshBuffer>();
333343
buf->append(&p.vertices[0], p.vertices.size(),
334344
&p.indices[0], p.indices.size());
335-
buf->drop();
336-
colors->push_back(
337-
ItemPartColor(p.layer.has_color, p.layer.color));
345+
346+
// Set up material
347+
buf->Material.setTexture(0, p.layer.texture);
348+
if (layer == 1) {
349+
buf->Material.PolygonOffsetSlopeScale = -1;
350+
buf->Material.PolygonOffsetDepthBias = -1;
351+
}
352+
p.layer.applyMaterialOptions(buf->Material);
353+
354+
mesh->addMeshBuffer(buf.get());
355+
colors->emplace_back(p.layer.has_color, p.layer.color);
338356
}
357+
}
339358
return mesh;
340359
}
341360

@@ -688,13 +707,15 @@ scene::SMesh *getExtrudedMesh(ITextureSource *tsrc,
688707
return mesh;
689708
}
690709

691-
void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f,
710+
static void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f,
692711
bool set_material, const video::E_MATERIAL_TYPE *mattype,
693712
std::vector<ItemPartColor> *colors, bool apply_scale)
694713
{
714+
// FIXME: this function is weirdly inconsistent with what MapBlockMesh does.
715+
// also set_material is never true
716+
695717
const u32 mc = mesh->getMeshBufferCount();
696718
// Allocate colors for existing buffers
697-
colors->clear();
698719
colors->resize(mc);
699720

700721
for (u32 i = 0; i < mc; ++i) {
@@ -705,6 +726,7 @@ void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f,
705726
if (layer->texture_id == 0)
706727
continue;
707728
if (layernum != 0) {
729+
// FIXME: why do this?
708730
scene::IMeshBuffer *copy = cloneMeshBuffer(buf);
709731
copy->getMaterial() = buf->getMaterial();
710732
mesh->addMeshBuffer(copy);

src/client/wieldmesh.h

-11
Original file line numberDiff line numberDiff line change
@@ -143,14 +143,3 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result);
143143

144144
scene::SMesh *getExtrudedMesh(ITextureSource *tsrc, const std::string &imagename,
145145
const std::string &overlay_name);
146-
147-
/*!
148-
* Applies overlays, textures and optionally materials to the given mesh and
149-
* extracts tile colors for colorization.
150-
* \param mattype overrides the buffer's material type, but can also
151-
* be NULL to leave the original material.
152-
* \param colors returns the colors of the mesh buffers in the mesh.
153-
*/
154-
void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f,
155-
bool set_material, const video::E_MATERIAL_TYPE *mattype,
156-
std::vector<ItemPartColor> *colors, bool apply_scale = false);

0 commit comments

Comments
 (0)