vk: add a mechanism for exclusion of single surfaces from smoothing
Uses `_xvk_smoothing_excluded` field. Surfaces can still be smoothed with a limited list of neightbours explicitly by being included in a smoothing group. Fixes #619
This commit is contained in:
parent
5698746f42
commit
6fda8bd977
|
@ -5,7 +5,9 @@
|
|||
- [x] single return/goto cleanup
|
||||
- [-] pass args via structs? -> not necessary
|
||||
- [-] collapse texture uploading into a single function -> not necessary, they are different enough
|
||||
- [ ] merge materials PR
|
||||
- [x] merge materials PR
|
||||
- [x] studio gibs translucency
|
||||
- [x] smoothing exclusion
|
||||
|
||||
# 2023-10-30 E321
|
||||
- [x] missing skybox
|
||||
|
|
|
@ -89,3 +89,7 @@ _xvk_smooth_entire_model "1"
|
|||
{
|
||||
//"_xvk_smoothing_threshold" "44" //workaround
|
||||
}
|
||||
|
||||
{
|
||||
_xvk_smoothing_excluded "2120 2117 2118 1269 1267 2791 2792 2793"
|
||||
}
|
||||
|
|
|
@ -241,8 +241,10 @@ void main() {
|
|||
//imageStore(out_dest, pix, vec4(.5 + geometry_normal * .5, 0.)); return;
|
||||
//const vec4 mat_rmxx = imageLoad(material_rmxx, pix);
|
||||
//imageStore(out_dest, pix, vec4((.5 + shading_normal * .5)*.8 + .2 * mat_rmxx.a , 0.)); return;
|
||||
//imageStore(out_dest, pix, vec4(.5 + shading_normal * .5, 0.)); return;
|
||||
|
||||
vec3 normal = pix.x < res.x / 2 ? shading_normal : geometry_normal;
|
||||
//vec3 normal = pix.x < res.x / 2 ? shading_normal : geometry_normal;
|
||||
vec3 normal = shading_normal;// : geometry_normal;
|
||||
imageStore(out_dest, pix, vec4(.5 + normal * .5, 0.)); return;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -848,21 +848,31 @@ static void getSurfaceNormal( const msurface_t *surf, vec3_t out_normal) {
|
|||
}
|
||||
|
||||
static qboolean shouldSmoothLinkSurfaces(const model_t* mod, qboolean smooth_entire_model, int surf1, int surf2) {
|
||||
//return Q_min(surf1, surf2) == 741 && Q_max(surf1, surf2) == 743;
|
||||
|
||||
// Filter explicit exclusion
|
||||
for (int i = 0; i < g_map_entities.smoothing.excluded_count; i+=2) {
|
||||
const int cand1 = g_map_entities.smoothing.excluded[i];
|
||||
const int cand2 = g_map_entities.smoothing.excluded[i+1];
|
||||
for (int i = 0; i < g_map_entities.smoothing.excluded_pairs_count; i+=2) {
|
||||
const int cand1 = g_map_entities.smoothing.excluded_pairs[i];
|
||||
const int cand2 = g_map_entities.smoothing.excluded_pairs[i+1];
|
||||
|
||||
if ((cand1 == surf1 && cand2 == surf2)
|
||||
|| (cand1 == surf2 && cand2 == surf1))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (smooth_entire_model)
|
||||
qboolean excluded = false;
|
||||
for (int i = 0; i < g_map_entities.smoothing.excluded_count; ++i) {
|
||||
const int cand = g_map_entities.smoothing.excluded[i];
|
||||
if (cand == surf1 || cand == surf2) {
|
||||
excluded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (smooth_entire_model && !excluded)
|
||||
return true;
|
||||
|
||||
// Smoothing groups have priority over individual exclusion.
|
||||
// That way we can exclude a surface from smoothing with most of its neighbours,
|
||||
// but still smooth it with some.
|
||||
for (int i = 0; i < g_map_entities.smoothing.groups_count; ++i) {
|
||||
const xvk_smoothing_group_t *g = g_map_entities.smoothing.groups + i;
|
||||
uint32_t bits = 0;
|
||||
|
@ -880,6 +890,9 @@ static qboolean shouldSmoothLinkSurfaces(const model_t* mod, qboolean smooth_ent
|
|||
}
|
||||
}
|
||||
|
||||
if (excluded)
|
||||
return false;
|
||||
|
||||
// Do not join surfaces with different textures. Assume they belong to different objects.
|
||||
{
|
||||
// Should we also check texture/material patches too to filter out pairs which originally had
|
||||
|
|
|
@ -581,18 +581,38 @@ static void patchEntity( const entity_props_t *props, uint32_t have_fields ) {
|
|||
}
|
||||
}
|
||||
|
||||
static void appendExludedPairs(const entity_props_t *props) {
|
||||
static void appendExcludedPairs(const entity_props_t *props) {
|
||||
if (props->_xvk_smoothing_excluded_pairs.num % 2 != 0) {
|
||||
ERR("vk_mapents: smoothing group exclusion list should be list of pairs -- divisible by 2; cutting the tail");
|
||||
ERR("vk_mapents: smoothing group exclusion pairs list should be list of pairs -- divisible by 2; cutting the tail");
|
||||
}
|
||||
|
||||
int count = props->_xvk_smoothing_excluded_pairs.num & ~1;
|
||||
if (g_map_entities.smoothing.excluded_pairs_count + count > COUNTOF(g_map_entities.smoothing.excluded_pairs)) {
|
||||
ERR("vk_mapents: smoothing exclusion pairs capacity exceeded, go complain in github issues");
|
||||
count = COUNTOF(g_map_entities.smoothing.excluded_pairs) - g_map_entities.smoothing.excluded_pairs_count;
|
||||
}
|
||||
|
||||
memcpy(g_map_entities.smoothing.excluded_pairs + g_map_entities.smoothing.excluded_pairs_count, props->_xvk_smoothing_excluded_pairs.values, count * sizeof(int));
|
||||
|
||||
g_map_entities.smoothing.excluded_pairs_count += count;
|
||||
}
|
||||
|
||||
static void appendExcludedSingles(const entity_props_t *props) {
|
||||
int count = props->_xvk_smoothing_excluded.num;
|
||||
|
||||
if (g_map_entities.smoothing.excluded_count + count > COUNTOF(g_map_entities.smoothing.excluded)) {
|
||||
ERR("vk_mapents: smoothing exclusion group capacity exceeded, go complain in github issues");
|
||||
count = COUNTOF(g_map_entities.smoothing.excluded) - g_map_entities.smoothing.excluded_count;
|
||||
}
|
||||
|
||||
memcpy(g_map_entities.smoothing.excluded + g_map_entities.smoothing.excluded_count, props->_xvk_smoothing_excluded_pairs.values, count * sizeof(int));
|
||||
memcpy(g_map_entities.smoothing.excluded + g_map_entities.smoothing.excluded_count, props->_xvk_smoothing_excluded.values, count * sizeof(int));
|
||||
|
||||
if (g_log_debug_bits & LOG_MODULE) {
|
||||
DEBUG("Adding %d smoothing-excluded surfaces", props->_xvk_smoothing_excluded.num);
|
||||
for (int i = 0; i < props->_xvk_smoothing_excluded.num; ++i) {
|
||||
DEBUG("%d", props->_xvk_smoothing_excluded.values[i]);
|
||||
}
|
||||
}
|
||||
|
||||
g_map_entities.smoothing.excluded_count += count;
|
||||
}
|
||||
|
@ -670,7 +690,11 @@ static void parseEntities( char *string, qboolean is_patch ) {
|
|||
}
|
||||
|
||||
if (have_fields & Field__xvk_smoothing_excluded_pairs) {
|
||||
appendExludedPairs(&values);
|
||||
appendExcludedPairs(&values);
|
||||
}
|
||||
|
||||
if (have_fields & Field__xvk_smoothing_excluded) {
|
||||
appendExcludedSingles(&values);
|
||||
}
|
||||
|
||||
if (have_fields & Field__xvk_smoothing_group) {
|
||||
|
@ -798,6 +822,7 @@ void XVK_ParseMapEntities( void ) {
|
|||
g_map_entities.entity_count = 0;
|
||||
g_map_entities.func_any_count = 0;
|
||||
g_map_entities.smoothing.threshold = cosf(DEG2RAD(45.f));
|
||||
g_map_entities.smoothing.excluded_pairs_count = 0;
|
||||
g_map_entities.smoothing.excluded_count = 0;
|
||||
for (int i = 0; i < g_map_entities.smoothing.groups_count; ++i)
|
||||
g_map_entities.smoothing.groups[i].count = 0;
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
X(25, string, _xvk_map_material, String) \
|
||||
X(26, int, rendermode, Int) \
|
||||
X(27, int, _xvk_smooth_entire_model, Int) \
|
||||
X(28, int_array_t, _xvk_smoothing_excluded, IntArray) \
|
||||
|
||||
/* NOTE: not used
|
||||
X(23, int, renderamt, Int) \
|
||||
|
@ -162,15 +163,20 @@ typedef struct {
|
|||
float threshold;
|
||||
|
||||
#define MAX_EXCLUDED_SMOOTHING_SURFACES_PAIRS 32
|
||||
int excluded[MAX_EXCLUDED_SMOOTHING_SURFACES_PAIRS * 2];
|
||||
int excluded_count;
|
||||
int excluded_pairs[MAX_EXCLUDED_SMOOTHING_SURFACES_PAIRS * 2];
|
||||
int excluded_pairs_count;
|
||||
|
||||
#define MAX_INCLUDED_SMOOTHING_GROUPS 32
|
||||
int groups_count;
|
||||
xvk_smoothing_group_t groups[MAX_INCLUDED_SMOOTHING_GROUPS];
|
||||
|
||||
#define MAX_EXCLUDED_SMOOTHING_SURFACES 256
|
||||
int excluded_count;
|
||||
int excluded[MAX_EXCLUDED_SMOOTHING_SURFACES];
|
||||
} smoothing;
|
||||
} xvk_map_entities_t;
|
||||
|
||||
// TODO expose a bunch of things here as funtions, not as internal structures
|
||||
extern xvk_map_entities_t g_map_entities;
|
||||
|
||||
enum { NoEnvironmentLights = -1, MoreThanOneEnvironmentLight = -2 };
|
||||
|
|
Loading…
Reference in New Issue