mirror of
https://github.com/luanti-org/luanti.git
synced 2025-07-02 16:38:41 +00:00
Use polygon offset to fix z-fighting for overlay tiles
This commit is contained in:
parent
dfd7628950
commit
5b14c03301
4 changed files with 49 additions and 23 deletions
|
@ -702,6 +702,16 @@ MapBlockMesh::MapBlockMesh(Client *client, MeshMakeData *data, v3s16 camera_offs
|
||||||
tex.MinFilter = video::ETMINF_NEAREST_MIPMAP_NEAREST;
|
tex.MinFilter = video::ETMINF_NEAREST_MIPMAP_NEAREST;
|
||||||
tex.MagFilter = video::ETMAGF_NEAREST;
|
tex.MagFilter = video::ETMAGF_NEAREST;
|
||||||
});
|
});
|
||||||
|
/*
|
||||||
|
* The second layer is for overlays, but uses the same vertex positions
|
||||||
|
* as the first, which quickly leads to z-fighting.
|
||||||
|
* To fix this we can offset the polygons in the direction of the camera.
|
||||||
|
* This only affects the depth buffer and leads to no visual gaps in geometry.
|
||||||
|
*/
|
||||||
|
if (layer == 1) {
|
||||||
|
material.PolygonOffsetSlopeScale = -1;
|
||||||
|
material.PolygonOffsetDepthBias = -1;
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
material.MaterialType = m_shdrsrc->getShaderInfo(
|
material.MaterialType = m_shdrsrc->getShaderInfo(
|
||||||
|
|
|
@ -50,6 +50,11 @@ struct FrameSpec
|
||||||
video::ITexture *texture = nullptr;
|
video::ITexture *texture = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We have two tile layers:
|
||||||
|
* layer 0 = base
|
||||||
|
* layer 1 = overlay
|
||||||
|
*/
|
||||||
#define MAX_TILE_LAYERS 2
|
#define MAX_TILE_LAYERS 2
|
||||||
|
|
||||||
//! Defines a layer of a tile.
|
//! Defines a layer of a tile.
|
||||||
|
|
|
@ -27,6 +27,18 @@
|
||||||
#define MIN_EXTRUSION_MESH_RESOLUTION 16
|
#define MIN_EXTRUSION_MESH_RESOLUTION 16
|
||||||
#define MAX_EXTRUSION_MESH_RESOLUTION 512
|
#define MAX_EXTRUSION_MESH_RESOLUTION 512
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Applies overlays, textures and optionally materials to the given mesh and
|
||||||
|
* extracts tile colors for colorization.
|
||||||
|
* \param mattype overrides the buffer's material type, but can also
|
||||||
|
* be NULL to leave the original material.
|
||||||
|
* \param colors returns the colors of the mesh buffers in the mesh.
|
||||||
|
*/
|
||||||
|
static void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f,
|
||||||
|
bool set_material, const video::E_MATERIAL_TYPE *mattype,
|
||||||
|
std::vector<ItemPartColor> *colors, bool apply_scale = false);
|
||||||
|
|
||||||
|
|
||||||
static scene::IMesh *createExtrusionMesh(int resolution_x, int resolution_y)
|
static scene::IMesh *createExtrusionMesh(int resolution_x, int resolution_y)
|
||||||
{
|
{
|
||||||
const f32 r = 0.5;
|
const f32 r = 0.5;
|
||||||
|
@ -317,25 +329,32 @@ static scene::SMesh *createSpecialNodeMesh(Client *client, MapNode n,
|
||||||
|
|
||||||
colors->clear();
|
colors->clear();
|
||||||
scene::SMesh *mesh = new scene::SMesh();
|
scene::SMesh *mesh = new scene::SMesh();
|
||||||
for (auto &prebuffers : collector.prebuffers)
|
for (int layer = 0; layer < MAX_TILE_LAYERS; layer++) {
|
||||||
|
auto &prebuffers = collector.prebuffers[layer];
|
||||||
for (PreMeshBuffer &p : prebuffers) {
|
for (PreMeshBuffer &p : prebuffers) {
|
||||||
if (p.layer.material_flags & MATERIAL_FLAG_ANIMATION) {
|
if (p.layer.material_flags & MATERIAL_FLAG_ANIMATION) {
|
||||||
const FrameSpec &frame = (*p.layer.frames)[0];
|
const FrameSpec &frame = (*p.layer.frames)[0];
|
||||||
p.layer.texture = frame.texture;
|
p.layer.texture = frame.texture;
|
||||||
}
|
}
|
||||||
for (video::S3DVertex &v : p.vertices) {
|
for (video::S3DVertex &v : p.vertices)
|
||||||
v.Color.setAlpha(255);
|
v.Color.setAlpha(255);
|
||||||
}
|
|
||||||
scene::SMeshBuffer *buf = new scene::SMeshBuffer();
|
auto buf = make_irr<scene::SMeshBuffer>();
|
||||||
buf->Material.setTexture(0, p.layer.texture);
|
|
||||||
p.layer.applyMaterialOptions(buf->Material);
|
|
||||||
mesh->addMeshBuffer(buf);
|
|
||||||
buf->append(&p.vertices[0], p.vertices.size(),
|
buf->append(&p.vertices[0], p.vertices.size(),
|
||||||
&p.indices[0], p.indices.size());
|
&p.indices[0], p.indices.size());
|
||||||
buf->drop();
|
|
||||||
colors->push_back(
|
// Set up material
|
||||||
ItemPartColor(p.layer.has_color, p.layer.color));
|
buf->Material.setTexture(0, p.layer.texture);
|
||||||
|
if (layer == 1) {
|
||||||
|
buf->Material.PolygonOffsetSlopeScale = -1;
|
||||||
|
buf->Material.PolygonOffsetDepthBias = -1;
|
||||||
|
}
|
||||||
|
p.layer.applyMaterialOptions(buf->Material);
|
||||||
|
|
||||||
|
mesh->addMeshBuffer(buf.get());
|
||||||
|
colors->emplace_back(p.layer.has_color, p.layer.color);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -688,13 +707,15 @@ scene::SMesh *getExtrudedMesh(ITextureSource *tsrc,
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f,
|
static void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f,
|
||||||
bool set_material, const video::E_MATERIAL_TYPE *mattype,
|
bool set_material, const video::E_MATERIAL_TYPE *mattype,
|
||||||
std::vector<ItemPartColor> *colors, bool apply_scale)
|
std::vector<ItemPartColor> *colors, bool apply_scale)
|
||||||
{
|
{
|
||||||
|
// FIXME: this function is weirdly inconsistent with what MapBlockMesh does.
|
||||||
|
// also set_material is never true
|
||||||
|
|
||||||
const u32 mc = mesh->getMeshBufferCount();
|
const u32 mc = mesh->getMeshBufferCount();
|
||||||
// Allocate colors for existing buffers
|
// Allocate colors for existing buffers
|
||||||
colors->clear();
|
|
||||||
colors->resize(mc);
|
colors->resize(mc);
|
||||||
|
|
||||||
for (u32 i = 0; i < mc; ++i) {
|
for (u32 i = 0; i < mc; ++i) {
|
||||||
|
@ -705,6 +726,7 @@ void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f,
|
||||||
if (layer->texture_id == 0)
|
if (layer->texture_id == 0)
|
||||||
continue;
|
continue;
|
||||||
if (layernum != 0) {
|
if (layernum != 0) {
|
||||||
|
// FIXME: why do this?
|
||||||
scene::IMeshBuffer *copy = cloneMeshBuffer(buf);
|
scene::IMeshBuffer *copy = cloneMeshBuffer(buf);
|
||||||
copy->getMaterial() = buf->getMaterial();
|
copy->getMaterial() = buf->getMaterial();
|
||||||
mesh->addMeshBuffer(copy);
|
mesh->addMeshBuffer(copy);
|
||||||
|
|
|
@ -143,14 +143,3 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result);
|
||||||
|
|
||||||
scene::SMesh *getExtrudedMesh(ITextureSource *tsrc, const std::string &imagename,
|
scene::SMesh *getExtrudedMesh(ITextureSource *tsrc, const std::string &imagename,
|
||||||
const std::string &overlay_name);
|
const std::string &overlay_name);
|
||||||
|
|
||||||
/*!
|
|
||||||
* Applies overlays, textures and optionally materials to the given mesh and
|
|
||||||
* extracts tile colors for colorization.
|
|
||||||
* \param mattype overrides the buffer's material type, but can also
|
|
||||||
* be NULL to leave the original material.
|
|
||||||
* \param colors returns the colors of the mesh buffers in the mesh.
|
|
||||||
*/
|
|
||||||
void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f,
|
|
||||||
bool set_material, const video::E_MATERIAL_TYPE *mattype,
|
|
||||||
std::vector<ItemPartColor> *colors, bool apply_scale = false);
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue