Використання декількох шейдерів


53

В даний час я вивчаю шейдери opengl, але не можу щось зрозуміти: як застосувати різні шейдери до об'єктів, наприклад, чайник, виконаний за допомогою шейдера тонів, та ще один в тій самій сцені, використовуючи дуже відбивну поверхню та інші спотворені від функція шуму, як у цьому відео

http://www.youtube.com/watch?v=1ogg4ZfdBqU

Ще один - нанесення шейдера для цвітіння на сцену та після цього шейдер розмиття руху. Як досягти цих ефектів, коли у вас може бути лише одна вершинна шейдер і один фрагмент шейдер? Чи є якийсь трюк, такий як використання більше однієї програми шейдерів?


Добрі відповіді Ре Натана та Девіда, саме тому ви бачите термін рендеринга або шейдерного проходу ; Для складання остаточного зображення / кадру потрібно кілька проходів. Однією з причин, чому обробка GPU стала настільки проклятою паралельною і, таким чином, такою швидкою, - потреба в декількох пропусках на кадр. Поверніться до рендерів програмного забезпечення Quake II або Half Life, щоб нагадати собі, скільки пройдених шейдерів кохання додають до всього досвіду 3D-графіки.
Інженер

Відповіді:


59

Проста відповідь полягає в тому, що ви змінюєте їх між кожним розіграшем. Встановіть шейдер, намалюйте чайник, встановіть інший шейдер, намалюйте ще один чайник.

Для більш складних матеріалів, де потрібно застосувати кілька шейдерів до одного об'єкта, наприклад, розмиття, світіння тощо. В основному у вас все відтворене текстурою. Потім ви візуалізуєте чотирьохконтролер на весь ваш екран із застосованою текстурою, використовуючи інший шейдер.

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

Існує ще одна методика під назвою " Відкладене затінення", де ви створюєте сцену без освітлення та застосовуєте її пізніше в екрані. Основна мета - зменшити витрати на освітлення на один піксель.

Зазвичай ви надаєте кольоровий буфер, який розміщується на екрані. Завдяки відкладеному затіненню ви натомість надаєте кольоровий буфер, а також буфер звичайного та глибинного покроку в одному проході шейдера (ви можете зберігати нормальні вектори та глибину в текстурі, як при звичайному відображенні та висоті).

Це означає, що для кожного пікселя ви знаєте положення найближчого фрагмента непрозорої геометрії (глибина або відстань від очей) колір і нормаль. Через це ви можете застосовувати освітлення до кожного пікселя на екрані, а не до кожного видимого пікселя кожного об'єкта, який ви надаєте. Пам’ятайте, що якийсь об’єкт буде намальований поверх інших об’єктів, якщо сцена не буде ідеально відтворена перед тим, як зробити зворотній порядок.

Для тіней ви насправді представляєте лише буфер глибини з точки зору свого світла, а потім використовуєте інформацію про глибину, щоб визначити, куди потрапляє світло. Це називається тіньовим картографуванням (існує також інший підхід, який називається тіньовими обсягами, який розробляє силует геометрії та видавлює його, але ви все ще будете використовувати шейдери.).

З більш сучасним OpenGL (3.0+) ви використовуєте об'єкт Framebuffer із доданими об'єктами Renderbuffers. Оскільки до рендербуферів можна ставитися як до текстури. Ви можете зробити такі речі, як мати 1 шейдер на декількох різних рендербуферах (так що вам не доведеться надавати текстуру, то ваші нормалі, а потім компоненти світіння), але основна практика все одно така.

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


16

Ви просто зв’яжіть один шейдер, візуалізуйте всі об'єкти за допомогою цього шейдера, потім зв’яжіть наступний шейдер, візуалізуйте об'єкти за допомогою цього тощо.

Ви можете мати стільки об'єктів шейдерів (шейдери, завантажені в пам'ять і складені), скільки вам потрібно; одночасно може бути пов'язаний лише один (активний).


5
Що стосується реалізації, я в кожному кадрі використовую glUseProgram (1) та glUseProgram (2) для зміни шейдерів? Наскільки це затратна робота?
ibrabeicker

4
Це нетривіальна вартість (хоча на останніх графічних процесорах менше, ніж на попередніх). Ось чому більшість людей сортують свої предмети за матеріалами, складаючи всі об’єкти з одним і тим же матеріалом разом. Але ви, звичайно, можете дозволити собі змінити програми в десятки-сотні разів за кадр, якщо не більше.
Натан Рід

9

Використовувати більше одного шейдера в сцені досить просто; змінити шейдер, встановити для нього значення, а потім винести об'єкт.

Однак будьте обережні, перемикання шейдерів може бути дорогим, тому перемикання шейдерів повинно бути мінімальним. Є кілька способів зменшити цей вплив, отримуючи всі потрібні ефекти.

Перший спосіб і, як правило, найбажаніший, - це додати функціональність для всіх ваших методів шейдерів лише до одного шейдера та використовувати умови, які ви встановили, щоб кожен об'єкт по-різному відображав одним і тим же шейдером. Я не знаю про шейдери OpenGL та GLSL, але за допомогою шейдерів HLSL та DirectX їх можна об'єднати як "техніку", і ви можете встановити техніку замість зміни шейдера. Це дозволяє фактично мати в одному файлі кілька різних піксельних і вершинних шейдерів.

Другий спосіб зменшити вплив продуктивності - це встановити шейдер, винести кожен об'єкт, який використовує цей шейдер, а потім повторити. Іншими словами, групування вашої візуалізації.

Якщо ви хочете застосувати два різних ефекту до одного об’єкта (тобто застосувати, скажімо, тоновий шейдер, то деяке освітлення), це можна зробити двома різними способами. Перший - написати шейдер, який застосовує кілька ефектів в одній функції. Другий спосіб - відобразити модель один раз із кожним шейдером та змішати результати, встановивши різні варіанти накладання. Однак це набагато більше роботи, і не досяжна за будь-яких обставин. Тому найкращий варіант - поєднати всі свої ефекти в один шейдер.


7

Ще один спосіб, який я виявив, - це через підпрограми glsl, де кожен тип шейдерів визначається однією функцією, і в додатку OpenGL ми можемо визначити поточну підпрограму, намалювати вершину буфера, змінити підпрограму та надання іншого буфера


4
Для цього потрібне обладнання, сумісне з GL 4.x, яке є обладнанням DX11.
Нікол Болас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.