Программирование игр

Игровой движок, 3D графика, сеть, физика, логика, уеб

НовостиСтатьиПодсказкиТерминыFAQФорумИнфо

Статьи

8 ноя 2022

В программировании игр часто приходится ссылаться на объекты, используя строковые идентификаторы: например, получить текстуру по имени её файла или найти актора по его имени. Однако, хранение и частое сравнение большого количества строк может оказаться дорогим как с вычислительной точки зрения, так и с точки зрения используемой памяти.

Читать | Комментарии [39]

7 ноя 2022

Coroutine (сопрограмма, корутина) — функция, выполнение которой можно явно прерываться методами языка программирования. В отличие от прерывания выполнения потока (thread), который реализован в ОС и происходит неявно и в любой момент. Здесь я разбираю в чем преимущество корутин и какие корутины добавлены в C++20.

Читать | Комментарии [58]

Recursive Tile-based architecture
Имитация раскачивания дерева под воздействием ветра
Освещение с использованием фотометрического профиля
Гидродинамика Шрёдингера на пальцах

Термины

2 дек 2023

Godot Game Engine

Godot (читается как «Годо», от фр. Godot) — кроссплатформенный игровой движок и редактор для 2D и 3D игр, с открытым исходным кодом под лицензией MIT. Изначально был разработан в 2007 году Хуаном Линиецки и Ариэлем Манзур. Core движка разрабатывается на C++.

Читать | Комментарии [15]

5 июня 2018

Universal Scene Description (USD)

Universal Scene Description (USD) — файловый формат описания трехмерной сцены, разработанный компанией Pixar.

Читать

Verge3D
Вуду-программирование
Blend4Web

Подсказки

10 мая 2020

MAX Script: Разделение 3D модели на элементы по группам нормаль векторов.

Здесь представлен скрипт 3D Studio MAX, при помощи которого можно разделить 3D модели на элементы по группам нормалей, также смотрите «MAX Script: Разделение 3D модели на элементы по группам сглаживания».

Читать

Delphi: Точный таймер (Win API)
^ Матрица LookAt
Инверсия матрицы 4x4

Новости

6 фев 2022

Вышла книга 3D Graphics Rendering Cookbook: A comprehensive guide to exploring rendering algorithms in modern OpenGL and Vulkan авторов Sergey Kosarevsky (_NetSurfer_) и Viktor Latypov (Vinil)

Ссылка | Комментарии [50]

8 апр 2020

Выложили мой доклад с exilecon. В нём я рассказываю о нескольких необычных техниках рендеринга, разработанных для Path of Exile. Доклад на английском языке. Есть русские субтитры.

Запустить видео по клику - Как делать игрыЗапустить видео по клику - Как делать игры

Ссылка | Комментарии [69]

4 мар 2019

Опубликована PDF-книга «Ray Tracing Gem. High-quality and real-time rendering with DXR and other APIs» на 600+ страниц, подготовленная NVIDIA и разными специалистами из области рейтрейсинга. Можно скачать отсюда:
https://link.springer.com/book/10.1007/978-1-4842-4427-2

Ссылка | Комментарии [7]

20 мар 2018

На проходящей в Сан-Франциско конференции разработчиков игр (GDC) компания Microsoft анонсировала поддержку в DirectX 12 технологии DirectX Raytracing (DXR). Новый программный интерфейс позволяет производить просчет рейтрейсинга при помощи поддержки этой технологии в железе.

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

SEED-screenshot | Microsoft анонсировала DirectX Raytracing (DXR)

Ссылка | Комментарии [504]

Форум

22 июня 2024

Предлагаю постить здесь всякие полезные плюшки, начнём.

Есть более быстрый способ вычислить минимальное расстояние между лучом и отрезком в пространстве? (ray segment intersection)  Не интересует крутая точность и проверка всех возможных вариантов, т.к. это рендер.

float RayLineSegmentDistance(vec3 rP, vec3 rD, vec3 lS, vec3 lE)
{
    float bL = length(lE - lS);
    vec3 bD = (lE - lS) / bL;
    vec3 tD = lS - rP;
    float aDb = dot(rD, bD);
    float aDt = dot(rD, tD);
    float bDt = dot(bD, tD);
    float u = (aDt - bDt * aDb) / (1. - aDb * aDb);
    float v = max(min(u * aDb - bDt, bL), 0.);
    u = max(min(v * aDb + aDt, 1e6), 0.);
    return length((rP + rD * u) - (lS + bD * v));
}

22 июня 2024

Условия: C++, 2D стрелялка, обязательная проверка столкновения всех со всеми, игнорирование некоторых типов объектов, покрывающая весь хитбокс сфера для упрощения проверки в широкой фазе, есть разбиение пространства через q-tree, многопоток и мемпул.

Проблема: это всё не помогает когда тысячи пуль спавнятся в одной точке и игрок находится рядом, начинается просчет каждого хитбокса, хотя и так понятно что все пули врезались в игрока. Можно ли оптимизировать такой случай? Я понимаю что можно просто их не спавнить в одной точке, но тогда фана не будет

Много пуль | Microsoft анонсировала DirectX Raytracing (DXR)

19 июня 2024

Ищу функцию для шейдера, возращающую псевдослучайный float 0-1 (если будет поддержка зерна, то вообще хорошо, но на такое я даже не надеюсь) и не глючащую на новых видеокартах/драйверах.

На манер такой:

vec3 p3 = vec3(uv, seed);  
p3  = fract(p3 * .1031);
p3 += dot(p3, p3.yzx + 33.33);
return fract((p3.x + p3.y) * p3.z);

но не глючащей на новых видеоартах.

На шейдер-тое неглючную не нашел, может плохо искал.
Поделитесь надежным провереным вариантом, если у кого есть.

17 июня 2024

Народ,не подскажите пожалуйста какие данные должен хранить блок в полностью разрушаемом воксельном мире? Пишу порт 7 Days To Die Alpha 1.0

12 июня 2024

Не знаю, возможно ли это в принципе, но может кто думал в сторону возможности сжатия серии SDF-функций в одну? Я про эти https://iquilezles.org/articles/distfunctions/

То есть представьте, есть большая SDF сцена и в ней есть много таких функций (поэтому она и будет лагать и тормозить), но вот если бы была математическая/программная возможность сжать серию таких функций в одну небольшую, то все бы забили на всякие RTX-ы и перешли бы на процедурный рендер. Я не говорю про растеризацию SDF сцены или про некоторые ускорения рей-марчинга, я говорю именно про то, что бы, например, вот 3 этих функции:

float sdSphere( vec3 p, float s )
{
  return length(p)-s;
}

float sdBox( vec3 p, vec3 b )
{
  vec3 q = abs(p) - b;
  return length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0);
}

float sdCone( vec3 p, vec2 c )
{
    // c is the sin/cos of the angle
    vec2 q = vec2( length(p.xz), -p.y );
    float d = length(q-c*max(dot(q,c), 0.0));
    return d * ((q.x*c.y-q.y*c.x<0.0)?-1.0:1.0);
}

сжать до одной в стиле  float sdScene( vec3 p );

Понятно, что у этой функции должны быть параметры (всякие радиусы окружностей, размер бока и пр), но все эти параметры должны быть зашиты в битовый код функции, то есть зайдя внутрь функции с позицией точки, можно было методом простых битовых операций или операций сложения/умножения получить результат для большой сцены. Ещё раз, речь не идёт про то, что бы переписать код всех функций тупо в одну, речь именно о сжатие данных.

В этом мире нет ничего невозможного, просто мы до этого ещё не додумались.

p.s.: возможно у меня есть догадки на этот счёт и связанны они с методами ИИ.

12 июня 2024

У меня есть инвентарь, есть игрок, есть меню, мне нужно чтобы при открытии меню, нельзя было открыть инвентарь, у меня возник вопрос, как лучше это реализовать, свой код приложу ниже, не нужно писать про ecs, я использую в проекте исключительно ООП

PlayerController(Логика связанная с игроком):

namespace Player
{
    
    public class PlayerController : Player
    {
        private IInputSystems _inputSystem;
        private ICameraSystem _cameraSystem;
        private void Awake()
        {
            _inputSystem = this.transform.AddComponent<KeyboardDefaultInputSystem>();
            _cameraSystem = this.transform.AddComponent<DefaultCameraSystemWithBobbing>();
        }

        void Update()
        {

            _inputSystem.Move(speed, this.gameObject);
            _cameraSystem.Camera_Rotate(sensitivity, smoothing, _camera_parent, _player);

        }
        

    }
}

MenuController(Логика связанная с меню):

public class MenuManager : MonoBehaviour
{
    private AnimationSystemFadeOutFabrics _animationFabric;
    private IAnimationSystemFadeout _animationSystem;
    [SerializeField] private Canvas _menu;
    private float _animationSpeed;
    private PauseManager _pauseManager;
    private MouseManager _mouseManager;
    private void Start()
    {
        _mouseManager = MouseManager.getInstance();
        _pauseManager = PauseManager.getInstance();
        _animationSpeed = _menu.GetComponent<InGameMenu.Menu>().animationSpeed;
        _animationFabric = new DefaultAnimationSystemFadeoutFabric();
        _animationSystem = _animationFabric.createAnimationSystemFadeout(_menu, _menu.GetComponent<CanvasGroup>(), _animationSpeed);
    }

    public void MenuOpen()
    {
        _animationSystem.Open();
        _pauseManager.PauseOn();
        _mouseManager.MouseUnlock();
    }

    public void MenuClose()
    {
        _animationSystem.Close();
        _pauseManager.PauseOff();
        _mouseManager.MouseLock();
    }

}

11 июня 2024

cbuffer cbPerObject : register(b0)
{
  float4x4 gWorldView;
};

cbuffer cbPass : register(b1)
{
  float4x4 gWorldViewProj; 
};

struct VertexIn
{
  float3 PosL  : POSITION;
    float3 Normal : NORMAL;
};

struct VertexOut
{
  float4 PosH  : SV_POSITION;
    float3 tNormal : NORMAL;
  float3 PosW : POSITION;
  float3 LightPos: POSITION1;
};

static float3 LightPos = { 0.0f, 10.0f, 0.0f };
static float3 DiffuseLightColor = { 1.0f, 1.0f, 0.5f };
static float FallOfStart = 15;
static float FallOfEnd = 15;
static float SpotPower = 0.00001;
static float3 LightDirection = { 5.0f, -5.0f, 0.0f };

VertexOut VS(VertexIn vin)
{
  VertexOut vout;
  
  vout.PosH = mul(float4(vin.PosL, 1.0f), gWorldViewProj);
  
  float4 PosW = mul(float4(vin.PosL, 1.0f), gWorldView);
  vout.PosW = PosW.xyz;
  
    vout.tNormal = mul(vin.Normal, (float3x3)gWorldView);

    vout.LightPos = mul(float4(LightPos, 1.0f), gWorldView);
    
    return vout;
}

float CalcAttenuation(float d, float falloffStart, float falloffEnd)
{
    return saturate((falloffEnd-d) / (falloffEnd - falloffStart));
}

float3 Get_Spot_Light(float3 tNormal, float3 PosW, float3 LightPosW)
{

  float3 ToLightPos = LightPosW - PosW;

  float Dist = length(ToLightPos);

  if(Dist > FallOfEnd)
    return 0;

  ToLightPos = normalize(ToLightPos);

  float3 Normal = normalize(tNormal);
  float Dot = max(dot(ToLightPos, Normal), 0.0f);

  float AttVal = CalcAttenuation(Dist, FallOfStart, FallOfEnd);

  LightDirection = normalize(LightDirection);

        float SpotFactor = pow(max(dot(-ToLightPos, LightDirection), 0.0f), SpotPower);

  return DiffuseLightColor * AttVal * SpotFactor * Dot;
  
}

float4 PS(VertexOut pin) : SV_Target
{

  float3 ResColor = Get_Spot_Light(pin.tNormal, pin.PosW, pin.LightPos);
  
  return float4(ResColor, 1.0f);

}

Делаю Spot light DirectX12, вот такой скриншот:

https://ibb.co/zh3zqPk

Мне не понятно- говориться в документации что spot light это свет от фонарика, то есть если фонарик расположен под углом к поверхности- то должно быть (приблизительно) овальное пятно света. У меня на скрине не овальное пятно света. Вот мой шейдер (работает для других источников света, провереный) объясните где я ошибся что бы пятно света было овальное.

10 июня 2024

Приветствую всех. Была такая игрулька кто помнит Head over heels 2003 года выпуска. Изометрическая бродилка.
https://github.com/dougmencken/HeadOverHeels - вот парень сделал копию этой игры. Выложил код, но игра гораздо отстает от оригинала. Хочу сделать похожую игру. Вопросы следующие:
1 Какой лучше движок выбрать для создания? (Godot, Unity … любой кастомный)
2 На чем такое лучше было бы написать? Какой язык программирования?
3 Программа для отрисовки спрайтов. Где посоветуете создавать рисунки подобного стиля?

Hoh1 | Microsoft анонсировала DirectX Raytracing (DXR)

Если кто-то разбирается в коде который отправил выше, прошу так же помощи.

С уважением.

10 июня 2024

Никогда особо с такой проблемой не сталкивалась, но вот начала передавать много данных через интерполяторы и прям пиксели яркостью 900 полезли изо всех щелей. Кто как с этим борится? Нагуглила что центройды помогают, но я не знаю насколько они бьют по перфк на мобилах.

6 июня 2024

Есть прямоугольник с текстурой какого-то текста. Прямоугольник умеет 4 точки:
P1 ——— P2
|              |
P3 ——— P4
У каждой точки есть текстурные координаты UV1(0,0),  UV2(1,0),  UV3(0,1) и UV4(1,1) соответственно.

Я вращаю orbit камеру вокруг него как угодно, но разумеется, в зависимости от поворота, этот текст переворачивается вверх ногами или пишется наоборот справа налево (culling отключен).

Вопрос: как во фрагментной шейдере реверсить текстурные координаты так, что бы текст оставался всего с нормальным написанием слева направо и чтоб буквы были не вверх тормашками?

У камеры есть все вектора (eye, up, right), то же самое можно посчитать для rect-а текста, матрицы вида и пр. Хмм.. Я пробовал разные варианты, но получается слишком много if-ов, то есть тупо ловишь все варианты и проверяешь их dot-ами всякими, в какую сторону мол смотрит, но это явно не тру вей, как можно сделать проще?

Upd: мне не нужно держать текст на текстуре чётко вровень с камерой, мне нужно что бы uv реверсились по иксу и игрику когда нужно для правильного прочтения текста.