Задать вопрос
  • Как правильно организовать соприкосновения поверхностей при инстансинге?

    @MarkusD Куратор тега C++
    NimuraF
    Я вот просто никак не могу уложить эту идею в голове

    Это потому что сейчас у тебя что-то сделано, прямо скажем, неправильно. :)

    Для завершения своего прошлого этапа ты пришел к определенному решению и сделал определенные действия. Это привело к тому, что для тебя текущий твой этап стал нерешаемым стандартными методами.
    Это нормально. Так работает метод проб и ошибок.

    Тебе надо откатиться назад и решить прошлый этап иначе. Одна матрица на весь массив инстансов - это легкое решение, которое не решает ничего. В буквальном смысле ты закрыл себе дорогу к разным траекториям движения капель, к эффектам ветра, к определению столкновений капель. Много к чему.
    Эта матрица означает что весь массив капель является единым неразрывным объектом, с которым взаимодействовать можно только целиком.
    Матричное преобразование - тяжелая штука. Тебе же на CPU нужно работать с значениями aOffset, именно они у тебя сейчас обозначают физическую позицию каждой капли. Посчитать 2D координату проще даже для 200к инстансов чем посчитать матрицу и выполнить с ней операцию на всех инстансах. А передается твой буфер aOffset на GPU сравнительно так же быстро, как и та же матрица. Иными словами, матрица - это просто альтернативное решение. Неудачное альтернативное решение.
    Когда на CPU посчитаешь все 200 точек капель для очередной их отрисовки, у тебя появятся все нужные данные чтобы проверить коллизии каждой капли по отдельности все на том же CPU.
  • Как правильно организовать соприкосновения поверхностей при инстансинге?

    @MarkusD Куратор тега C++
    NimuraF, это потому что ты пробуешь определять столкновение в шейдере. :)
    А этого там делать совсем не нужно. Шейдер - для отрисовки уже готового состояния. Т.е. капля в момент отрисовки уже должна быть посчитана как столкнувшаяся. И или ты ее инстанс просто убрал из буфера, или для нее у тебя что-то такое заведено в атрибутах инстанса, что скажет шейдеру выкинуть весь примитив из дальнейшей обработки.

    Считай столкновения просто на CPU в отдельной функции до отрисовки. У тебя там будет очень простая математика пересечения двух отрезков или пересечения двух прямоугольников.
  • Как правильно организовать соприкосновения поверхностей при инстансинге?

    @MarkusD Куратор тега C++
    NimuraF, если тебя интересует только визуальная часть столкновения капли с препятствием и чтобы дальше капля не обсчитывалась, то это можно сделать примерно так. На выбор есть два варианта.
    Ты ведь все равно пересчитываешь позиции инстансов капель и каждый раз заново набиваешь буфер значениями. Просто при набивании буфера позиций инстансов выкидывай те капли, которые модель столкновений уже посчитала попавшими на поверхность. Набиваешь буфер позиций инстансов, запоминаешь его размер и используешь этот размер в glDrawArraysInstanced.
    Само событие столкновения, реакцию на него и порождение брызг можно сделать на CPU. И брызги, кстати, можно тоже инстансингом рисовать, а считать тоже в модели физики.

    Вот так
    if ((result.x < -0.5 && result.y > -0.5) || (result.x > 0.5 && result.y > -0.5) || (result.x >= -0.5 && result.x <= 0.5 && result.y > 0.5))
        gl_Position = result;

    отрисовку, ты уже понимаешь, не остановить. Вершинный шейдер остановить невозможно. discard можно применять только в пиксельном шейдере. Преждевременный return без установки gl_Position ведет к неопределенному поведению. gl_Position нужно всегда определять.
    Но мы в больших движках уже давно придумали выход из такой ситуации. Мы просто в таких случаях позиционируем вершину за пределами видимой области.
    gl_Position = vec4( -1.0, -1.0, -1.0, 0.0 ); не портит порядок обработки вершин. Если это сделать для всего примитива, то он будет выброшен из дальнейшей обработки целиком.
  • Не могу создать класс персонажа в UE5 на с++. Что делать?

    DoniUrano
    Всем привет.

    П3.4 регламента работы сервиса. Регламент ты перед написанием вопроса читал, соблюдать его согласился, но не соблюдаешь.

    Новичок в программировании, изучаю unreal, вместе с ним с++.

    Это взаимоисключающие направления. Сперва тебе надо получить достаточную квалификацию в C++. UE сложен сам по себе, а для тебя с ним работать сейчас вообще невозможно.

    логи я читать не умею, поэтому вообще не понимаю, что делать((.

    П5.12 регламента работы сервиса. Тут так нельзя. Переходи на фриланс, создавай задачу, назначай стоимость.
  • Почему не получается передать указатель на вектор в класс?

    @MarkusD Куратор тега C++
    Kryptonit, ну так запусти и выпиши сюда все ошибки, по которым у тебя вопросы.
  • Почему не получается передать указатель на вектор в класс?

    @MarkusD Куратор тега C++
    Kryptonit , а что это за ошибки, ты нам не расскажешь видимо?
    Как тогда отвечать на твой вопрос?
  • Как реализовать шаблонный оператор\функцию, чтобы скрыть < и > символы после объявления?

    @MarkusD Куратор тега C++
    yatanai, да, ты все правильно понимаешь.
    У тебя есть вариант такой реализации:
    template<typename T>
    bool at(T*& storage, size_t n);

    Возвращай true только когда заполнил storage правильным значением.
    В этом случае тебе не надо будет указывать шаблонный аргумент при инстанцировании.
  • Почему не срабатывает смещение при инстансинге?

    @MarkusD Куратор тега C++
    NimuraF, с решением я всегда рад помочь. :)
    По поводу условий существования: ты всегда можешь оформить новый вопрос. Я и все остальные подскажем тебе решение с радостью.
  • Какой компилятор выбрать для C++?

    @MarkusD Куратор тега C++
    Vladimir Nesterow
    Здравствуйте, господа.

    П3.4 регламента работы сервиса. Постарайся больше не нарушать.

    Не кидайте камнями, если похожий вопрос был.

    П2.2 регламента. У тебя есть обязанность перед размещением вопроса проверить его на дубликаты. И опять же, П3.4.
  • Как умножить матрицы с помощью SSE?

    @MarkusD Куратор тега C++
    Марат Нагаев, П3.1, П3.4, П5.12 регламента.
    Ты здесь уже давно, с правилами уже должен быть знаком.
  • Как реализовать шаблонный оператор\функцию, чтобы скрыть < и > символы после объявления?

    @MarkusD Куратор тега C++
    yatanai, есть только два способа запустить автоматический механизм вывода шаблонных параметров.
    Первый способ - это написать конструктор шаблона класса в C++17 и дальше, типы параметров которого будут взяты из аргументов шаблона.
    Второй способ - это написать шаблон функции, типы параметров которой взяты из аргументов шаблона.
    У тебя не сделано ни то, ни это. У тебя нет шансов на автоматический вывод шаблонных аргументов.
  • Возможно сделать иначе?

    @MarkusD Куратор тега C++
    mayton2019, а тег какой на вопросе стоит?
  • Почему не срабатывает смещение при инстансинге?

    @MarkusD Куратор тега C++
    NimuraF, пошли по порядку. :)
    Честно говоря, не совсем понимаю, что из себя представляет этот самый массив из вектор с n=2, загруженный в буфер

    Любой буфер - это просто кусок данных. Буферы атрибутов - это буквально типизированные массивы.
    GLfloat raindrops[] - тут у тебя закодировано 6 вершин. Ты мог бы сделать и такое объявление: glm::vec3 raindrops[], проинициализировав элементы массива должным образом. Разницы было бы никакой.
    glm::vec2 translations[100] можно объявить как GLfloat translations[300] и разницы будет тоже никакой.
    С т.з. OGL память translations и память raindrops - это просто память чтобы заполнить буфер. Под вопросом для GPU остается только то, как эту память нужно интерпретировать чтобы получить атрибуты.

    Вот на примере того же квадрата, я загружаю в VBO 6 вершин, указываю шаг в 3 элемента (3 координаты) и на основе этого opengl отрисовывает мне пресловутый квадрат.

    Это неправильное понимание процессов. Правильным является такое понимание.
    GLfloat raindrops[] - это данные буфера позиций вершин примитива на стороне CPU.
    glBufferData(GL_ARRAY_BUFFER, sizeof(raindrops), raindrops, GL_STATIC_DRAW);
    - переносим данные буфера позиций из памяти CPU в память GPU.
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
    - указываем, что каждый атрибут позиции вершины представлен тремя компонентами без нормализации и с типом float в буфере, а смещение между двумя атрибутами в буфере равно 12Б(3 * sizeof(GLfloat) == 12). При этом, базовое смещение внутри буфера до первого атрибута отсутствует.
    Т.е. этой функцией производится настройка методики выборки атрибутов из буфера. Этот буфер ты связываешь с нулевым потоком атрибутов шейдера, а в шейдере у тебя что? А в шейдере у тебя layout (location = 0) in vec3 aPos;, т.е. атрибут на три вещественных компонента.

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

    Здесь же я, по сути, делаю то же самое, только aOffset - это какой-то длинный пак данных, в котором я просто указываю шаг через glVertexAttribDivisor(1, 6)?

    Тут я ошибся с аргументами, неправильно их вспомнил. Должно быть вот так: glVertexAttribDivisor(1, 1);.
    Т.е. за один инстанс обрабатывается один атрибут этого буфера. glVertexAttribDivisor(1, 6); означает что один атрибут обрабатывается за 6 инстансов. Через эту настройку можно управлять группировкой атрибутов между инстансами.
    Вызов этой функции - это дополнительная инструкция для методики выборки атрибутов.
    glVertexAttribDivisor(1, 1); - выбирать следующий атрибут только для следующего инстанса, а не для следующей вершины.

    Так же небольшой нюанс возник с VAO, вот, допустим, я передаю те самые 2 (0 и 1) атрибута, т.е. мой VAO будет выглядеть следующим образом

    Тут я не смогу тебя направить. Я не пользуюсь VAO потому что всегда пишу кроссплатформенный код. VAO - это нотация OGL, а в DX, MTL и прочих GAPI этой нотации нет. С этим вопросом тебе стоит разобраться самостоятельно, правильно ли у тебя там все. Внешне, насколько я знаю теорию, у тебя там все правильно.

    Так же я немного не понял вот эту строчку в шейдере:

    Ты прав, тут несовпадение размерностей. Их надо выровнять. Это я, просто, не сильно старался вычитывать код и кусками его составлял из твоего.
    Можно сделать вот так: vec4(aPos.xy + aOffset, 0.0, 1.0);.
    Можно так: vec4(aPos + vec3(aOffset, 0.0), 1.0);
    Вариантов много. Надо просто выбрать правильный для тебя.

    Теперь при инстансинге у тебя выборка атрибутов будет такой: сперва пойдет обработка примитива первого инстанса и начнут перебираться атрибуты нулевого потока. Когда все 6 атрибутов будут выбраны, нулевой поток сбросится на начало, в первом потоке произойдет выборка следующего атрибута и пойдет обработка примитива для следующего инстанса.

    И немного ещё не разобрался с вызовом, для подобной схемы вызов тех самых инстансов может производиться следующим образом?

    Все верно. Главным является вызов glDrawArraysInstanced. Именно он запускает отрисовку с инстансингом. Все остальное остается как есть, независимо от состояния инстансинга.
    Т.е. если до отрисовки с инстансингом у тебя рисовался один примитив, то включение инстансинга, как минимум, не должно сломать это поведение.

    А насчёт RenderDoc, я, в общем-то, его поставил и вроде как с базовыми механиками подразобрался, но у меня возникло небольшое недопонимание с анализом самого кадра.

    С его освоением лучше не торопиться. Лучше посмотреть видео и почитать статьи, хоть на том же хабре.
    Причину, почему у тебя рисуется только один инстанс, я даже придумать не могу, честно говоря. Чтобы строить догадки, мне нужно самостоятельно запустить код и приглядеться к его поведению. А на это у меня просто нет времени. Думаю, ты это хорошо понимаешь по времени моих комментариев.
    Если тебе интересно зайти в графику, то подружись с отладчиком. Чем дальше в этот лес ты пойдешь, тем сильнее он тебе потребуется.
  • Какое направление в Unreal Engine для изучения стоит выбрать тем, кто хочет найти работу без опыта ком. разработки?

    Molotenchuk,
    можно не рассчитывать даже на удалёнку от переехавших российских компаний?

    Даже на удаленку. Геймдев покидает страну в данное время.
  • Как найти работу без опыта?

    Нуржан Мурзахмет
    Успешная молодая бизнес-вумен сорока лет ищет состоявшегося мужчину-девственника 25 лет с 20-летним опытом в сексе.

    Примерно так, да :)

    Фронтенд - это перенасыщенная ниша занятости. И это не спроста так, порог вхождения тут очень низкий.
    Чтобы тебя взяли без опыта работы, тебе надо показывать буквально выдающиеся результаты или перейти туда, где конкуренция между соискателями ниже.
  • Почему не срабатывает смещение при инстансинге?

    @MarkusD Куратор тега C++
    NimuraF, в этих пяти строчках раскрывается отношение к коду непрофессионала и профессионального инженера.
    Ты, вроде бы, используешь удобные для чтения идентификаторы, по которым складывается первое впечатление о смысле. Это правильно. Но с другой стороны, ты код не даешь человеку прочитать одним взглядом. Это в целом ломает удобство чтения твоего кода. А пишешь ты его всегда именно для читателя, особенно сейчас в вопросе.
    Просто прими это к сведению.

    Я посмотрю код, но уже вечером. Навскидку в нем много нестыковок.
    aPos + offset - размерность надо выровнять.
    uniform vec2 offsets[100]; - какой размер одного элемента? Думаю - 16Б.
    glGetUniformLocation(...); - так можно, но загрузка значений для массивов делается иначе.
  • Почему не срабатывает смещение при инстансинге?

    @MarkusD Куратор тега C++
    NimuraF , освободи код шейдеров от мишуры кавычек.
    Используй или сырые строки (6), или просто перепиши сюда только их текст.
    Сейчас код шейдеров нечитаемый.
  • Как исправить ошибку сборки проекта?

    @MarkusD Куратор тега C++
    Stradus3 , сейчас твой вопрос нарушает П3.8 регламента работы сервиса.
    Тебе слудет убрать все скриншоты, правильно оформить свой код и показать текст ошибок из лога сборки проекта.
  • Как перевести текст в битовую форму?

    @MarkusD Куратор тега C++
    RommB , вопрос требует уточнения. Настолько сильно требует, что есть риск удаления вопроса.
    Покажи несколько точных примеров: какой текст на входе и какое битовое представление должно быть на выходе.