Форум программистов, компьютерный форум, киберфорум
OpenGL
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/4: Рейтинг темы: голосов - 4, средняя оценка - 5.00
1 / 1 / 0
Регистрация: 04.01.2016
Сообщений: 62

Геометрический шейдер не работает, как предполагается

21.04.2024, 12:08. Показов 948. Ответов 16

Студворк — интернет-сервис помощи студентам
Добрый день. Простой пример с геометрическим шейдером, но не получается отладить. В вершинный шейдер подаются на вход точки и VBO с флагами. Геом. шейдер в точках в зависимости от флага рисует треугольники. Хочу пошагово отладить в ShaderEd, но при запуске отладки на этом примере программа вылетает.

shaderConstraint.vert
glSlang
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#version 330 core
 
layout(location = 0) in vec3 aPosition;
layout(location = 1) in float aConstraintType;
 
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
 
out VS_OUT {
    float indicator;
} vs_out;
 
void main(void)
{
    gl_Position = vec4(aPosition, 1.0) * model * view * projection;
    vs_out.indicator = aConstraintType;
}
shaderConstraint.glsl
glSlang
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#version 330 core
layout (points) in;
layout (triangle_strip, max_vertices = 10) out;
 
in VS_OUT {
    float indicator;
} gs_in[];
 
void DrawArrow(vec4 position, float indicator)
{    
    if (indicator != 1) 
    {
        gl_Position = position;
        EmitVertex();
        gl_Position = position + vec4(-0.03, -0.05, -0.01, 0.0);
        EmitVertex();
        gl_Position = position + vec4(0.03, -0.05, -0.01, 0.0);
        EmitVertex();
        EndPrimitive();
    }
    if (indicator != 0) 
    {
        gl_Position = position;
        EmitVertex();
        gl_Position = position + vec4(-0.05, 0.03, -0.01, 0.0);
        EmitVertex();
        gl_Position = position + vec4(-0.05, -0.03, -0.01, 0.0);
        EmitVertex();
        EndPrimitive();
    }
}
 
void main() {    
    DrawArrow(gl_in[0].gl_Position, gs_in[0].indicator);
}
shaderConstraint.frag
glSlang
1
2
3
4
5
6
7
8
#version 330
 
out vec4 outputColor;
 
void main()
{
    outputColor = vec4(1.0, 0.0, 0.0, 1.0);
}
Миниатюры
Геометрический шейдер не работает, как предполагается  
Вложения
Тип файла: rar ShaderDebug.rar (1.7 Кб, 4 просмотров)
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
21.04.2024, 12:08
Ответы с готовыми решениями:

Как передать массив int в геометрический шейдер
И как работать с этим массивом в шейдере через индексы, или просто, как с ним работать?

Простой геометрический шейдер
Здравствуйте! Не так давно стал периодически заниматься OpenGl и вот возникла необходимость в отрисовке толстых и пунктирных линий (за...

Геометрический шейдер и varying
Здравствуйте Скоро понадобится геометрический шейдер, вот изучаю матчасть. Не понял одну вещь, пример - в вертексном шейдере я...

16
1925 / 786 / 110
Регистрация: 01.10.2012
Сообщений: 4,452
Записей в блоге: 2
21.04.2024, 16:39
1. Геометрический шейдер не "добавляет" а "замещает"

2. Откуда такой порядок умножения? (первоисточник ?)
C++
1
gl_Position = vec4(aPosition, 1.0) * model * view * projection;
3. Наверно Вы хотите рисовать треугольники одинаково независимо от расстояния до камеры и размера окна вывода. Об этом нужно заботиться самому, напр так

C++
1
2
3
4
5
6
7
const float sideA = 4.0;
const float sideB = 6.0;
 
uniform float screen_half_x; 
uniform float screen_half_y; 
...
gl_Position = (position / position.w + vec4(-side_B / screen_half_x, side_A / screen_half_y, 0.0)) * position.w;
1
1 / 1 / 0
Регистрация: 04.01.2016
Сообщений: 62
21.04.2024, 17:09  [ТС]
Igor3D, я пишу на C#, библиотека openTK, там порядок умножения другой.
С координатами и преобразованиями все ок. Выводится как я хочу. Единственная проблема с передачей индикатора треугольника через интерфейсный блок. Не могу понять что не так и не могу пошагово отладить в ShadeEd, потому что он вылетает просто. Патовая ситуация))
На картинке приложенный вывод.
У меня два буфера VBO: в одном вершины, в которых надо нарисовать треугольньки. Допустим как на картинке это 4 точки, соответственно там 12 элементов в буфере. И во втором VBO индикаторы, которые геом. шейдер читает и выбирает один или два треугольника нарисовать. На каждую вершину по одному индикатору. Но при этом если я создаю VBO из 4-х элементов, то геом. шейдер не во всех вершинах рисует треугольники. Нужно создавать больше. Из этого я делаю вывод, что геом. шейдер за рах читает из буфера больше одного индикатора, хотя я когда привязывал атрибут указал, что нужно читать один элемент.
Фрагмент кода с привязкой атрибута:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public override void Initialize(uint[] indices, params BufferObject[] vbos)
        {
            var vbo = vbos[0];
            var vboDeformed = vbos[1];
            var vboConstraintType = vbos[2]; //Индикаторы для рисования треугольников в вершинах
 
            _shader.Use();
            var vertexLocation = _shader.GetAttribLocation("aPosition");
            var constraintType = _shader.GetAttribLocation("aConstraintType");
 
            _vao.Initialize(vbo, indices);
            _vao.AttachBuffer(VBOEnum.ConstraintType, vboConstraintType);
            _vao.AttribPointer(VBOEnum.Node, vertexLocation, 3, AttribType.Float, 3 * sizeof(float), 0); //Привязка координат вершин
            _vao.AttribPointer(VBOEnum.ConstraintType, constraintType, 1, AttribType.Float, 1 * sizeof(float), 0); //Привязка индикатора
            _vao.Deactivate();
        }
Миниатюры
Геометрический шейдер не работает, как предполагается  
0
1925 / 786 / 110
Регистрация: 01.10.2012
Сообщений: 4,452
Записей в блоге: 2
21.04.2024, 18:53
Цитата Сообщение от радист морзе Посмотреть сообщение
Но при этом если я создаю VBO из 4-х элементов, то геом. шейдер не во всех вершинах рисует треугольники. Нужно создавать больше. Из этого я делаю вывод, что геом. шейдер за рах читает из буфера больше одного индикатора, хотя я когда привязывал атрибут указал, что нужно читать один элемент.
Я бы порисовал тр-ки разными цветами прописав "indicator" разными значениями. И/или завязать цвет на индекс примитива (напр красный канал индикатор, зеленый индекс). И вообще, отладчик для шейдеров - слишком шикарно
0
 Аватар для zayats80888
6344 / 3515 / 1428
Регистрация: 07.02.2019
Сообщений: 8,981
21.04.2024, 19:43
Цитата Сообщение от радист морзе Посмотреть сообщение
Фрагмент кода с привязкой атрибута:
Но у вас там используется всего один буфер для атрибутов, вот этот:
Цитата Сообщение от радист морзе Посмотреть сообщение
_vao.AttachBuffer(VBOEnum.ConstraintType , vboConstraintType);
0
1 / 1 / 0
Регистрация: 04.01.2016
Сообщений: 62
21.04.2024, 20:11  [ТС]
zayats80888, буфер с вершинами цепляю в методе "_vao.Initialize(vbo, indices)". Оба буфера VBO и вершины и индекса норм целяются, прохожу дебаггером и вижу, что метод "GetAttribLocation" возвращает из шейдера корректный layout. Я не уверен, но кажется проблема в том, что я неправильно передаю данные через интерфейсный блок.
Igor3D, пример с цветами понятен. Конкретно эту задачу с такой постановкой получится решить. Но у меня есть планы по расширению функционала. И хотелось бы на будущее разобраться как правильно передавать массивы данных в геом. шейдер.
0
 Аватар для zayats80888
6344 / 3515 / 1428
Регистрация: 07.02.2019
Сообщений: 8,981
21.04.2024, 20:20
Цитата Сообщение от радист морзе Посмотреть сообщение
Я не уверен, но кажется проблема в том, что я неправильно передаю данные через интерфейсный блок
Нет, с шейдером все в порядке. Вы скорее всего напортачили с AttribPointer.
Я не знаком с api opentk, но в чистом opengl вызов glVertexAttribPointer ассоциирует атрибут с данными в буфере, который привязан к GL_ARRAY_BUFFER на момент вызова.

Можете дать ссылку на документацию к методам, которые вы вызываете для _vao, или это ваши рукописные методы?
1
1 / 1 / 0
Регистрация: 04.01.2016
Сообщений: 62
21.04.2024, 21:24  [ТС]
zayats80888, в моем понимании openTk просто обертка над функциями opengl. У меня для VAO, VBO, EBO свои классы. Можно посмотреть код по ссылкам.
Код объекта сцены для рендеринга, строка 127:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public override void Initialize(uint[] indices, params BufferObject[] vbos)
        {
            var vbo = vbos[0];
            var vboDeformed = vbos[1];
            var vboConstraintType = vbos[2];
 
            _shader.Use();
            var vertexLocation = _shader.GetAttribLocation("aPosition");
            var constraintType = _shader.GetAttribLocation("aConstraintType");
 
            _vao.Initialize(vbo, indices);
            _vao.AttachBuffer(VBOEnum.ConstraintType, vboConstraintType);
            _vao.AttribPointer(VBOEnum.Node, vertexLocation, 3, AttribType.Float, 3 * sizeof(float), 0);
            _vao.AttribPointer(VBOEnum.ConstraintType, constraintType, 1, AttribType.Float, 1 * sizeof(float), 0);
            _vao.Deactivate();
           
           ...
        }
Код объекта VAO где я привязываю атрибуты шейдера к буферам VBO, при этом перед этим я активирую нужный мне VBO, строка 47:
C#
1
2
3
4
5
6
7
8
public void AttribPointer(VBOEnum typeVBO, int index, int elementsPerVertex, AttribType type, int stride, int offset)
        {
            _typeToVBO[typeVBO].Activate();
 
            _attribsList.Add(index);
            GL.EnableVertexAttribArray(index);
            GL.VertexAttribPointer(index, elementsPerVertex, (VertexAttribPointerType)type, false, stride, offset);
        }
0
 Аватар для zayats80888
6344 / 3515 / 1428
Регистрация: 07.02.2019
Сообщений: 8,981
21.04.2024, 22:29
Цитата Сообщение от радист морзе Посмотреть сообщение
Можно посмотреть код по ссылкам.
Вроде верно, но мне трудно в шарпе ориентироваться.

Только я так и не увидел демонстрации проблемы. Можно пример содержимого буфера индексов, вершин и индикаторов, и соответствующую этим данным некорректную картинку.
0
1 / 1 / 0
Регистрация: 04.01.2016
Сообщений: 62
21.04.2024, 23:15  [ТС]
zayats80888, на картине приложил три варианта. Правильынй вывод по графике должен быть такой, чтобы при буфере индикаторов VBO из четрых вершин {2; 2; 2; 2} в каждоый вершине отрисовалось по 2 треугольника.
Ошибка заключается в том, что сейчас при таком буфере норм отрисовывается только первая вершина. Если я увеличиваю буфер вдвое, то отрисовываются нормально уже три вершины. А если х3, то все четыре вершины.
Какой-то логический вывод что здесь происходит у меня не получилось сделать)) Напрашивается проверить звено передачи данных из VBO индикатор в шейдер, но я его уже до дыр засмотрел так что хз.
Миниатюры
Геометрический шейдер не работает, как предполагается  
0
 Аватар для zayats80888
6344 / 3515 / 1428
Регистрация: 07.02.2019
Сообщений: 8,981
21.04.2024, 23:22
Лучший ответ Сообщение было отмечено радист морзе как решение

Решение

Цитата Сообщение от радист морзе Посмотреть сообщение
на картине приложил три варианта.
Ну елки палки...
У вас в буфере индексов {0, 4, 5, 9}. Откуда шейдеру брать данные, если их только максимум для индекса 3?

Добавлено через 1 минуту
Еще раз уточню, количество элементов в буфере индикаторов не может быть меньше, чем максимальный индекс + 1
(по факту их должно быть столько же, сколько вершин в буфере вершин).
0
1925 / 786 / 110
Регистрация: 01.10.2012
Сообщений: 4,452
Записей в блоге: 2
22.04.2024, 01:41
А зачем здесь EBO если можно рисовать точки с помощью DrawArrays? Это и объективно лучше т.к. индексов обычно больше.

Цитата Сообщение от радист морзе Посмотреть сообщение
Но у меня есть планы по расширению функционала. И хотелось бы на будущее разобраться как правильно передавать массивы данных в геом. шейдер.
Да никак, в том смысле что данных "per facet" все равно не передать. Для layout (points) доступны обычные/вертексные атрибуты, но это все.

Пример: полигоны (для простоты треугольники) имеют цвета (по одному на тр-к). Но нарисовать это "чисто шейдером", увы, не удается
zayats80888, поправьте если не так
0
 Аватар для zayats80888
6344 / 3515 / 1428
Регистрация: 07.02.2019
Сообщений: 8,981
22.04.2024, 18:08
Цитата Сообщение от Igor3D Посмотреть сообщение
Пример: полигоны (для простоты треугольники) имеют цвета (по одному на тр-к). Но нарисовать это "чисто шейдером", увы, не удается
zayats80888, поправьте если не так
Возможно я не понял о чем вы говорите, но можно же массив через UBO, например, передать, а тот же gl_PrimitiveIDIn использовать в качестве индекса.
0
1 / 1 / 0
Регистрация: 04.01.2016
Сообщений: 62
22.04.2024, 21:52  [ТС]
zayats80888, 2 дня думал что же тут не так)) Большое спсибо. Замылился глаз, совсем не подумал, что если я вывожу графику с использованием EBO, то все привязанные буферы VBO будут считываться согласно этих индексов
0
22.04.2024, 22:09

Не по теме:

Цитата Сообщение от радист морзе Посмотреть сообщение
Замылился глаз
бывает

0
1925 / 786 / 110
Регистрация: 01.10.2012
Сообщений: 4,452
Записей в блоге: 2
23.04.2024, 12:48
Цитата Сообщение от zayats80888 Посмотреть сообщение
Возможно я не понял о чем вы говорите, но можно же массив через UBO, например, передать, а тот же gl_PrimitiveIDIn использовать в качестве индекса.
Говорю о вечной проблеме OpenGL - данные/атрибуты передаются для вертексов (per vertex), нет передачи напр для каждого треугольника или др примитива (per facet). А примитивы могут иметь свой цвет, материал и.т.п., и это не вертексы. UBO хорошо подходит напр для передачи массива лайтов которых может быть десятки, ну сотни. Но не для фейсов, не та емкость. Геометрический шейдер - очень полезная вещь, но данной проблемы он не решает.
0
 Аватар для zayats80888
6344 / 3515 / 1428
Регистрация: 07.02.2019
Сообщений: 8,981
25.04.2024, 15:14
Цитата Сообщение от Igor3D Посмотреть сообщение
Но не для фейсов, не та емкость.
С появлением SSBO эта проблема перестала быть актуальной.
Цитата Сообщение от Igor3D Посмотреть сообщение
Геометрический шейдер - очень полезная вещь, но данной проблемы он не решает.
Идентификатор примитива доступен и в фрагментном шейдере.

Но в целом согласен, либо атрибуты вершин, либо вся группа примитивов в draw call (или отдельный инстанс в нем).
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
25.04.2024, 15:14
Помогаю со студенческими работами здесь

Что делает геометрический шейдер?
Что делает геометрический шейдер и какие его отличия от вершинного?

Геометрический шейдер
Есть следующий геометрический шейдер #version 130 #extension GL_ARB_geometry_shader4 : enable // GEOMETRY_VERTICES_OUT_ARB ...

Построение плоскости по отрезкам [GLSL, геометрический шейдер]
В геометрический шейдер прилетает отрезок с координатами точек X1 и X2, у каждой точки есть свой вектор нормали N1 и N2 (они лежат в одной...

Метод set() у ArrayList не работает как предполагается
Я хочу присвоить значения ArrayList'a coefficients в переменным, которые занесены в другой ArrayList, чтобы не прописывать это вручную, но...

Сравнение строк. If работает не так, как предполагается
Добрые люди) спасите и помогите. Разбила уже код как только могла. При вводе любого числа выдает ошибку, так как в процедуре...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
Сравнение GCC 14 и Clang 18 компиляторов C для HPC
bytestream 08.06.2025
В высокопроизводительных вычислениях (HPC) выбор компилятора - это ход, способный радикально изменить производительность всей системы. Работая последние 15 лет с критическими HPC-системами, я видел. . .
Всё о конфигурации ASP.NET Core
stackOverflow 08.06.2025
Старый добрый web. config, похоже, отправился на пенсию вместе с классическим ASP. NET. За годы работы с различными проектами я убедился, что хорошо организованная конфигурация – это половина успеха. . .
dev-c++5.11 Продолжаю движение.
russiannick 08.06.2025
Казалось, день прошел впустую. Просмотрел кучу видео и только потом заметил заголовок - уроки си. Искусители сбивали новичка с пути с++. Так легко ошибиться когда вокруг столько яп содержащих в. . .
Квантовые алгоритмы и обработка строк в Q#
EggHead 07.06.2025
Квантовые вычисления перевернули наше представление о том, как работать с данными, а Q# стал одним из ключевых языков для разработки квантовых алгоритмов. В традиционых системах мы оперируем битами —. . .
NUnit и C#
UnmanagedCoder 07.06.2025
В . NET существует несколько фреймворков для тестирования: MSTest (встроенный в Visual Studio), xUnit. net (более новый фреймворк) и, собственно, NUnit. Каждый имеет свои преимущества, но NUnit. . .
с++ Что нового?
russiannick 06.06.2025
Продолжаю обзор dev-cpp5. 11. Посмотрев на проекты, предоставленные нам для обучения, становится видно, что они разные по содержащимся файлам где: . dev обязательно присутствует . cpp/ . c один из них. . .
WebAssembly в Kubernetes
Mr. Docker 06.06.2025
WebAssembly изначально разрабатывался как бинарный формат инструкций для виртуальной машины, обеспечивающий высокую производительность в браузерах. Но потенциал технологии оказался гораздо шире - она. . .
Как создать первый микросервис на C# с ASP.NET Core, step by step
stackOverflow 06.06.2025
Если говорить простыми словами, микросервисная архитектура — это подход к разработке, при котором приложение строится как набор небольших, слабо связанных сервисов, каждый из которых отвечает за. . .
Рисование коллайдеров Box2D v2 на Three.js с помощью порта @box2d/core
8Observer8 06.06.2025
Используется порт Box2D v2 под названием @box2d/ core - пакет NPM. Загрузил документацию Box2D v2 на Netlify: https:/ / box2d-v2-docs. netlify. app/ Документацию Box2D v2 можно скачать с официального. . .
Как создать стек в Python
AI_Generated 05.06.2025
Как архитектор с более чем десятилетним опытом работы с Python, я неоднократно убеждался, что знание низкоуровневых механизмов работы стеков дает конкурентное преимущество при решении сложных задач. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru
OSZAR »