Sidebar

Скрытие энтитей на расстоянии

Aynekko

Маппер
Команда форума
Супер Модератор
07.06.2010
3 632
28
  • Золотая медаль RC
  • Бронзовая медаль 216
Фича наподобие сорса. У каждой энтити будет поле fadedistance, в котором можно будет задать на каком расстоянии энтитя исчезнет. На данный момент функционал стабилен, но есть и недоработки - энтити не будут отображаться в мониторах и порталах, т.к. расстояние считается напрямую от энтити до взгляда игрока. По-хорошему нужно делать просчет "взгляда" от того места, куда смотрит монитор - но у меня, к сожалению не вышло. А точнее, вышло частично. Но тогда будут появляться визуальные баги.
P.S. Сразу скажу, я не считаю себя кодером и вообще это не моя "специальность", поэтому все делаете на свой страх и риск и очень рекомендую сделать бэкапы всего проекта - движка, клиента и сервера. Я все это сделал путем экспериментов и не до конца все понимаю, поэтому любые предложения по улучшению только приветствуются.

P.P.S. сломается совместимость с другими билдами ксаша!

Итак, приступим. Редактировать придется все - движок, клиент и сервер.

Начинаем с движка:
progdefs.h, в структуре typedef struct entvars_s добавляем после int renderfx; наш новый параметр
C++:
int fadedistance;
common.h, в структуре typedef struct { ... } tentlist_t; добавляем после int renderfx;
C++:
int fadedistance;  // curstate.fadedistance
net_encode.c, в static const delta_field_t ent_fields[] добавляем после { ENTS_DEF( renderfx ) },
C++:
{ ENTS_DEF( fadedistance )    },
sv_save.c, в static TYPEDESCRIPTION gStaticEntry[] добавляем в конец структуры, по подобию
C++:
DEFINE_FIELD( entity_state_t, fadedistance, FIELD_INTEGER ),
.

Насчет нижеследующих вещей я не совсем уверен, но тоже добавил туда по подобию - опирался на renderfx. Скорее всего они часть другого проекта, но я не до конца уверен, нужны они движку при компиле или нет.
Можете их пока пропустить, но если не будет компилить - то добавьте.
Папка cl_dll, entity.cpp, добавляем в void DLLEXPORT HUD_ProcessPlayerState
C++:
dst->fadedistance = src->fadedistance;
.
Папка common, entity_state.h, в struct entity_state_s добавляем после renderfx
C++:
int fadedistance;
Папка dlls, client.cpp, в int AddToFullPack добавляем после renderfx по подобию
C++:
state->fadedistance  = ent->v.fadedistance;
В том же файле, в void CreateBaseline так же по подобию
C++:
baseline->fadedistance = (byte)entity->v.fadedistance;
В папке dlls, util.cpp, в разделе TYPEDESCRIPTION gEntvarsDescription[] добавляем после renderfx
C++:
DEFINE_ENTITY_FIELD( fadedistance, FIELD_INTEGER ),
На этом с движком закончили.
Переходим в сервер игры.
saverestore.cpp, TYPEDESCRIPTION gEntvarsDescription[], после renderfx по подобию добавляем
C++:
DEFINE_ENTITY_FIELD( fadedistance, FIELD_INTEGER ),
client.cpp, в int AddToFullPack добавляем после renderfx по подобию
C++:
state->fadedistance  = ent->v.fadedistance;
В том же файле, в void CreateBaseline так же по подобию
C++:
baseline->fadedistance = (byte)entity->v.fadedistance;
Потом ищем файл progdefs.h и добавляем туда в структуру typedef struct entvars_s после renderfx
C++:
int fadedistance;
Ну а теперь самое основное - клиент!
r_local.h, после void R_DrawBrushModel( cl_entity_t *e ); добавьте новую функцию
C++:
float R_ComputeFadingDistance( cl_entity_t *e );
r_main.cpp, добавьте сюда эту саму функцию:
C++:
/*
=============
R_ComputeFadingDistance - diffusion addition
=============
*/
float R_ComputeFadingDistance( cl_entity_t *e )
{
if( !CVAR_TO_BOOL( r_fade_props ))
return 1.0f;

// fade distance is not set in the entity
if( e->curstate.fadedistance <= 0 )
return 1.0f;

// calculate correct origin (helps for brush ents)
Vector CenterOffset = (e->curstate.mins + e->curstate.maxs) / 2.f;
Vector EntOrigin = e->curstate.origin + CenterOffset;

// calculate new, increased fade distance if we are zoomed
// for FOV above 70 it is assumed that distance remains unchanged
float FOVfactor = bound( 30, RI->fov_x, 70) / 70;
int FadeDistance = e->curstate.fadedistance * (1 / FOVfactor);

Vector ViewOrigin;
/* UNDONE - portal/monitor views not counted!!!
if( (RI->vieworg - EntOrigin).Length() < (tr.viewparams.vieworg - EntOrigin).Length() )
ViewOrigin = RI->vieworg;
else
ViewOrigin = tr.viewparams.vieworg;
*/
ViewOrigin = tr.viewparams.vieworg;

// for testing purposes
//if( e->curstate.fadedistance == 2002 )
//gEngfuncs.Con_Printf("RI length %i, ViewParams length %i, ViewOrigin is %i %i %i\n", (int)(RI->vieworg - EntOrigin).Length(), (int)(tr.viewparams.vieworg - EntOrigin).Length(), (int)ViewOrigin.x, (int)ViewOrigin.y, (int)ViewOrigin.z);

    // player within range, no need to fade
    if( (ViewOrigin - EntOrigin).Length() <= FadeDistance )
        return 1.0f;

    int EntRenderAmt = 255; // set default render amt for opaque ents

    // grab the custom render amt to start fading from
    if( (e->curstate.rendermode != kRenderNormal) || (e->curstate.rendermode != kRenderTransAlpha) )
        EntRenderAmt = e->curstate.renderamt;

    // if the distance from model origin and the player exceeds desired fade distance, start fading
    if( (int)(ViewOrigin - EntOrigin).Length() > FadeDistance )
        e->curstate.renderamt = EntRenderAmt - ( (int)(ViewOrigin - EntOrigin).Length() - FadeDistance );

    // keep the custom render mode intact, only switch to texture if Normal or Solid (those can't fade)
    if( e->curstate.renderamt < 255 )
    {
        if( (e->curstate.rendermode == kRenderNormal) || (e->curstate.rendermode == kRenderTransAlpha) )
            e->curstate.rendermode = kRenderTransTexture;
    }
e->curstate.renderamt = bound( 0, e->curstate.renderamt, 255);

tr.blend = e->curstate.renderamt / 255.0f;

return tr.blend;
}

Это та самая функция, что заведует исчезанием всех энтитей.
Теперь там же, в r_main.cpp, в qboolean R_AddEntity добавьте строчку после if( FBitSet( clent->curstate.effects, EF_NODRAW )) return false; // done
C++:
if( R_ComputeFadingDistance( clent ) <= 0.0f ) return false;
Далее, r_misc.cpp, void HUD_ProcessPlayerState, добавляем после renderfx по подобию
C++:
dst->fadedistance = src->fadedistance;
Находим файл entity_state.h и в struct entity_state_s кидаем
C++:
int fadedistance;
И вишенка на торте - давайте добавим консольную команду, чтобы теститровать влияние функции прямо в игре.
Идем в папку render на клиенте.
r_cvars.h добавляем
C++:
extern cvar_t    *r_fade_props;
r_view.cpp добавляем в начале рядом с другими кварами
C++:
cvar_t    *r_fade_props;
r_view.cpp, void V_Init, добавляем по подобию
C++:
r_fade_props = CVAR_REGISTER( "r_fade_props", "1", FCVAR_ARCHIVE );
Теперь самое важное, без чего все это работать не будет. В самой папке моде в файле delta.lst нужно найти все упоминания renderfx и под этими строчками добавить по подобию
C++:
DEFINE_DELTA( fadedistance, DT_INTEGER, 16, 8.0 ),
Если не ошибаюсь, там 3 раза она упоминается.

КАК ВСЕ ЭТО ИСПОЛЬЗОВАТЬ?
В любой энтити - спрайт, модель, монстр - добавьте параметр fadedistance и нужную вам дистанцию. 500, 1000, ну или сколько там. Тестируйте в общем на глаз :)
Вот как это выглядит в игре:

На этом все. Это не более чем эксперименты, буду рад отзывам. В моем моде фишка оказалась очень полезной.

UPDATE 26.07.2021:
Экспериментальная фича, но возможно добавит нехило фпс на открытых пространствах.
Идем в сервер, находим client.cpp, там находим int AddToFullPack. После вот этих строчек
C++:
if( !pEntity )
{
return 0;
}
Вставляем код:
C++:
if( pEntity->pev->fadedistance > 0 )
{
     Vector CenterOffset = (ent->v.mins + ent->v.maxs) / 2.f;
      Vector EntOrigin = ent->v.origin + CenterOffset;
     if( fabs( (host->v.origin - EntOrigin).Length() ) > ent->v.fadedistance + 255 )
                return 0;
}
Этот код, как видно, затрагивает только энтити, у которых дистанция задана. Он не отправляет никакие данные об этой энтити на клиент, если она полностью скрыта. В качестве примера - есть огромное открытое пространство с кучей мелких моделей. Даже не смотря на то, что они скрыты визуально, информация о них все равно идет на клиент, что, как выяснилось, нехило влияет на фпс. Ну а раз они скрыты, зачем нам посылать инфу? Но это все мои рассуждения. Поэтому тестируйте, пробуйте, делитесь результатами.
 
Последнее редактирование:

Next Day

New member
23.12.2019
19
8
3
Тутор просто офигенный, оптимизирует нереально!!!!
Вообще в не укор Дяде Мише , но это изначально должно было быть в xash!
Всем кто делает игру,мод на xash просто обязательно использовать особенно если хотите детализировать уровень побольше да и в любом другом случаи лишних fps не бывает.

Вот моя сырая наработка на полностью не оптимизированной карте без тутора Aynekko
xash нет.png


Как можно заметить fps =28 и это учитывая мой комп который не самый слабый
Комп Win10 razen 5 2600 16GB RAM GTX 1070 8GB ssd 120gb и hdd 1tb

А вот уже с оптимизацией Aynekko
xash есть.png

Fps =60 но это только потому что моник старый 60 герц и fps залочен на 60
Fps может быть намного больше стал не знаю ,но факт уже налицо.

Вообщем всем советую кто на Xash оптимизирует правда не реально!

Aynekko СПАСИБО ТЕБЕ БОЛЬШОЕ И УДАЧИ В ДАЛЬНЕЙШЕЙ РАЗРАБОТКЕ!!!
 
  • Like
  • Love
Reactions: KorteZZ and Aynekko

Aynekko

Маппер
Команда форума
Супер Модератор
07.06.2010
3 632
28
  • Золотая медаль RC
  • Бронзовая медаль 216
Вообщем всем советую кто на Xash оптимизирует правда не реально!
Спасибо за отзыв! А можешь показать скрин c fps_max 0 и отключенной вертикальной синхрой? И еще если можно чтобы было видно r_speeds 1 до и после. Интересно насколько все-таки срезалось и вырос фпс.
 
  • Like
Reactions: Next Day

Next Day

New member
23.12.2019
19
8
3
Выключено
xashoff.png


Включено
xashon.png


Получается + 39Fps, для этой карты это дофига!
Повторюсь карта очень не оптимизирована!
 

Aynekko

Маппер
Команда форума
Супер Модератор
07.06.2010
3 632
28
  • Золотая медаль RC
  • Бронзовая медаль 216
Получается + 39Fps, для этой карты это дофига!
Повторюсь карта очень не оптимизирована!
Да, значения все еще высоки, но получилось неплохо. Ты же куче энтитей прописал fadedistance? Каким прописывал? Брашевым func_wall, env_static? Просто у тебя вполи тоже срезался нехило. И даже трава куда-то делась! Она что ли на брашевой энтити была?))
 
  • Like
Reactions: Next Day

Next Day

New member
23.12.2019
19
8
3
Дальше есть вода которая скорей всего больше всего и грузит карту
и она срезала wpoly.
Вообщем я поставил воде и моделям этот параметр ,но что самое замечательное можно это присвоить ко всему что нагружает игру и нужно только вблизи.
 

Aynekko

Маппер
Команда форума
Супер Модератор
07.06.2010
3 632
28
  • Золотая медаль RC
  • Бронзовая медаль 216
Дальше есть вода которая скорей всего больше всего и грузит карту
и она срезала wpoly.
Вообщем я поставил воде и моделям этот параметр ,но что самое замечательное можно это присвоить ко всему что нагружает игру и нужно только вблизи.
Супер. Ты еще полетай по карте с ноуклипом, потестируй. Нормально ли исчезает все. А так да, любым энтитям можно ставить :)
 
  • Like
Reactions: Next Day

Next Day

New member
23.12.2019
19
8
3
Летал вроде все замечательно, исчезает все класно как надо особенно если грамотно все настроить.
И да СУПЕР
 
  • Like
Reactions: Aynekko

Next Day

New member
23.12.2019
19
8
3
Привет [B]KorteZZ[/B], следить пока негде все еще на ранних этапах разработки.В задумке есть кооператив, поэтому есть проблемы связанные с мультиплеером Xash.
Но как только проект будит приведен во что то более целостное опубликую здесь или на hlfx.
 

Next Day

New member
23.12.2019
19
8
3
Может странно, но я не пользуюсь не Вк не Телегой ,а вот Дискорд недавно поставил.
 
  • Like
Reactions: KorteZZ

Aynekko

Маппер
Команда форума
Супер Модератор
07.06.2010
3 632
28
  • Золотая медаль RC
  • Бронзовая медаль 216
Тутор просто офигенный, оптимизирует нереально!!!!
Next Day, я тут дополнил тутор (см. UPDATE в нижней части первого поста), можешь пожалуйста проверить? Должно хорошо фпс добавить у тебя, т.к. пространства открытые.
 
  • Like
Reactions: Next Day

Aynekko

Маппер
Команда форума
Супер Модератор
07.06.2010
3 632
28
  • Золотая медаль RC
  • Бронзовая медаль 216
  • Like
Reactions: Next Day

Next Day

New member
23.12.2019
19
8
3
Потестировав пришёл к выводу что в некоторых местах даже до +100 fps вообщем полезное дополнение.
Было бы классно если можно сделать чтобы ентити за спиной игрока быстрей отсекались
,он их все равно не видит:geek:!
Это возможно?
 

Aynekko

Маппер
Команда форума
Супер Модератор
07.06.2010
3 632
28
  • Золотая медаль RC
  • Бронзовая медаль 216
Круто! :D
Было бы классно если можно сделать чтобы ентити за спиной игрока быстрей отсекались
,он их все равно не видит:geek:!
Это возможно?
Нет, они уже и так отсекаются из видимости.
 

Новые сообщения

Донат - Хостинг

Итого
200.00 $
Цель
600.00 $

Доноры Красавчики

Пользователи онлайн

Нет пользователей онлайн.