mirror of
https://github.com/minetest/minetest.git
synced 2024-11-29 19:13:44 +01:00
Add a setting to group transparency sorted triangles by buffer (#15115)
This commit is contained in:
parent
c175046d30
commit
df4e70b2c7
@ -1843,6 +1843,11 @@ video_driver (Video driver) enum ,opengl,opengl3,ogles2
|
|||||||
# Set to 0 to disable it entirely.
|
# Set to 0 to disable it entirely.
|
||||||
transparency_sorting_distance (Transparency Sorting Distance) int 16 0 128
|
transparency_sorting_distance (Transparency Sorting Distance) int 16 0 128
|
||||||
|
|
||||||
|
# Draw transparency sorted triangles grouped by their mesh buffers.
|
||||||
|
# This breaks transparency sorting between mesh buffers, but avoids situations
|
||||||
|
# where transparency sorting would be very slow otherwise.
|
||||||
|
transparency_sorting_group_by_buffers (Transparency Sorting Group by Buffers) bool true
|
||||||
|
|
||||||
# Radius of cloud area stated in number of 64 node cloud squares.
|
# Radius of cloud area stated in number of 64 node cloud squares.
|
||||||
# Values larger than 26 will start to produce sharp cutoffs at cloud area corners.
|
# Values larger than 26 will start to produce sharp cutoffs at cloud area corners.
|
||||||
cloud_radius (Cloud radius) int 12 1 62
|
cloud_radius (Cloud radius) int 12 1 62
|
||||||
|
@ -73,6 +73,7 @@ static const std::string ClientMap_settings[] = {
|
|||||||
"trilinear_filter",
|
"trilinear_filter",
|
||||||
"bilinear_filter",
|
"bilinear_filter",
|
||||||
"anisotropic_filter",
|
"anisotropic_filter",
|
||||||
|
"transparency_sorting_group_by_buffers",
|
||||||
"transparency_sorting_distance",
|
"transparency_sorting_distance",
|
||||||
"occlusion_culler",
|
"occlusion_culler",
|
||||||
"enable_raytraced_culling",
|
"enable_raytraced_culling",
|
||||||
@ -115,6 +116,9 @@ void ClientMap::onSettingChanged(std::string_view name, bool all)
|
|||||||
m_cache_bilinear_filter = g_settings->getBool("bilinear_filter");
|
m_cache_bilinear_filter = g_settings->getBool("bilinear_filter");
|
||||||
if (all || name == "anisotropic_filter")
|
if (all || name == "anisotropic_filter")
|
||||||
m_cache_anistropic_filter = g_settings->getBool("anisotropic_filter");
|
m_cache_anistropic_filter = g_settings->getBool("anisotropic_filter");
|
||||||
|
if (all || name == "transparency_sorting_group_by_buffers")
|
||||||
|
m_cache_transparency_sorting_group_by_buffers =
|
||||||
|
g_settings->getBool("transparency_sorting_group_by_buffers");
|
||||||
if (all || name == "transparency_sorting_distance")
|
if (all || name == "transparency_sorting_distance")
|
||||||
m_cache_transparency_sorting_distance = g_settings->getU16("transparency_sorting_distance");
|
m_cache_transparency_sorting_distance = g_settings->getU16("transparency_sorting_distance");
|
||||||
if (all || name == "occlusion_culler")
|
if (all || name == "occlusion_culler")
|
||||||
@ -1337,7 +1341,8 @@ void ClientMap::updateTransparentMeshBuffers()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (do_sort_block) {
|
if (do_sort_block) {
|
||||||
blockmesh->updateTransparentBuffers(m_camera_position, block->getPos());
|
blockmesh->updateTransparentBuffers(m_camera_position, block->getPos(),
|
||||||
|
m_cache_transparency_sorting_group_by_buffers);
|
||||||
++sorted_blocks;
|
++sorted_blocks;
|
||||||
} else {
|
} else {
|
||||||
blockmesh->consolidateTransparentBuffers();
|
blockmesh->consolidateTransparentBuffers();
|
||||||
|
@ -182,6 +182,7 @@ private:
|
|||||||
bool m_cache_trilinear_filter;
|
bool m_cache_trilinear_filter;
|
||||||
bool m_cache_bilinear_filter;
|
bool m_cache_bilinear_filter;
|
||||||
bool m_cache_anistropic_filter;
|
bool m_cache_anistropic_filter;
|
||||||
|
bool m_cache_transparency_sorting_group_by_buffers;
|
||||||
u16 m_cache_transparency_sorting_distance;
|
u16 m_cache_transparency_sorting_distance;
|
||||||
|
|
||||||
bool m_loops_occlusion_culler;
|
bool m_loops_occlusion_culler;
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
// Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
// Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||||
|
|
||||||
#include "mapblock_mesh.h"
|
#include "mapblock_mesh.h"
|
||||||
|
#include "CMeshBuffer.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "mapblock.h"
|
#include "mapblock.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
@ -818,7 +819,8 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapBlockMesh::updateTransparentBuffers(v3f camera_pos, v3s16 block_pos)
|
void MapBlockMesh::updateTransparentBuffers(v3f camera_pos, v3s16 block_pos,
|
||||||
|
bool group_by_buffers)
|
||||||
{
|
{
|
||||||
// nothing to do if the entire block is opaque
|
// nothing to do if the entire block is opaque
|
||||||
if (m_transparent_triangles.empty())
|
if (m_transparent_triangles.empty())
|
||||||
@ -834,24 +836,56 @@ void MapBlockMesh::updateTransparentBuffers(v3f camera_pos, v3s16 block_pos)
|
|||||||
m_transparent_buffers_consolidated = false;
|
m_transparent_buffers_consolidated = false;
|
||||||
m_transparent_buffers.clear();
|
m_transparent_buffers.clear();
|
||||||
|
|
||||||
|
std::vector<std::pair<scene::SMeshBuffer *, std::vector<u16>>> ordered_strains;
|
||||||
|
std::unordered_map<scene::SMeshBuffer *, size_t> strain_idxs;
|
||||||
|
|
||||||
|
if (group_by_buffers) {
|
||||||
|
// find (reversed) order for strains, by iterating front-to-back
|
||||||
|
// (if a buffer A has a triangle nearer than all triangles of another
|
||||||
|
// buffer B, A should be drawn in front of (=after) B)
|
||||||
|
scene::SMeshBuffer *current_buffer = nullptr;
|
||||||
|
for (auto it = triangle_refs.rbegin(); it != triangle_refs.rend(); ++it) {
|
||||||
|
const auto &t = m_transparent_triangles[*it];
|
||||||
|
if (current_buffer == t.buffer)
|
||||||
|
continue;
|
||||||
|
current_buffer = t.buffer;
|
||||||
|
auto [_it2, is_new] =
|
||||||
|
strain_idxs.emplace(current_buffer, ordered_strains.size());
|
||||||
|
if (is_new)
|
||||||
|
ordered_strains.emplace_back(current_buffer, std::vector<u16>{});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// find order for triangles, by iterating back-to-front
|
||||||
scene::SMeshBuffer *current_buffer = nullptr;
|
scene::SMeshBuffer *current_buffer = nullptr;
|
||||||
std::vector<u16> current_strain;
|
std::vector<u16> *current_strain = nullptr;
|
||||||
for (auto i : triangle_refs) {
|
for (auto i : triangle_refs) {
|
||||||
const auto &t = m_transparent_triangles[i];
|
const auto &t = m_transparent_triangles[i];
|
||||||
if (current_buffer != t.buffer) {
|
if (current_buffer != t.buffer) {
|
||||||
if (current_buffer) {
|
|
||||||
m_transparent_buffers.emplace_back(current_buffer, std::move(current_strain));
|
|
||||||
current_strain.clear();
|
|
||||||
}
|
|
||||||
current_buffer = t.buffer;
|
current_buffer = t.buffer;
|
||||||
|
if (group_by_buffers) {
|
||||||
|
auto it = strain_idxs.find(current_buffer);
|
||||||
|
assert(it != strain_idxs.end());
|
||||||
|
current_strain = &ordered_strains[it->second].second;
|
||||||
|
} else {
|
||||||
|
ordered_strains.emplace_back(current_buffer, std::vector<u16>{});
|
||||||
|
current_strain = &ordered_strains.back().second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
current_strain.push_back(t.p1);
|
current_strain->push_back(t.p1);
|
||||||
current_strain.push_back(t.p2);
|
current_strain->push_back(t.p2);
|
||||||
current_strain.push_back(t.p3);
|
current_strain->push_back(t.p3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!current_strain.empty())
|
m_transparent_buffers.reserve(ordered_strains.size());
|
||||||
m_transparent_buffers.emplace_back(current_buffer, std::move(current_strain));
|
if (group_by_buffers) {
|
||||||
|
// the order was reversed
|
||||||
|
for (auto it = ordered_strains.rbegin(); it != ordered_strains.rend(); ++it)
|
||||||
|
m_transparent_buffers.emplace_back(it->first, std::move(it->second));
|
||||||
|
} else {
|
||||||
|
for (auto it = ordered_strains.begin(); it != ordered_strains.end(); ++it)
|
||||||
|
m_transparent_buffers.emplace_back(it->first, std::move(it->second));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapBlockMesh::consolidateTransparentBuffers()
|
void MapBlockMesh::consolidateTransparentBuffers()
|
||||||
|
@ -209,8 +209,14 @@ public:
|
|||||||
/// Center of the bounding-sphere, in BS-space, relative to block pos.
|
/// Center of the bounding-sphere, in BS-space, relative to block pos.
|
||||||
v3f getBoundingSphereCenter() const { return m_bounding_sphere_center; }
|
v3f getBoundingSphereCenter() const { return m_bounding_sphere_center; }
|
||||||
|
|
||||||
/// update transparent buffers to render towards the camera
|
/** Update transparent buffers to render towards the camera.
|
||||||
void updateTransparentBuffers(v3f camera_pos, v3s16 block_pos);
|
* @param group_by_buffers If true, triangles in the same buffer are batched
|
||||||
|
* into the same PartialMeshBuffer, resulting in fewer draw calls, but
|
||||||
|
* wrong order. Triangles within a single buffer are still ordered, and
|
||||||
|
* buffers are ordered relative to each other (with respect to their nearest
|
||||||
|
* triangle).
|
||||||
|
*/
|
||||||
|
void updateTransparentBuffers(v3f camera_pos, v3s16 block_pos, bool group_by_buffers);
|
||||||
void consolidateTransparentBuffers();
|
void consolidateTransparentBuffers();
|
||||||
|
|
||||||
/// get the list of transparent buffers
|
/// get the list of transparent buffers
|
||||||
|
@ -302,6 +302,7 @@ void set_default_settings()
|
|||||||
settings->setDefault("arm_inertia", "true");
|
settings->setDefault("arm_inertia", "true");
|
||||||
settings->setDefault("show_nametag_backgrounds", "true");
|
settings->setDefault("show_nametag_backgrounds", "true");
|
||||||
settings->setDefault("show_block_bounds_radius_near", "4");
|
settings->setDefault("show_block_bounds_radius_near", "4");
|
||||||
|
settings->setDefault("transparency_sorting_group_by_buffers", "true");
|
||||||
settings->setDefault("transparency_sorting_distance", "16");
|
settings->setDefault("transparency_sorting_distance", "16");
|
||||||
|
|
||||||
settings->setDefault("enable_minimap", "true");
|
settings->setDefault("enable_minimap", "true");
|
||||||
|
Loading…
Reference in New Issue
Block a user