számítógépes grafika

48
Számítógépes Grafika OpenGL 4 shaderek, GLSL

Upload: manasa

Post on 13-Jan-2016

55 views

Category:

Documents


0 download

DESCRIPTION

OpenGL 4 shaderek, GLSL. Számítógépes Grafika. OpenGL 4. A következő programozható fázisok vannak a 4.x-es OpenGL-ben: Vertex shader Tesselation control shader Tesselation evaluation shader Geometry shader Fragment shader. OpenGL 4 pipeline. Vertex és pixel shader. Vertex shader. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Számítógépes Grafika

Számítógépes Grafika

OpenGL 4 shaderek, GLSL

Page 2: Számítógépes Grafika

OpenGL 4

A következő programozható fázisok vannak a 4.x-es OpenGL-ben: Vertex shader Tesselation control shader Tesselation evaluation shader Geometry shader Fragment shader

Page 3: Számítógépes Grafika

OpenGL 4 pipeline

Page 4: Számítógépes Grafika

Vertex és pixel shader

Page 5: Számítógépes Grafika

Vertex shader

A vertex shader programunkban végezzük el a bejövő geometria csúcspontjainak transzformációját

glDrawArrays/glDrawElements hívásban hivatkozott csúcspontok lesznek a bemenetei

A vertex shader bemeneti változóihoz (in módosító) a hozzárendelést a programból csináljuk

A csúcspontbeli attribútumoknál ritkábban változó bemenetet uniform változókon keresztül adhatjuk át (uniform = a kirajzolás hívás idejére konstans)

Page 6: Számítógépes Grafika

Vertex shader

A bejövő csúcspont koordinátáit clip space-be ( -1 <= x,y,z <= 1) kell transzformálni és a beépített gl_Position változónak átadni – ezt a pipeline nem programozható részeinek is kell gl_Position =

gl_MVPMatrix * bejövő_vertex_pos4 Ezen kívül azt csinálunk „amit akarunk” (minden out-tal megjelölt változónak adhatunk értéket és továbbküldhetjük a következő programozható fázisnak)

Page 7: Számítógépes Grafika

Vertex shader

A következő beépített kimeneti változók írhatóak a vertex shaderből:

vec4 gl_Position: a transzformált homogén koordinátái a bejövő vertex-nek. Ebbe írnia kell a VS-nek.

float gl_PointSize: a kirajzolandó pont mérete pixelben (point sprite-okhoz). Opcionális.

vec4 gl_ClipVertex: felhasználói vágósíkokhoz. Opcionális.

És ezeken kívül minden, amit mi is felveszünk...

Page 8: Számítógépes Grafika

Fragment shader

vec4 gl_FragColor: a fragment színe, de ha nem írun bele viszont van kimeneti vec4, az lesz ez vec4 glFragData[gl_MaxDrawBuffers]: ha több color attachment-je van az aktív FBO-nak, akkor ezen keresztül írhatunk rájuk float gl_FragDepth: fragment mélységi értéke (ha módosítanánk, mint a raycasterben) vec4 gl_FragCoord: csak olvasható, a fragment homogén koordinátái (4. koord 1/w) bool gl_FrontFacing: előrefelé néz-e a fragment lapja

Page 9: Számítógépes Grafika

Vertex shader

#version 400

in vec3 VertexPosition;

in vec3 VertexColor;

out vec3 Color;

void main()

{

Color = VertexColor;

gl_Position = vec4(VertexPosition,1.0);

}

Page 10: Számítógépes Grafika

Fragment shader

#version 400

in vec3 Color;

out vec4 FragColor;

void main()

{

FragColor = vec4(Color, 1.0);

}

Page 11: Számítógépes Grafika

Program-shader megfeleltetések

Vertex attribútumok és a shader bemeneti változóinak összerendelés:

glBindAttribLocation(programHandle, // shader prog0, // index"VertexPosition"); // sh-s nev

glBindAttribLocation(programHandle, 1, "VertexColor");

Page 12: Számítógépes Grafika

Program-shader megfeleltetések

glGenVertexArrays( 1, &vaoHandle );

glBindVertexArray(vaoHandle);

glEnableVertexAttribArray(0); // Vertex position

glEnableVertexAttribArray(1); // Vertex color

glBindBuffer(GL_ARRAY_BUFFER, positionBufferHandle);

glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 0, (GLubyte *)NULL );

glBindBuffer(GL_ARRAY_BUFFER, colorBufferHandle);

glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, 0, (GLubyte *)NULL );

Page 13: Számítógépes Grafika

Program-shader megfeleltetések

Lényegében tehát általános, indexekkel azonosított csatornákon keresztül megy az információátadás

A csatornák száma a GL_MAX_VERTEX_ATTRIBS segítségével kérhetőek le

Page 14: Számítógépes Grafika

Layout

A shader oldalon is megcsinálhatjuk a bejövő csatornák „index-esítését”, és nem kell bind-olni az attrib location-öket:

layout (location = 0) in vec3 VertexPosition;

layout (location = 1) in vec3 VertexColor;

Ezt a kimeneti változóknál is lehet használni:layout (location = 0) out vec4 FragColor;

Page 15: Számítógépes Grafika

Uniform változók

A shaderen belül read-only-k (konstansok), de kezdeti értéket kaphatnak uniform mat4 MVP

Típusok:, n = 2,3,4 mat<n>: n x n-es mátrix vec<n>: n dim vektor

Page 16: Számítógépes Grafika

Uniform változók

Először meg kell tudnunk az OpenGL-es azonosítóját a uniform változónak: GLuint mvpInShader = glGetUniformLocation(programHandle, "MVP");

Ezután már típusának megfelelő fv-vel értéket adhatunk neki: GlUniformMatrix4fv(

mvpInShader, 1, GL_FALSE, &app_mvp[0][0]);

Többiek: http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml

Page 17: Számítógépes Grafika

Uniform változók

Alaptípusok tömbjét is megjelölhetünk uniform-ként

Ekkor pl. egy mátrixtömb konkrét indexen lévő mátrixának azonosítóját megkapjuk így:

GLuint location = glGetUniformLocation( programHandle, "MyArray[1]" );

Page 18: Számítógépes Grafika

Uniform block

Több shader változó használhatja a program szempontjából ugyanazon uniform változókat

Ezeket mégis külön-külön kellene feltöltenünk stb., mert ugyanannak a uniform változónak más lesz a címe a különböző shader programokban

A uniform block segítségével ezen segíthetünk (csak használjunk shared layout-ot)

Page 19: Számítógépes Grafika

Uniform block – a shaderben

uniform BlobSettings

{vec4 InnerColor;

vec4 OuterColor;

float RadiusInner;

float RadiusOuter;

};

Page 20: Számítógépes Grafika

Uniform block

A uniform változók adatait tartalmazó puffer objektum a uniform buffer object

A változókra hivatkozásnál elég az adattag nevét írni, nem kell prefixelni az UBO nevével (tehát pl. elég az InnerColor, nem kell BlobSettings.InnerColor)

Page 21: Számítógépes Grafika

Uniform block

GLuint blockIndex = glGetUniformBlockIndex( programHandle, "BlobSettings");

GLint blockSize;

glGetActiveUniformBlockiv( programHandle, blockIndex,GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize);

GLubyte * blockBuffer= (GLubyte *)malloc(blockSize);

Page 22: Számítógépes Grafika

Uniform block

const GLchar *names[] = { "InnerColor", "OuterColor",

"RadiusInner", "RadiusOuter" };

GLuint indices[4];

glGetUniformIndices(programHandle, 4, names, indices);

GLint offset[4];

glGetActiveUniformsiv(programHandle, 4, indices,GL_UNIFORM_OFFSET, offset);

Page 23: Számítógépes Grafika

Uniform block

GLfloat outerColor[] = {0.0f, 0.0f, 0.0f, 0.0f};

GLfloat innerColor[] = {1.0f, 1.0f, 0.75f, 1.0f};

GLfloat innerRadius = 0.25f, outerRadius = 0.45f;

memcpy(blockBuffer + offset[0], innerColor, 4 * sizeof(GLfloat));

memcpy(blockBuffer + offset[1], outerColor, 4 * sizeof(GLfloat));

memcpy(blockBuffer + offset[2], &innerRadius, sizeof(GLfloat));

memcpy(blockBuffer + offset[3], &outerRadius, sizeof(GLfloat));

Page 24: Számítógépes Grafika

Uniform block

GLuint uboHandle;

glGenBuffers( 1, &uboHandle );

glBindBuffer( GL_UNIFORM_BUFFER,uboHandle );

glBufferData( GL_UNIFORM_BUFFER, blockSize,blockBuffer, GL_DYNAMIC_DRAW );

glBindBufferBase( GL_UNIFORM_BUFFER, blockIndex, uboHandle );

Page 25: Számítógépes Grafika

Fragment shader

#version 400

in vec3 Color;

out vec4 FragColor;

void main()

{

FragColor = vec4(Color, 1.0);

}

Page 26: Számítógépes Grafika

Az összes shader

Page 27: Számítógépes Grafika

Az összes shader

Az összes shader opcionális, pass-through-ként működnek ha nincs saját hozzárendelve

Ha van akár geometry, akár tesszelációs shader, akkor kell legyen vertex shader is

Page 28: Számítógépes Grafika

Geometry shader

Meglévő geometria módosítására, törlésére, bővítésére

Bemenete a transzformált vertexekből képezett primitívekből áll

Kimenete 0, 1, vagy több primitív A kimenő primitív típus különbözhet a bejövőtől! De csak egyféle típusú lehet a kimenet

Page 29: Számítógépes Grafika

Geometry shader

Minden primitívre egyszer fut le A primitív összes csúcspontját eléri, a

csúcspontokban tárolt összes információval együtt

Lehet akár culling-ot is csinálni benne

Page 30: Számítógépes Grafika

Geometry shader

EmitVertex: ha kész vagyunk a primitív egyik csúcspontjához tartozó attribútumok kitöltésével, ezzel az utasítással adhatjuk tovább a pipeline-nak Ha nincs EmitVertex, akkor implicit eldobódik

csúcspont EmitPrimitive: ha elkészült a primitív összes

csúcspontja, akkor EmitPrimitive-vel tudjuk visszadobni a pipeline-ba Ha nincs EmitPrimitive, akkor a GS lefutásakor

implicit hívódik egy

Page 31: Számítógépes Grafika

Tesszellációs shader

Ha aktiválva van, akkor csak egyetlen rajzolási primitívünk van: GL_PATCHES

A patch primitív tetszőleges geometriai és egyéb információk halmaza, ami alapján a tesszelációs shader az inkrementális képszintézisnek megfelelő primitíveket hoz létre

Maximális „csúcsok” száma egy patch-ben: GL_MAX_PATCH_VERTICES

Page 32: Számítógépes Grafika

Tesszellációs shader

A kirajzolandó patch-adathalmaz csúcspontjainak száma: glPatchParameteri(

GL_PATCH_VERTICES, num); Például Bézier kontrollpontok száma

Page 33: Számítógépes Grafika

Tesszellációs shader

A patch primitívet nem rajzoljuk ki, a tesselation control és tesselation evaluator számára szolgáltat adatokat

A tényleges pipeline-ba bekerülő primitíveket a tesselation primitive generator állítja elő (ez a TCS és TES között van a pipelineban)

Page 34: Számítógépes Grafika

TCS

A TPG-t konfigurálja, hogy az miképp készítsen primitíveket (mennyit és melyik beépített algoritmussal)

Ezen kívül per-vertex kimeneti attribútumokat állíthat elő

Page 35: Számítógépes Grafika

TES

A TPG által létrehozott primitívek minden egyes (paramétertérbeli) csúcspontjára meghívódik

Lényegében: a görbe- vagy felületséma kiértékelése a feladata

Fő feladat: a pozíció meghatározása

Page 36: Számítógépes Grafika

Geometry shader példa

Page 37: Számítógépes Grafika

Geometry shader - bemenet

• A következő típusú bemenetek lehetnek:

points (1)

lines (2)

lines_adjacency (4)

triangles (3)

triangles_adjacency (6)

Primitívenként 1, 2, 4, 3, 6 csúcspontokkal

Page 38: Számítógépes Grafika

Geometry shader - bemenet

A szomszédossági adatos primitívek OpenGL kliens oldali kódjában a következők:

GL_LINES_ADJACENCY

GL_LINE_STRIP_ADJACENCY

GL_TRIANGLES_ADJACENCY

GL_TRIANGLE_STRIP_ADJECENCY

Page 39: Számítógépes Grafika

Geometry shader - bemenet

A többi primitív típusból pedig a pipeline csinálja meg a GS bemenetet

Ami tehát mindig 1 primitívből áll, amihez tartozhat szomszédossági információ is

Hogyan kapja ezt meg?

Page 40: Számítógépes Grafika

Geometry shader - bemenet

Page 41: Számítógépes Grafika

Geometry shader - bemenet

Page 42: Számítógépes Grafika

Geometry shader - bemenet

Page 43: Számítógépes Grafika

Geometry shader - bemenet

Page 44: Számítógépes Grafika

Geometry shader – bemenet, kimenet

Page 45: Számítógépes Grafika
Page 46: Számítógépes Grafika
Page 47: Számítógépes Grafika
Page 48: Számítógépes Grafika