29
Tecgraf/PUC-Rio Geometry & Tesselation Shaders Waldemar Celes

Geometry & Tesselation Shaders Waldemar Celes

  • Upload
    others

  • View
    8

  • Download
    0

Embed Size (px)

Citation preview

Tecgraf/PUC-Rio

Geometry & Tesselation Shaders Waldemar Celes

Principais novidades com série NV8000 q  Novo estágio de programação

ð Geometry shader q  Suporte a inteiros

ð Textura, operações, endereçamento q  Modelo unificado de shaders

ð Mesma funcionalidades nos diferentes shaders q  Possível uso do pipeline para gerar geometria

ð Sem a fase de rasterização q  Arrays de texturas

ð Renderização em camadas q  Variáveis uniformes em buffer object

Geometry shader

q Pipeline programável antigo (D3D9)

From http://firingsquad.com/hardware/directx_10_graphics_preview

Geometry shader

q Pipeline programável novo (D3D10)

From http://firingsquad.com/hardware/directx_10_graphics_preview

Geometry shader

q Depois do VS, antes da rasterização

GS Vertex T&L, vertex shader

Clipping, color clamping, perspective division

Geometry shader

q Fluxo de dados

GS Point, Line, Triangle

Point, Line strip, Triangle strip

Pode gerar primitivas Pode emitir vértices por primitiva

API para novas primitivas q  Primitivas com informação de adjacências

ð Lines ² GL_LINES_ADJACENCY_EXT

ð Line strip ² GL_LINE_STRIP_ADJACENC Y_EXT

ð Triangle ² GL_TRIANGLES_ADJACENC Y_EXT

ð Triangle strip ² GL_TRIANGLE_STRIPACENC Y_ADJ_EXT

1 2 4 3 5 6 8 7

1 2 4 3 5 6 8 7

2

5 1

3 4

6 2

5 1

3 7

4

9

11

8

6 10

12

Obs: vizinhos são ignorados na ausência de um geometry shader

Geometry shader

q GS opera sobre uma primitiva por vez ð Gera como saída uma ou mais primitivas

² Todas do mesmo tipo

ð Primitiva original (de entrada) é descartada

q Exige a presença de um vertex shader ð GLSL reporta erro de link-edição

Geometry shader q  Input

ð Tipo de primitiva de entrada: 1 a 6 vértices ² Dependendo do tipo de primitiva de entrada

–  Ponto: 1 - proveniente de pontos –  Linha: 2 - proveniente de linhas ou faixas de linhas –  Triângulo: 3 - proveniente de triângulos, faixas, leques –  Linha com adjacência: 4 - proveniente de linhas e faixa c/ adj –  Triângulo com adjacência: 6 - prov. de triângulos e faixa c/ adj

ð GS deve ser compatível com tipo de primitiva ² Tipo de primitiva é parâmetro de um GS

– Deve ser definido

Geometry shader q Output

ð Uma ou mais primitivas de um mesmo tipo ² Points ² Line strip ² Triangle strip

ð GS deve ser compatível com tipo de primitiva ² Tipo de primitiva de saída é parâmetro de um GS

– Deve ser definido

GS variables q  Uniforms

ð Variáveis globais ²  Incluindo samplers para acesso de textura

q  Input variables ð Saída de um VS

² Vertex attributes (built-in) ² User-defined vertex attributes

ð  ID da primitiva (built-in) ² Gerada automaticamente ²  ID inicializado com zero no “glBegin”

q  Output varying variables ð Saída de um GS

² Vertex attributes (built-in) ² User-defined vertex attributes

GS input variables q  Atributos built-in de vértices

q  Atributos extras ð  Se no VS temos:

ð  No GS, teremos:

q  Atributos globais ð  in int gl_PrimitiveIDIn; ð  in int gl_InvocationID;

ptg

The input primitive type is specified in the body of the geometry shader using a layout qualifier. The general form of the input layout qualifier is

layout (primitive_type) in;

This specifies that primitive_type is the input primitive type that the geometry shader is expected to handle, and primitive_type must be one of the supported primitive modes: points, lines, triangles, lines_adjacency, or triangles_adjacency. The geometry shader runs once per primitive. This means that it’ll run once per point for GL_POINTS; once per line for GL_LINES, GL_LINE_STRIP, and GL_LINE_LOOP; and once per triangle for GL_TRIANGLES, GL_TRIANGLE_STRIP, and GL_TRIANGLE_FAN. The inputs to the geometry shader are presented in arrays containing all of the vertices making up the input primitive. The predefined inputs are stored in a built-in array called gl_in[], which is an array of structures and defined as shown in Listing 11.5.

LISTING 11.5 The Definition of gl_in[]

in gl_PerVertex {

vec4 gl_Position; float gl_PointSize; float gl_ClipDistance[];

} gl_in[];

The members of this structure are the built-in variables that are written in the vertex shader: gl_Position, gl_PointSize, and gl_ClipDistance[]. You should be very familiar with gl_Position and gl_PointSize by now, and gl_ClipDistance is explained in Chapter 12. These variables appear as global variables in the vertex shader, but their values end up in the structure members when they appear in the geometry shader. Other vari-ables written by the vertex shader also become arrays in the geometry shader. In the case of individual varyings, outputs in the vertex shader are declared as normal, and the inputs to the geometry shader have a similar declaration, except that they are arrays. Consider a vertex shader that defines outputs as

out vec4 color; out vec3 normal;

The corresponding input to the geometry shader would be

in vec4 color[]; in vec3 normal[];

Notice that both the color and normal varyings have become arrays in the geometry shader. If you have a large amount of data to pass from the vertex to the geometry shader,

Geometry Shaders 423

11

Download from www.wowebook.com

ptg

The input primitive type is specified in the body of the geometry shader using a layout qualifier. The general form of the input layout qualifier is

layout (primitive_type) in;

This specifies that primitive_type is the input primitive type that the geometry shader is expected to handle, and primitive_type must be one of the supported primitive modes: points, lines, triangles, lines_adjacency, or triangles_adjacency. The geometry shader runs once per primitive. This means that it’ll run once per point for GL_POINTS; once per line for GL_LINES, GL_LINE_STRIP, and GL_LINE_LOOP; and once per triangle for GL_TRIANGLES, GL_TRIANGLE_STRIP, and GL_TRIANGLE_FAN. The inputs to the geometry shader are presented in arrays containing all of the vertices making up the input primitive. The predefined inputs are stored in a built-in array called gl_in[], which is an array of structures and defined as shown in Listing 11.5.

LISTING 11.5 The Definition of gl_in[]

in gl_PerVertex {

vec4 gl_Position; float gl_PointSize; float gl_ClipDistance[];

} gl_in[];

The members of this structure are the built-in variables that are written in the vertex shader: gl_Position, gl_PointSize, and gl_ClipDistance[]. You should be very familiar with gl_Position and gl_PointSize by now, and gl_ClipDistance is explained in Chapter 12. These variables appear as global variables in the vertex shader, but their values end up in the structure members when they appear in the geometry shader. Other vari-ables written by the vertex shader also become arrays in the geometry shader. In the case of individual varyings, outputs in the vertex shader are declared as normal, and the inputs to the geometry shader have a similar declaration, except that they are arrays. Consider a vertex shader that defines outputs as

out vec4 color; out vec3 normal;

The corresponding input to the geometry shader would be

in vec4 color[]; in vec3 normal[];

Notice that both the color and normal varyings have become arrays in the geometry shader. If you have a large amount of data to pass from the vertex to the geometry shader,

Geometry Shaders 423

11

Download from www.wowebook.com

ptg

The input primitive type is specified in the body of the geometry shader using a layout qualifier. The general form of the input layout qualifier is

layout (primitive_type) in;

This specifies that primitive_type is the input primitive type that the geometry shader is expected to handle, and primitive_type must be one of the supported primitive modes: points, lines, triangles, lines_adjacency, or triangles_adjacency. The geometry shader runs once per primitive. This means that it’ll run once per point for GL_POINTS; once per line for GL_LINES, GL_LINE_STRIP, and GL_LINE_LOOP; and once per triangle for GL_TRIANGLES, GL_TRIANGLE_STRIP, and GL_TRIANGLE_FAN. The inputs to the geometry shader are presented in arrays containing all of the vertices making up the input primitive. The predefined inputs are stored in a built-in array called gl_in[], which is an array of structures and defined as shown in Listing 11.5.

LISTING 11.5 The Definition of gl_in[]

in gl_PerVertex {

vec4 gl_Position; float gl_PointSize; float gl_ClipDistance[];

} gl_in[];

The members of this structure are the built-in variables that are written in the vertex shader: gl_Position, gl_PointSize, and gl_ClipDistance[]. You should be very familiar with gl_Position and gl_PointSize by now, and gl_ClipDistance is explained in Chapter 12. These variables appear as global variables in the vertex shader, but their values end up in the structure members when they appear in the geometry shader. Other vari-ables written by the vertex shader also become arrays in the geometry shader. In the case of individual varyings, outputs in the vertex shader are declared as normal, and the inputs to the geometry shader have a similar declaration, except that they are arrays. Consider a vertex shader that defines outputs as

out vec4 color; out vec3 normal;

The corresponding input to the geometry shader would be

in vec4 color[]; in vec3 normal[];

Notice that both the color and normal varyings have become arrays in the geometry shader. If you have a large amount of data to pass from the vertex to the geometry shader,

Geometry Shaders 423

11

Download from www.wowebook.com

Emissão de vértices no GS q  Output variables (como no VS)

ð  gl_Position, gl_PointSize, gl_ClipDistance[], etc. ²  OBS: VS pode não escrever o valor de gl_Position

q  Emissão de vértices ð  GS pode emitir um número variável de vértices por primitivas

²  Implementação pode limitar o máximo ²  Máximo de cada GS deve ser especificado para alocação de espaço

ð  Função built-in: EmitVertex( ) ²  Valores das output variables são emitidos

–  Variáveis passam a ter valors indefinidos

Emissão de primitivas no GS q  Variáveis built-in de saída

ð  out int gl_PrimitiveID ð  out int gl_Layer

²  For multilayer rendering

q  Definição de primitivas ð GS pode definir um número variável de primitivas

²  Implementação pode limitar o máximo

ð Função built-in: EndPrimitive( ) ² Finaliza uma primitiva: outra de mesmo tipo pode ser gerada ² O EndPrimitive da última primitiva é opcional

GS: exemplo pass-thourgh ptg

The other difference between geometry shaders and vertex and fragment shaders is that geometry shaders are an optional part of the OpenGL pipeline. It is perfectly legal to have only a vertex and fragment shader linked into a program object, and this is, until now, the only way you’ve used OpenGL. When no geometry shader is present, the OpenGL pipeline operates as normal; the outputs from the vertex shader are interpolated across the primitive being rendered and are fed directly to the fragment shader. When a geometry shader is present, however, the outputs of the vertex shader become the inputs to the geometry shader, and the outputs of the geometry shader are what are interpolated and fed to the fragment shader. The geometry shader can further process the output of the vertex shader, and if it is generating new primitives (this is called amplification) can apply different transformations to each primitive as it creates them.

The Pass-Through Geometry ShaderGeometry shaders are written in GLSL, just like vertex and fragment shaders, and there’s nothing magical about them. This will all be explained shortly, but Listing 11.2 shows a simple geometry shader in its entirety.

LISTING 11.2 Source Code for a Simple Geometry Shader

#version 330

precision highp float;

layout (triangles) in; layout (triangle_strip) out; layout (max_vertices = 3) out;

void main(void) {

int i;

for (i = 0; i < gl_in.length(); i++) { gl_Position = gl_in[i].gl_Position; EmitVertex();

}EndPrimitive();

}

This is a very simple pass-through geometry shader, which sends its input to its output without modifying it. It looks similar to a vertex shader, but there are a few extra differ-ences to cover. Going over the shader a few lines at a time makes everything clear. The first few lines simply set up the version number (330) and the precision of the shader just

CHAPTER 11 Advanced Shader Usage420

Download from www.wowebook.com

GS: exemplos de uso

q Dado vértice e normal ð Gerar linha como glyph

q Gerar coordenada de textura por primitiva

Layered rendering q  Layered framebuffer object

ð  cube map textures ² Cada face representa uma camada

ð  three-dimensional textures ² Cada fatia representa uma camada

ð one- dimensional texture array ² Cada textura representa uma camada

ð  two-dimensional texture array ² Cada textura representa uma camada

q  Primitivas enviadas para diferentes camadas ð Definida em tempo de execução

² Valor da variável gl_Layer

Transform feedback q  Novo modo de render do OpenGL

ð Permite usar o pipeline para gerar primitivas ² Armazenadas em buffer objects

–  Arrays de atributos de vértices

ð Primitivas armazenadas antes do clipping ² Se exisitir GS, logo após ele

ð Resultado usado posteriormente ² Ou como dados de vértices ² Ou como array para FS

ð Aplicações ² Acelera algoritmo de múltiplas passadas

–  Onde se tem criação de geometria ² GPGPU

From http://firingsquad.com/hardware/directx_10_graphics_preview

Novidades com OpenGL 4.0 (DX11)

q Novos estágios: tessellation ð Processa nova primitiva

patch Aplicação

Vertex Shader

Tess Control Shader

Tess Evaluation Shader

Geometry Shader

Setup/Rasterizer

Tess Generator

Tessellation Control Shader

q Opcional q  In/Out

ð In: a patch ð Out: a patch

² Array of vertices (and attribs) ² Per-patch attribs

q Shader executado para cada vértice de saída ð Produz atributos do vértice correspondente ð Pode ler atributos gerados para outros vértices ð Pode ler e escrever atributos de patch ð Função barrier( ) provê sincronismo

Tessellation Primitive Generator

q Funcionalidade fixa, não programável q Subdivide primitiva

ð De acordo com o nível pedido: tess level ð In/Out

² In: triangles; Out: triangles ² In: quads; Out: quads or lines

q A cada vértice gerado é atribuito coordenadas paramétricas

² Triangle: (u, v, w) ² Quad: (u, v)

Tessellation Evaluation Shader

q Obrigatório para primitivas patch q Executado para cada vértice gerado q Propósito principal

ð Gerar posição e atributos dos vértices q Pode ler atributos dos vértices do patch q Pode ler atributos associados ao patch

q Requer vertex shader q Saída enviada para GS ou pipeline fixo

Tessellation Control Shader q Variáveis de entrada

ð gl_in[ ] à vetor de estrutura com os campos: ² gl_Position, gl_FrontColor, gl_TexCoord[ ], etc.

ð Variáveis built-in ² gl_InvocationID, gl_PatchVerticesIn, gl_PrimitiveID

–  gl_InvocationID indicates the vertex under consideration

q Variáveis de saída ð Atributos de vértices

² gl_out[ ] –  gl_Position, etc.

ð Atributos de patch: GLSL qualifier à patch ² Built-in

–  gl_TessLevelOuter[4], gl_TessLevelInner[2]

Tessellation Primitive Generator

q Define-se tipo de subdivisão ð quads, triangles, isolines

Tessellation mode: triangles

1st inner level perpendicular lines inner subdivision

inner tessellation 1st, 2nd, 3rd outer levels outer tesselation

Tessellation mode: quads

1st, 2nd inner levels perpendicular lines inner subdivision

inner tessellation 1st, 2nd, 3rd, 4th outer levels outer tesselation

Tessellation mode: isolines

1st, 2nd outer levels perpendicular lines line generation

Tessellation Evaluation Shader

q Variáveis de entrada ð Atributos dos vértices do patch: gl_in[ ] ð Variáveis built-in

² gl_PatchVerticesIn, gl_PrimitiveID ² gl_TessCoord ² gl_TessLevelOuter[ ], gl_TessLevelInner[ ]

q Variáveis de saída ð gl_Position, etc.

Aplicações

Ref: http://castano.ludicon.com/blog/2009/01/10/10-fun-things-to-do-with-tessellation/

PN triangles Silhouette refinement

Bezier surfaces Terrain rendering