Open shluters în interpretare modernă

Open shluters în interpretare modernă

Noile versiuni ale programului OpenGL nu vă așteaptă și tot timpul, există informații că unele funcții nu mai sunt recomandate sau chiar eliminate complet. Și ceea ce vine să înlocuiască tradiționalul, funcționalul obișnuit?
Dar nimic, totul se poate face acum cu umbrele ușor. Acest lucru va fi discutat mai târziu.

Tendința este că toate funcționalitățile, fie că este vorba de modelul de iluminare, de un fel de transformări, de interpretarea datelor în texturi și așa mai departe ... Toate astea merg în umbre. Chiar și în versiunea OpenGL 2.0, ați putea face multe lucruri, dar vechea funcționalitate a rămas doar pentru compatibilitate și a fost înlocuită treptat cu metode noi, eliminând funcțiile vechi. Și, în plus, tot ceea ce se face în shadere este hardware accelerat.

A fost un moment în care mi-a fost frică să părăsesc obișnuitul și să folosesc lucruri precum shadere. Pentru mult timp mi se păreau de neînțeles, deși tutorialele despre sabzh păreau spectaculos frumoase și interesante! Și apoi, într-o zi, adunând puterea, i-am stăpânit încă (problema sa mutat dintr-un centru mort). Și acum am decis să împărtășesc un exemplu simplu de utilizare a acestora.

Abateri teoretice

Astăzi vom vorbi despre shaderele GLSL, dar GLSL nu este singurul limbaj pentru lucrul cu OpenGL.
Puteți utiliza, de exemplu, shadere în CG (C pentru grafică). Aceasta necesită o bibliotecă suplimentară NVIDIA CG.

GLSL (OpenGL Shading Language) este un limbaj de nivel înalt pentru programarea shader. Sintaxa limbii se bazează pe limbajul de programare ANSI C, totuși, datorită concentrării sale specifice, multe caracteristici au fost excluse din acesta, pentru a simplifica limba și pentru a îmbunătăți performanța. Funcții suplimentare și tipuri de date sunt incluse în limba, de exemplu, pentru lucrul cu vectori și matrice. GLSL a devenit parte integrală a OpenGL în versiunea 2.0.

Conductă grafică OpenGL 2.0

Open shluters în interpretare modernă

Vertex Shader - înlocuiește o parte a conductei grafice care efectuează transformările asociate cu datele de vârf. Cum ar fi multiplicarea vârfurilor (și normalelor) prin matricea de proiecție și modelare, instalarea culorilor vertexelor, instalarea materialelor de iluminat. Acesta va funcționa pentru fiecare vârf desenat.
Este obligatoriu ca shaderul de vârf să înregistreze poziția vertexului, în variabila construită gl_Position.

Shader geometric - un shader capabil să proceseze nu numai un vertex, ci un întreg primitiv. Poate fie să elimine (de la procesare) primitive, fie să creeze altele noi, adică un shader geometric este capabil să genereze primitive. Și, de asemenea, posibilitatea de a schimba tipul primitivelor de intrare. (Notă: shaderul geometric este pe deplin inclus în OpenGL, în versiunea 3.2)

Fragment shader - înlocuiește o parte a conductei grafice (HA) care procesează fiecare fragment obținut în etapele anterioare ale HA (nu un pixel). Procesarea poate include etapele cum ar fi obținerea de date din textura, realizarea calculului greșit, calcularea greșită a amestecului.
Lucrarea obligatorie pentru shader-ul fragmentului este de a înregistra culoarea fragmentului, de la variabila built-in gl_FragColor sau de ao arunca cu o comandă specială de aruncare. În cazul eliminării unui fragment, nu se vor face mai multe calcule cu acesta, iar fragmentul nu se va mai potrivi în tamponul pentru cadre.

(Notă: de asemenea, în OpenGL există încă două tipuri de shadere de tessellation, acestea fiind disponibile în OpenGL 4.0 și peste)

Descărcați și compilați

shader GLSL a decis să păstreze sub formă de cod sursă, dar OpenGL 4.1 shader vă permite să încărcați o serie de date binare pentru o mai bună portabilitate shadere pe diferite platforme hardware și software. Codul sursă este compilat de șofer. Ele pot fi compilate numai după crearea contextului OpenGL curent. Driverul se generează într-un cod binar optim care înțelege echipamentul. Acest lucru asigură faptul că același shader va funcționa corect și eficient pe diferite platforme.

Codul sursă poate fi reprezentat ca linii ANSI care se termină cu un șir de transfer ("n") sau fără el. În cazurile în care nu există transfer, trebuie să treci o serie de lungimi ale fiecărei linii.

Pașii de descărcare și de compilare:

  • Primii identificatori sunt identificați sub forma de GLuint, pentru shadere - glCreateShader și programul shader glCreateProgram;
  • ID-ul shader este încărcat cu codul sursă, care este trecut la driverul glShaderSource;
  • După shader, glCompileShader este compilat;
  • Mai multe shadere de diferite tipuri sunt atașate programului glAttachShader;
  • Ultimul pas este conectarea shaderelor atașate la un program shader numit glLinkProgram.

Este timpul să luați în considerare un exemplu mic care utilizează OpenGL 2.0. Dar, în același timp, în exemplul nu utilizează conducte grafice fixe, la cât mai aproape posibil de OpenGL 3.3. Acest lucru poate asigura o trecere lină la noua versiune de OpenGL, precum și a face mai ușor de a lucra cu OpenGL ES 2.0 / 3.0, la fel ca în OpenGL ES 2.0 / 3.0 îi lipsește, de asemenea, o conductă fixă ​​de grafică.

Vom folosi vertex și fragment de shader, deci fără a le în versiuni mai noi de OpenGL vor desena nimic, dar alte tipuri de shadere noi nu vor fi luate în considerare, deoarece acestea nu sunt în OpenGL 2.0 Noi facem, și nu sunt necesare în OpenGL 3.3 și mai sus.

Vertex Shader

Creați un atribut sub forma unui vector bidimensional numit coord. Este în ea și vor veni date despre coordonatele topului.
Atributul (atributul) este datele transferate către shader-ul de vârf (alte shadere nu sunt disponibile). Datele ajung la un shader pe fiecare vârf. Aceste date sunt doar pentru citire.
vec2 este un vector bidimensional de tip float.

gl_Position este variabila built-in pentru scrierea vertexului procesat de shader. Deci, așa cum are tipul vec4, vom crea un vector de patru componente luând x și y din atribut, z setat la zero și w la 1.0. Mai departe datele noastre de pe partea de sus merge mai departe de-a lungul conductei.

Fragment shader

Declarați Uniformă o variabilă a tipului vectorului cu patru componente. În ea, vom da culoarea dorită a primitivului.

Uniform este datele trimise la shader de către aplicație, spre deosebire de atribut, acestea sunt globale, atât pentru shadere, cât și pentru noduri. Asta este, dacă declarați o variabilă uniformă cu același nume în vârf și un fragment al shaderului, acestea vor fi comune pentru ele. De asemenea, datele nu depind de ce fel de vertex este procesat, ele rămân neschimbate până când aplicația le modifică.

gl_FragColor este o variabilă încorporată de tip vec4, înregistrează culoarea fragmentului procesată de shader-ul fragmentului.

Pentru a construi un exemplu, veți avea nevoie de bibliotecile GLEW și freeglut

Acest exemplu este foarte simplu. Scopul este de a arăta cum sunt încărcate și conectate shaderele. Și cum vor arăta cele mai simple vârfuri și shadere de fragmente?

Exemplu de cod sursă

concluzie