1. Друзья, в это тяжёлое и непонятное для всех нас время мы просим вас воздержаться от любых упоминаний политики на форуме, - этим ситуации не поможешь, а только возникнут ненужные ссоры и обиды. Это касается также шуток и юмора на тему конфликта. Пусть войны будут только виртуальными, а политики решают разногласия дипломатическим путём. С уважением, администрация Old-Games.RU.

    Скрыть объявление
  2. Если Вы видите это сообщение, значит, вы ещё не зарегистрировались на нашем форуме.

    Зарегистрируйтесь, если вы хотите принять участие в обсуждениях. Перед регистрацией примите к сведению:
    1. Не регистрируйтесь с никами типа asdfdadhgd, 354621 и тому подобными, не несущими смысловой нагрузки (ник должен быть читаемым!): такие пользователи будут сразу заблокированы!
    2. Не регистрируйте больше одной учётной записи. Если у вас возникли проблемы при регистрации, то вы можете воспользоваться формой обратной связи внизу страницы.
    3. Регистрируйтесь с реально существующими E-mail адресами, иначе вы не сможете завершить регистрацию.
    4. Обязательно ознакомьтесь с правилами поведения на нашем форуме, чтобы избежать дальнейших конфликтов и непонимания.
    С уважением, администрация форума Old-Games.RU
    Скрыть объявление

Разработка (боль и страдание 2)

Автор: id0 · 31 май 2025 · ·
Шейдеры и поверхности.
  1. npc20250524003411-00.jpg

    Вообще, я заметил, что слишком много тут сижу, срусь на форумах, и ничего не делаю :) Поэтому теперь буду заходить пореже, раз в недельку или где-то так. Вот пару дней не заходил, зато разобрался с огромным гемороем, который мучал меня с самого начала разработки. Но обо всём по порядку.

    Пишу я это исключительно потому, что я всю голову себе сломал, как именно это сделать, перелопатил полинтернета, и еле-еле разобрался, информации - кот наплакал. Специально поставлю метки для поисковиков, может кому поможет. Итак:

    В первом Quake разумеется нет никаких шейдеров. И проверки поверхностей нет. Вернее есть, но только вшитых в движок, крепко-накрепко захардкоженных. Это, к примеру, триггеры, водная поверхность, и в таком духе, их совсем немного. Поэтому даже в модах когда делают звуки шагов они для любой поверхности одинаковые. Однако в третьей кваке шейдеры есть, и darkplaces их использует. А я как раз и хотел звуки шагов.

    Скрипты то для этого лежат повсюду и их много, однако я нашёл почти готовый для darkplaces, в исходниках мода Q.U.A.L.K.E.R. Правда там они почему-то не доделаны, звуков нет и они не работают. Не буду разбирать тут полностью весь скрипт, суть не в этом. Суть вот в этих строчках:

    float trace_dphitq3surfaceflags; // Q3SURFACEFLAG_ value of impacted surface

    Вот эта строчка - это функционал из скрипта dpextensions.qc, который использует сам функционал движка. Скрипт этот обязателен для любого, кто делает что-то на darkplaces. Но что делает строчка? Очень просто - сканирует поверхность скомпиленных в q3map2 bsp, на предмет ключевых слов, в данном случае флагов поверхности (surfaceparm). Например далее в скрипте написано:

    //surfaceparm slick // 2
    //surfaceparm dust //262144
    //surfaceparm metalsteps //4096
    //surfaceparm noimpact //16
    //surfaceparm nomarks //32
    //surfaceparm alphashadow //65536
    //surfaceparm hint //256
    //surfaceparm lightfilter //32768


    Это биты, которые используют поверхности в коде. В шейдере это выглядит так:

    textures/metal/metal_floor_01
    {
    surfaceparm metalsteps
    {
    map $lightmap
    map textures/metal/metal_floor_01
    }
    }


    Далее в скрипте назначаются переменные:

    float SURFACE_METAL = 4096;
    float SURFACE_GRAVEL = 262144;

    ...
    И так далее. Потом идёт проверка в коде, типа:

    if(trace_dphitq3surfaceflags == SURFACE_METAL)
    {
    if (r <=0.25) sound(self, CHAN_BODY, "footsteps/metal1.wav", 0.5, SoundRadius(450));
    else if (r <=0.5 && r>0.25) sound(self, CHAN_BODY, "footsteps/metal2.wav", 0.5, SoundRadius(450));
    else if (r <=0.75 && r>0.5) sound(self, CHAN_BODY, "footsteps/metal3.wav", 0.5, SoundRadius(450));
    else sound(self, CHAN_BODY, "footsteps/metal4.wav", 0.5, SoundRadius(450));
    }

    И играет звук.

    Но вот проблема. Это тоже вшитые в код поверхности, они уже есть, существуют, и, например, использовать surfaceparm nomarks для поверхности, конечно можно, но блин их мало, и вообще костыли. Surfaceparm nomarks в теле шейдера вообще-то означает, что он не будет принимать декали (дырки от пуль и прочее такое). А что делать если хочется, к примеру, снег?

    Оказывается выход есть.

    Создаём в папке мода scripts, где лежат все шейдеры (а по сути материалы) файлик custinfoparms.txt. Внутри пишем (Это не я придумал, а взял где-то, там уже написаны все незанятые биты для поверхностей в HEX формате. Так надо.):

    // Custom Infoparms File
    // Custom Contentsflags
    {
    interactclip 0x00000080
    weaponclip 0x00000100
    bossclip 0x00000200
    }
    // Custom Surfaceflags
    {
    generic 0x00000000
    dirt 0x00000040
    grass 0x00008040
    gravel 0x00018000
    grate 0x00020000
    metal 0x00020040
    ice 0x00028000
    mud 0x00028040
    puddle 0x00040000
    soft 0x00040040
    snow 0x00048000
    stone 0x00048040
    wood 0x00060000
    flesh 0x00068000
    }


    Этот файл видит компилятор q3map2, при условии, что в bsp строке прописано -custinfoparms, вот так:

    bspq.jpg

    Но это ещё не всё. Нам ещё нужно узнать целое число (integer). Переводим dirt 0x00000040 в число. Это можно сделать в любом онлайн сервисе:

    hex.jpg

    Получилось 64. Теперь пишем в коде:

    float SURFACE_DIRT = 64;

    и что то вроде:

    else if(trace_dphitq3surfaceflags == SURFACE_DIRT)
    {
    if (r <=0.25) sound(self, CHAN_BODY, "footsteps/dirt1.wav", footstep_volume, SoundRadius(450));
    else if (r <=0.5 && r>0.25) sound(self, CHAN_BODY, "footsteps/dirt2.wav", footstep_volume, SoundRadius(450));
    else if (r <=0.75 && r>0.5) sound(self, CHAN_BODY, "footsteps/dirt3.wav", footstep_volume, SoundRadius(450));
    else sound(self, CHAN_BODY, "footsteps/dirt4.wav", footstep_volume, SoundRadius(450));
    }

    Компилим наши qc файлы в progs.dat, об этом я уже писал подробно в прошлый раз, закидываем файл в папку мода. Это в общих чертах, я не буду заострять на этом, суть записи в другом.

    Но и это ещё не всё. В шейдере поверхности пишем:

    textures/terrain/ground_sand_01
    {
    surfaceparm dirt
    {
    map $lightmap
    map textures/terrain/ground_sand_01
    }
    }


    Компилим карту. О нет! Компилятор пишет, что WARNING: Unknown surfaceparm: "dirt"! Не обращайте внимания, всё равно он её скомпилил. В конце скрипта я написал небольшой дебаг, который показывает число поверхности, чтобы не быть голословным. Так-то звуки я слышу, но проверить не помешает:

    npc20250530234558-00.jpg

    Всё в порядке, как мы помним число наше было 64, да и звуки слышно.

    Если кому интересно, то прилагаю полный скрипт, но от него одного толку немного, там ещё много нужно прописывать всего. Но главное теперь понятно. Ура!

    З.Ы. Кстати шейдеры в Q3 довольно клёвая штука, карту даже не нужно перекомпилировать, можно просто изменить шейдер, и при следующем запуске игры большинство параметров сразу изменится. Но не все. Не знаю насчёт флагов поверхности.

    Ну и, само собой, потом можно будет просто перекомпилировать сам движок, вот с этими параметрами, и тогда надобность с такими плясками отпадёт, но всё-же - для модеров - способ незаменимый.

    Вложения:

    • FOOTSTEPS.zip
      Размер файла:
      1,1 КБ
      Просмотров:
      10

Комментарии

  1. Cortez Cardinal
    А нельзя напрямую float SURFACE_DIRT = 0x40?
    Стало интересно глянуть, что умеет QuakeC.
    1. id0
      Не знаю, не пробовал. Там всё сложно, а я такой себе кодер. А QuakeC много чего умеет, вообще вся квака в нём написана, движок - это чисто иструмент, со своими плюсами минусами. Выше движка не прыгнешь, поэтому и появляются порты, которые, например обходят ограничение по размерам карт, и прочее такое. А всё остальное в QuakeC пишется, вся логика и механика игры.
Чтобы оставить комментарий просто зарегистрируйтесь и станьте участником!
  1. На этом сайте используются файлы cookie, чтобы персонализировать содержимое, хранить Ваши предпочтения и держать Вас авторизованным в системе, если Вы зарегистрировались.
    Продолжая пользоваться данным сайтом, Вы соглашаетесь на использование нами Ваших файлов cookie.
    Скрыть объявление