Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

Вопрос Расскажите про internal chams.

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
12 Сен 2023
Сообщения
12
Реакции
0
Всем привет! Такой вопрос, как вы делаете internal chams? Я вначале пробовал сделать через перехват drawObject, в итоге все нормально работает, но на модельках игроков могут возникать артефакты ( например цвет части снаряжения красятся в цвет Invisble, хотя моделька игрока стоит рядом со мной ) + есть смешивание цвета.
Далее я попробовал сделать через GeneratePrimitives, тут пропали артефакты, но появилась проблема с отображением visible и invisible разными цветами — цвета накладываются друг на друга, нет чёткого разделения "за стеной / на виду". Как это побороть? Спрашивал у нейронки - сказала делать stencil / depth-fail, но я не нашел примеры таких реализаций. Расскажите как вы делаете свои internal chams, какие технологии используете? Как вы добились четкого разделения цветов ( если смогли )? Буду очень благодарен за ответ!
 
Привет! Отличный вопрос, и ты сам почти на него ответил, когда упомянул нейросеть. Проблема, с которой ты столкнулся (GeneratePrimitives не разделяет visible/invisible), — это классическая проблема работы с буфером глубины (Depth Buffer) и трафаретом (Stencil Buffer).

Краткий итог твоих экспериментов:

  • DrawObject: Есть доступ к материалам, но ломается логика вендорского кода (артефакты, инверсный скиннинг).
  • GeneratePrimitives: Безопасно (нет артефактов), но нет доступа к проверке глубин, поэтому цвета накладываются.
Как это побороть: Тебе нужно вернуться к хуку на DrawObject (или DIP), но принудительно управлять тем, кто и когда рисуется, используя Stencil Buffer. Это и есть та самая "технология internal chams", которую ты ищешь.

Вот пошаговая схема, как это реализовать (в концепциях DirectX 11/OpenGL, под любую игру адаптируется так же).

Теория: Как работают "правильные" Chams​

Тебе нужно нарисовать одну и ту же модель дважды за один кадр, но с разными настройками теста глубины. Обычный подход (который не сработал у тебя с GeneratePrimitives) рисует всё подряд. Правильный подход выглядит так:

  1. Первый проход (Invisible / XQZR): Рисуем модель отключая запись в буфер глубины (Depth Write) или меняя тест глубины на GREATER (больше). Так мы закрашиваем пиксели, которые находятся за стенами.
  2. Запись в Stencil: Когда рисуем первый проход, мы пишем маркер (например, 1) в Stencil Buffer. Это метка "здесь был игрок".
  3. Второй проход (Visible): Рисуем модель снова. Но теперь мы говорим шейдеру: "Рисуй, только если в Stencil лежит НЕ наш маркер" (или лежит, в зависимости от задачи).
  4. Сброс Stencil: В конце цикла рендера стираем маркер.
 
Привет! Отличный вопрос, и ты сам почти на него ответил, когда упомянул нейросеть. Проблема, с которой ты столкнулся (GeneratePrimitives не разделяет visible/invisible), — это классическая проблема работы с буфером глубины (Depth Buffer) и трафаретом (Stencil Buffer).

Краткий итог твоих экспериментов:

  • DrawObject: Есть доступ к материалам, но ломается логика вендорского кода (артефакты, инверсный скиннинг).
  • GeneratePrimitives: Безопасно (нет артефактов), но нет доступа к проверке глубин, поэтому цвета накладываются.
Как это побороть: Тебе нужно вернуться к хуку на DrawObject (или DIP), но принудительно управлять тем, кто и когда рисуется, используя Stencil Buffer. Это и есть та самая "технология internal chams", которую ты ищешь.

Вот пошаговая схема, как это реализовать (в концепциях DirectX 11/OpenGL, под любую игру адаптируется так же).

Теория: Как работают "правильные" Chams​

Тебе нужно нарисовать одну и ту же модель дважды за один кадр, но с разными настройками теста глубины. Обычный подход (который не сработал у тебя с GeneratePrimitives) рисует всё подряд. Правильный подход выглядит так:

  1. Первый проход (Invisible / XQZR): Рисуем модель отключая запись в буфер глубины (Depth Write) или меняя тест глубины на GREATER (больше). Так мы закрашиваем пиксели, которые находятся за стенами.
  2. Запись в Stencil: Когда рисуем первый проход, мы пишем маркер (например, 1) в Stencil Buffer. Это метка "здесь был игрок".
  3. Второй проход (Visible): Рисуем модель снова. Но теперь мы говорим шейдеру: "Рисуй, только если в Stencil лежит НЕ наш маркер" (или лежит, в зависимости от задачи).
  4. Сброс Stencil: В конце цикла рендера стираем маркер.
Stencil не поможет. Модель ломается от смены материала, а не от z-теста.
 
Привет! Отличный вопрос, и ты сам почти на него ответил, когда упомянул нейросеть. Проблема, с которой ты столкнулся (GeneratePrimitives не разделяет visible/invisible), — это классическая проблема работы с буфером глубины (Depth Buffer) и трафаретом (Stencil Buffer).

Краткий итог твоих экспериментов:

  • DrawObject: Есть доступ к материалам, но ломается логика вендорского кода (артефакты, инверсный скиннинг).
  • GeneratePrimitives: Безопасно (нет артефактов), но нет доступа к проверке глубин, поэтому цвета накладываются.
Как это побороть: Тебе нужно вернуться к хуку на DrawObject (или DIP), но принудительно управлять тем, кто и когда рисуется, используя Stencil Buffer. Это и есть та самая "технология internal chams", которую ты ищешь.

Вот пошаговая схема, как это реализовать (в концепциях DirectX 11/OpenGL, под любую игру адаптируется так же).

Теория: Как работают "правильные" Chams​

Тебе нужно нарисовать одну и ту же модель дважды за один кадр, но с разными настройками теста глубины. Обычный подход (который не сработал у тебя с GeneratePrimitives) рисует всё подряд. Правильный подход выглядит так:

  1. Первый проход (Invisible / XQZR): Рисуем модель отключая запись в буфер глубины (Depth Write) или меняя тест глубины на GREATER (больше). Так мы закрашиваем пиксели, которые находятся за стенами.
  2. Запись в Stencil: Когда рисуем первый проход, мы пишем маркер (например, 1) в Stencil Buffer. Это метка "здесь был игрок".
  3. Второй проход (Visible): Рисуем модель снова. Но теперь мы говорим шейдеру: "Рисуй, только если в Stencil лежит НЕ наш маркер" (или лежит, в зависимости от задачи).
  4. Сброс Stencil: В конце цикла рендера стираем маркер.
что за чат гпт ответ
 
Хз как в кс2, я на неё не делал ничего, но делал чамсы в тф2, так как движки одного семейства, думаю логика в кс2 будет схожая. Я хукал функцию отрисовки моделей DrawModelExecute, брал готовые материалы из игры IMaterial для видимой части и для невидимой соответственно, делаются они хитрожопо через IMaterialSystem g_pMaterialSystem, и его виртуальную функцию FindMaterial. У полученных материалов нужна функция SetMaterialVarFlag с двумя аргументами, первый аргумент это какой флаг ставим - для чамсов флаг MATERIAL_VAR_IGNOREZ = (1 << 15) отвечает за рендер материала сквозь стены, второй аргумент это значение флага - 1 значит через стены рендерим, 0 значит обычным образом. Завершает всё это IVModelRender *g_pModelRender, который имеет в себе функцию ForcedMaterialOverride, ей как раз и засовывю свои хитрожопые материалы за место оригинальных при отрисовке моделей игрока (в коде стоят проверки само собой на то, кого функция рисует)

кусок кода отвечающий за подмену материалов:
Expand Collapse Copy
    matHidden->SetMaterialVarFlag(MATERIAL_VAR_IGNOREZ, true);//Ставим флаг чтобы через стены рендерилось
    matHidden->AlphaModulate(1);
    g_pModelRender->ForcedMaterialOverride(matHidden, 0);//Меняем материал на наш
    oDrawModelExecute(thisptr, state, info, pBoneToWorld);//Рендерим
    if (visibleColor)
    {
        visibleColor->SetVecValue(menu.chams_vis_color.x, menu.chams_vis_color.y, menu.chams_vis_color.z);
    }
    else
    {
        visibleColor = matVisible->FindVar("$color2", nullptr, false);
    }
    matVisible->SetMaterialVarFlag(MATERIAL_VAR_IGNOREZ, false);//Ставим флаг чтобы через стены не рендерилось
    matVisible->AlphaModulate(1);
    g_pModelRender->ForcedMaterialOverride(matVisible, 0);//Меняем материал
    oDrawModelExecute(thisptr, state, info, pBoneToWorld);//Рендерим

    g_pModelRender->ForcedMaterialOverride(nullptr, 0);//Сбрасываем материалы чтобы дальше он нормально рендерил все остальное
Вот так как-то, надеюсь поможет хотя бы маленько
P.S. да тут вообще никак не хукается и не используется DirectX и остальное, все через игровые классы-обёртки над рендером, поэтому и получается делать монолитные чамсы на всю модельку персонажа а не на отдельные его части
 
Хз как в кс2, я на неё не делал ничего, но делал чамсы в тф2, так как движки одного семейства, думаю логика в кс2 будет схожая. Я хукал функцию отрисовки моделей DrawModelExecute, брал готовые материалы из игры IMaterial для видимой части и для невидимой соответственно, делаются они хитрожопо через IMaterialSystem g_pMaterialSystem, и его виртуальную функцию FindMaterial. У полученных материалов нужна функция SetMaterialVarFlag с двумя аргументами, первый аргумент это какой флаг ставим - для чамсов флаг MATERIAL_VAR_IGNOREZ = (1 << 15) отвечает за рендер материала сквозь стены, второй аргумент это значение флага - 1 значит через стены рендерим, 0 значит обычным образом. Завершает всё это IVModelRender *g_pModelRender, который имеет в себе функцию ForcedMaterialOverride, ей как раз и засовывю свои хитрожопые материалы за место оригинальных при отрисовке моделей игрока (в коде стоят проверки само собой на то, кого функция рисует)

кусок кода отвечающий за подмену материалов:
Expand Collapse Copy
    matHidden->SetMaterialVarFlag(MATERIAL_VAR_IGNOREZ, true);//Ставим флаг чтобы через стены рендерилось
    matHidden->AlphaModulate(1);
    g_pModelRender->ForcedMaterialOverride(matHidden, 0);//Меняем материал на наш
    oDrawModelExecute(thisptr, state, info, pBoneToWorld);//Рендерим
    if (visibleColor)
    {
        visibleColor->SetVecValue(menu.chams_vis_color.x, menu.chams_vis_color.y, menu.chams_vis_color.z);
    }
    else
    {
        visibleColor = matVisible->FindVar("$color2", nullptr, false);
    }
    matVisible->SetMaterialVarFlag(MATERIAL_VAR_IGNOREZ, false);//Ставим флаг чтобы через стены не рендерилось
    matVisible->AlphaModulate(1);
    g_pModelRender->ForcedMaterialOverride(matVisible, 0);//Меняем материал
    oDrawModelExecute(thisptr, state, info, pBoneToWorld);//Рендерим

    g_pModelRender->ForcedMaterialOverride(nullptr, 0);//Сбрасываем материалы чтобы дальше он нормально рендерил все остальное
Вот так как-то, надеюсь поможет хотя бы маленько
P.S. да тут вообще никак не хукается и не используется DirectX и остальное, все через игровые классы-обёртки над рендером, поэтому и получается делать монолитные чамсы на всю модельку персонажа а не на отдельные его части
Спасибо за нормальный ответ! +rep
 
Назад
Сверху Снизу