A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

25 de fevereiro de 2014 Programação em GPUs (OpenGL/GLSL CUDA) Yalmar Ponce.

Apresentações semelhantes


Apresentação em tema: "25 de fevereiro de 2014 Programação em GPUs (OpenGL/GLSL CUDA) Yalmar Ponce."— Transcrição da apresentação:

1 25 de fevereiro de 2014 Programação em GPUs (OpenGL/GLSL CUDA) Yalmar Ponce

2 25 de fevereiro de 2014 Roteiro Introdução Tipos de dados, Estruturas, Funções Shaders Exemplos Luz (Direcional, Pontual, Spot) Efeitos (Parede de Tijolos, Madeira, Desenho animado) Modificando Geometria Textura e Multitextura Shader de Geometria Exemplos FBO CUDA Projeto Final Mapeamento de Sombra (Shadow mapping)

3 25 de fevereiro de 2014 Introdução Aplicações Renderização em tempo real Efeitos Jogos

4 25 de fevereiro de 2014 Introdução GPUs são rápidas GHz Intel Core Extreme 96 GFLOPS – pico Memory Bandwidth: 13 GB/s Preço: 800~ dólares NVIDIA GeForce GTX 280: 930 GFLOPS Memory Bandwidth: 141 GB/s Preço: 499 dólares

5 25 de fevereiro de 2014 Introdução Versão simplificada da pipeline GPUCPU Application Transform & Light Rasterize Shade Video Memory (Textures) Xformed, Lit Vertices (2D) Graphics State Render-to-texture Assemble Primitives Vertices (3D) Screenspace triangles (2D) Fragments (pre-pixels) Final Pixels (Color, Depth)

6 25 de fevereiro de 2014 Introdução Processador de Vértices Programável GPU Transform & Light CPU Application Rasterize Shade Video Memory (Textures) Xformed, Lit Vertices (2D) Graphics State Render-to-texture Assemble Primitives Vertices (3D) Screenspace triangles (2D) Fragments (pre-pixels) Final Pixels (Color, Depth) Fragment Processor Vertex Processor Processador de fragmentos Programável

7 25 de fevereiro de 2014 Introdução Geração de geometria programável GPUCPU Application Vertex Processor Rasterize Fragment Processor Video Memory (Textures) Xformed, Lit Vertices (2D) Graphics State Render-to-texture Vertices (3D) Screenspace triangles (2D) Fragments (pre-pixels) Final Pixels (Color, Depth) Assemble Primitives Geometry Processor Acesso a memória mais flexível

8 25 de fevereiro de 2014 Shaders Shaders são programas que executam em determinadas etapas do pipeline Não são aplicações stand-alone Necessitam de uma aplicação que utilize um API (OpenGL ou Direct3D)

9 25 de fevereiro de 2014 Shaders No caso: Vertex shader – Vertex Processor Fragment shader – Fragment Processor Geometry shader – Geometry Processor

10 25 de fevereiro de 2014 Shaders Vertex Processor Transforma do espaço de mundo para o espaço de tela Calcula iluminação per-vertex

11 25 de fevereiro de 2014 Shaders Geometry Processor Como os vértices se conectam para formar a geometria Operações por primitiva

12 25 de fevereiro de 2014 Shaders Fragment Processor Calcula a cor de cada pixel Obtém cores de texturas

13 25 de fevereiro de 2014 Shaders Hoje a programação de shaders é feita em linguagens de alto nível No estilo de c/c++ As principais que temos hoje: GLSL – OpenGL Shader Language HLSL – High Level Shader Language Cg – C for Graphics

14 25 de fevereiro de 2014 Shaders Temos algumas ferramentas que servem tanto para criação e edição de shaders: NVIDIA FX Composer 2.5 NVIDIA FX Composer 2.5 RenderMonkey ATI RenderMonkey ATI

15 25 de fevereiro de 2014 Shaders

16 25 de fevereiro de 2014 Shaders

17 25 de fevereiro de 2014 Tipos de dados Estruturas bem intuitivas Vetores: vec2, vec3 e vec4 – floating point ivec2, ivec3 e ivec4 – interger bvec2, bvec3 e bvec4 – boolean Matrizes mat2, mat3 e mat4 – floating point

18 25 de fevereiro de 2014 Tipos de dados Texturas Sampler1D, Sampler2D, Sampler3D - texturas 1D, 2D e 3D SamplerCube – Cube map textures Sampler1Dshadow, Sampler2DShadow – mapa de profundidade 1D e 2D

19 25 de fevereiro de 2014 Input/Output Existem 3 tipos de input em um shader: Uniforms Varyings Attributes

20 25 de fevereiro de 2014 Input/Output Uniforms Não mudam durante o rendering Ex: Posição da luz ou cor da luz Esta presente em todos os tipos de shader Varyings Usado para passar dados do vertex shader para o fragment shader ou geometry shader

21 25 de fevereiro de 2014 Input/Output Varyings São read-only no fragment e geometry shader mas read/write no vertex shader Deve-se declarar a mesma varying em todos os programas Attributes Estão presentes apenas nos Vertex shaders São valores (possivelmente diferentes) associados a cada vértice

22 25 de fevereiro de 2014 Input/Output Attributes Ex: Posição do vértice ou normais São apenas read-only

23 25 de fevereiro de 2014 Input/Output Exemplos de Attributes no vertex shader gl_Vertex – vetor 4D, posição do vértice gl_Normal – vetor 3D, Normal do vértice gl_Color – vetor 4D, cor do vértice gl_MultiTexCoordX – vetor 4D, coordenada de textura na unit X Existem vários outros atributos

24 25 de fevereiro de 2014 Input/Output Exemplos de Uniforms gl_ModelViewMatrix gl_ModelViewProjectionMatrix gl_NormalMatrix

25 25 de fevereiro de 2014 Input/Output Exemplos de Varyings gl_FrontColor - vetor 4D com a cor frontal das primitivas gl_BackColor – vetor 4D com a cor de trás das primitivas gl_TexCoord[N] – vetor 4D representando a n-ésima coordenada de textura

26 25 de fevereiro de 2014 Input/Output Exemplos de output: gl_Position – vetor 4D representando a posição final do vértice gl_FragColor – vetor 4D representando a cor final que será escrita no frame buffer gl_FragDepth – float representando o depth que será escrito do depth buffer

27 25 de fevereiro de 2014 Input/Output Também é possível definir attributes, uniforms e varyings Ex: Passar um vetor tangente 3D por todos os vértices da sua aplicação É possível especificar o atributo tangente attribute vec3 tangente;

28 25 de fevereiro de 2014 Input/Output Alguns outros exemplos: uniform sampler2D my_color_texture; varying vec3 vertex_to_light_vector; varying vec3 vertex_to_eye_vector; attribute vec3 binormal;

29 25 de fevereiro de 2014 Funções e Estruturas de Controle Similar a linguagem C Suporta estruturas de repetição e decisão If/else For Do/while Break Continue

30 25 de fevereiro de 2014 Funções e Estruturas de Controle Possui funções como: Seno (sin) Cosseno (cos) Tangente (tan) Potencia (pow) Logaritmo (log) Logaritmo (log2) Raiz (sqrt)

31 25 de fevereiro de 2014 GLSL-Setup Antes de criar os shaders é necessário implementar uma função (no caso do GLSL) para ler e enviar os shaders para o hardware

32 25 de fevereiro de 2014 GLSL-Setup void setShaders(){ char *vs = NULL,*fs = NULL,*fs2 = NULL; v = glCreateShader(GL_VERTEX_SHADER); f = glCreateShader(GL_FRAGMENT_SHADER); vs = textFileRead("minimal.vert"); fs = textFileRead("minimal.frag"); const char * vv = vs; const char * ff = fs; glShaderSource(v, 1, &vv,NULL); glShaderSource(f, 1, &ff,NULL); free(vs);free(fs); glCompileShader(v); glCompileShader(f); p = glCreateProgram(); glAttachShader(p,v); glAttachShader(p,f); glLinkProgram(p); glUseProgram(p); }

33 25 de fevereiro de 2014 Exemplos simples

34 25 de fevereiro de 2014 Hello World O código shader mais simples Vertex Shader void main() { gl_Position = ftransform(); } Fragment Shader void main(){ gl_FragColor = vec4(0.4,0.4,0.8,1.0); }

35 25 de fevereiro de 2014 Modificando a geometria Achatar o modelo 3D, ou seja, z = 0 void main(void) { vec4 v = vec4(gl_Vertex); v.z = 0.0; gl_Position = gl_ModelViewProjectionMatrix * v; }

36 25 de fevereiro de 2014 Modificando a geometria II void main(void){ vec4 v = vec4(gl_Vertex); v.z = sin(5.0*v.x )*0.25; gl_Position = gl_ModelViewProjectionMatrix * v; }

37 25 de fevereiro de 2014 Animação É necessário manter a passagem do tempo nos frames No vertex shader não é possível guardar valores a variável é definida na aplicação OpenGL

38 25 de fevereiro de 2014 Animação O shader recebe o valor time numa variável Uniform uniform float time; void main(void){ vec4 v = vec4(gl_Vertex); v.z = sin(5.0*v.x + time*0.01)*0.25; gl_Position = gl_ModelViewProjectionMatri x*v; } A função de render: void renderScene(void){... glUniform1fARB(loc, time); glutSolidTeapot(1); time+=0.01; glutSwapBuffers(); }

39 25 de fevereiro de 2014 Manipulação de Texturas GLSL permite acesso as coordenadas de textura por vértice GLSL provê variáveis do tipo Attribute, para cada unidade de textura (max 8) attribute vec4 gl_MultiTexCoord[0..8]

40 25 de fevereiro de 2014 Manipulação de Texturas Precisa calcular a coordenada de textura Armazenar numa variável varying gl_TexCoord[i] onde i é a unidade de textura utilizada gl_TexCoord[0] = gl_MultiTexCoord0; Um simples código para definir coordenadas de textura para uma textura utilizando a unit 0 Vertex Shader void main(){ gl_TexCoord[0] = gl_MultiTexCoord0; gl_Position = ftransform(); }

41 25 de fevereiro de 2014 Manipulação de Texturas gl_TexCoord é uma variável varying Será utilizada no fragment shader para acessar as coordenadas de textura interpoladas Para acessar os valores de textura temos que declarar uma variável do tipo uniform no fragment shader Para uma textura 2D temos: uniform sampler2D tex;

42 25 de fevereiro de 2014 Manipulação de Texturas A função que nos retorna um textel é a texture2D Os valores retornados levam em consideração todos as definições de textura feitos no OpenGL (filtering, mipmap, clamp, etc)

43 25 de fevereiro de 2014 Manipulação de Texturas Vertex Shader void main(){ gl_TexCoord[0] = gl_MultiTexCoord0; gl_Position = ftransform(); } Fragment shader uniform sampler2D tex; void main() { vec4 color = texture2D(tex,gl_TexCoord[0].st); gl_FragColor = color; }

44 25 de fevereiro de 2014 Múltiplas Texturas Definir as texturas glGenTextures(1, &Textura); glBindTexture(GL_TEXTURE_2D, Textura); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, level, format, Width, Height, 0, GL_RGB,GL_UNSIGNED_BYTE, TexureInfo); Na aplicação OpenGL, é necessário habilitar as texturas que serão usadas. glActivateTexture(GL_TEXTUREi) onde i = 0..8

45 25 de fevereiro de 2014 Múltiplas Texturas Multi Texturing glEnable (GL_TEXTURE_2D); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texid0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texid1);... glBegin(GLenum Mode);. glEnd(); glDisable (GL_TEXTURE_2D);

46 25 de fevereiro de 2014 GLSL e Multi-Textura Cada textura que será usada no programa GLSL deve ser associada a uma textura na aplicação OpenGL. Vertex/Fragment Shader uniform sampler2D textureName1, textureName2; Programa OpenGL (inicialiazação) GLuint tex1, tex2; GLint texLoc1, texLoc2; texLoc1 = glGetUniformLocation(programObj, "textureName1"); texLoc2 = glGetUniformLocation(programObj, "textureName2"); glUniform1i(texLoc1, 0); // a primeira deve ser 0 glUniform1i(texLoc2, 1); Programa OpenGL ( ativar multitextura) glEnable(GL_TEXTURE_2D); glActiveTexture(GL_TEXTURE0); // habilita para uso tex1 glActiveTexture(GL_TEXTURE1); // habilita para uso tex2 drawQuad(); Note que a textura atribuída com a função glUniform1i(texLoc1, i) i = 0, 1,... deve ser ativada com glActiveTexture(GL_TEXTUREi) antes de usar um programa GLSL

47 25 de fevereiro de 2014 Textura 3D glGenTextures(1, &TexName); glBindTexture(GL_TEXTURE_3D, TexName); glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT); glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, TexSize, TexSize, TexSize, 0, GL_RGBA,GL_UNSIGNED_BYTE, data);

48 25 de fevereiro de 2014 Exemplos mais complexos

49 25 de fevereiro de 2014 Efeito tijolo Vertex Shader 2ndEd/CH06-brick.vert.txt 2ndEd/CH06-brick.vert.txt Fragment Shader 2ndEd/CH06-brick.frag.txt 2ndEd/CH06-brick.frag.txt

50 25 de fevereiro de 2014 Effeito madeira Vertex Shader shaders2ndEd/CH15- wood.vert.txt shaders2ndEd/CH15- wood.vert.txt Fragment Shader shaders2ndEd/CH15- wood.frag.txt shaders2ndEd/CH15- wood.frag.txt

51 25 de fevereiro de 2014 Efeito nuvem Vertex Shader ders2ndEd/CH15-cloud.vert.txt ders2ndEd/CH15-cloud.vert.txt Fragment Shader ders2ndEd/CH15-cloud.frag.txt ders2ndEd/CH15-cloud.frag.txt

52 25 de fevereiro de 2014 Geometry Shader

53 25 de fevereiro de 2014 Geometry Shader Permite mudar a geometria de entrada Necessário especificar a geometria de entrada e saida glProgramParameteriEXT(GLhandleARB program, GL_GEOMETRY_INPUT_TYPE_EXT, GL_LINES_ADJACENCY_EXT); glProgramParameteriEXT(GLhandleARB program, GL_GEOMETRY_OUTPUT_TYPE_EXT, GL_TRIANGLE_STRIP); Adicionalmente deve ser especificado o número máximo de vértices a serem criados glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT,&temp); glProgramParameteriEXT(GLhandleARB program, GL_GEOMETRY_VERTICES_OUT_EXT,temp);

54 25 de fevereiro de 2014 Geometry Shader Convenções #version 120 #extension GL_EXT_geometry_shader4 : enable Geometry language built-in outputs: varying out vec4 gl_FrontColor; varying out vec4 gl_BackColor; varying out vec4 gl_FrontSecondaryColor; varying out vec4 gl_BackSecondaryColor; varying out vec4 gl_TexCoord[]; // at most gl_MaxTextureCoords varying out float gl_FogFragCoord; Geometry language input varying variables: varying in vec4 gl_FrontColorIn[gl_VerticesIn]; varying in vec4 gl_BackColorIn[gl_VerticesIn]; varying in vec4 gl_FrontSecondaryColorIn[gl_VerticesIn]; varying in vec4 gl_BackSecondaryColorIn[gl_VerticesIn]; varying in vec4 gl_TexCoordIn[gl_VerticesIn][]; varying in float gl_FogFragCoordIn[gl_VerticesIn]; varying in vec4 gl_PositionIn[gl_VerticesIn]; varying in float gl_PointSizeIn[gl_VerticesIn]; varying in vec4 gl_ClipVertexIn[gl_VerticesIn];

55 25 de fevereiro de 2014 Exemplo #version 120 #extension GL_EXT_geometry_shader4:enable #extension GL_EXT_gpu_shader4:enable varying out vec3 eyeNormal; varying out vec3 vNormal; varying out vec3 eyePosition; varying out vec3 LightPosition; void main(void){ vec4 v = gl_PositionIn[0]; LightPosition = gl_LightSource[0].position; vec4 p0 = texture2D(vtx_tex, getPos(v.x)); vec4 p1 = texture2D(vtx_tex, getPos(v.y)); vec4 p2 = texture2D(vtx_tex, getPos(v.z)); vec4 p3 = texture2D(vtx_tex, getPos(v.w)); eyeNormal = n0; vNormal = vn0; eyePosition = py0; gl_Position = pt0; EmitVertex(); vNormal = vn1; eyePosition = py1; gl_Position = pt1; EmitVertex(); vNormal = vn2; eyePosition = py2; gl_Position = pt2; EmitVertex(); vNormal = vn2; eyePosition = py2; gl_Position = pt2; EmitVertex(); EndPrimitive(); }

56 25 de fevereiro de 2014 Exemplo #version 120 #extension EXT_gpu_shader4 : require varying vec3 eyeNormal; varying vec3 vNormal; varying vec3 eyePosition; varying vec3 LightPosition; void main() { vec3 light = normalize( LightPosition ); vec3 r = reflect( eyePosition, eyeNormal)*0.5; vec3 red = vec3( 0.23, 0.52, 0.72); const vec3 white = vec3( 1, 1, 1); float ndotl = max(dot( eyeNormal, light), 0.0); if (ndotl == 0.0) ndotl = dot( eyeNormal, -light); ndotl = min( max( ndotl, 0.0) + 0.2, 1.0); float spec = pow( max( 0.0, dot( r, light)), 32.0); vec3 color = clamp( ndotl*red + spec*white, 0.0, 1.0); gl_FragColor = vec4( color, 1.0); }

57 25 de fevereiro de 2014 Conclusões Diversos tipos de aplicações

58 25 de fevereiro de 2014 Conclusões

59 25 de fevereiro de 2014 Classe C++ para o Setup GLSL LCG Toolkit

60 25 de fevereiro de 2014 Exemplo de uso #include "glslkernel.h GLSLKernel VBOShader; VBOShader.vertex_source("vertex.glsl"); VBOShader.geometry_source("geometry.glsl"); VBOShader.fragment_source("fragment.glsl"); VBOShader.set_geom_max_output_vertices(12); VBOShader.set_geom_input_type(GL_POINTS); VBOShader.set_geom_output_type(GL_TRIANGLE_STRIP); VBOShader.install(true); VBOShader.use(true); VBOShader.set_uniform("vtx_tex", 0); VBOShader.use(true); glDrawElements( GL_POINTS, n_points, GL_UNSIGNED_INT, 0); VBOShader.use(false);

61 25 de fevereiro de 2014 Framebuffers

62 25 de fevereiro de 2014 Frame buffer Escrita em memória é feito pelo processador de fragmentos Memória GPU apenas de escrita Vertex Buffer Vertex Processor Rasterizer Fragment Processor Texture Frame Buffer(s) VS 3.0 GPUs

63 25 de fevereiro de OpenGL Framebuffer Objects Ideia Geral Framebuffer object pode ser visto como uma estrutura de ponteiros Associar memória da GPU a um framebuffer como write- only A memória não pode ser lida enquanto estiver associada ao framebuffer Qual memória? Texture Renderbuffer Vertex buffer?? Texture (RGBA) Renderbuffer (Depth) Framebuffer Object

64 25 de fevereiro de Framebuffer Objects O que é um FBO? Uma estrutura que manipula ponteiros e objetos memória Cada objeto memória associado pode ser usado como um framebuffer para rendering

65 25 de fevereiro de Framebuffer Objects (FBOs) OpenGL extension Habilita render-to-texture in OpenGL Mix-and-match depth/stencil buffers Substitui pbuffers! Platform-independent

66 25 de fevereiro de Framebuffer Objects Quais tipos de memória podem ser associados a um FBO? Textures Renderbuffers Depth, stencil, color Framebuffers de escrita tradicionais

67 25 de fevereiro de Que é um Renderbuffer? Modelo Traditional de memória framebuffer Memória GPU Write-only Color buffer Depth buffer Stencil buffer Novo objeto de memória OpenGL Parte do Framebuffer Object extension

68 25 de fevereiro de Renderbuffer Operações suportadas CPU interface Allocate Free Copia GPU CPU Associar para acesos write-only no framebuffer

69 25 de fevereiro de Framebuffer Objects Modo de uso Pode ter N texturas associadas a um FBO (até 16) destinos de rendering são cambiados com glDrawBuffers Manter uma FBO para cada tamanho/formato Mudar destinos de rendering attach/unattach textures Pode ter diferentes FBOs com texturas vinculadas Mudar destinos de rendering ligando (bind) FBOs

70 25 de fevereiro de Framebuffer Objects Performance Render-to-texture glDrawBuffers Mais eficientes que pbuffers Attach/unattach texturas é mais eficiente que mudar de FBO Manter formato/tamanho idêntico para todas as memórias associadas ao FBO Readback glReadPixels

71 25 de fevereiro de Framebuffer Object Exemplos e maiores detalhes Classes C++ de FBO e Renderbuffer OpenGL Spec

72 25 de fevereiro de Pixel Buffer Objects Mecanismo eficiente para transferir pixel data API parecido com vertex buffer objects Vertex Buffer Vertex Processor Rasterizer Fragment Processor Texture Frame Buffer(s) VS 3.0 GPUs

73 25 de fevereiro de Pixel Buffer Objects Usos Render-to-vertex-array glReadPixels no GPU-based pixel buffer Usar pixel buffer como vertex buffer Streaming de textures rápido Mapear PBO na memória da CPU Escrever diretamente ao PBO Reduz uma ou mais cópias Readback asincrono Cópia de dados GPU CPU não-bloqueante glReadPixels no PBO não bloqueiado É bloqueiado quando PBO é mapeiado na memória da CPU

74 25 de fevereiro de 2014 Resumo : Render-to-Texture Operação básica em apps GPGPU Suporte OpenGL Valores de 16, 32-bit por pixel Multiple Render Targets (MRTs) e Copy-to-texture glCopyTexSubImage Render-to-texture GL_EXT_framebuffer_object

75 25 de fevereiro de Resumo : Render-To-Vertex-Array Habilita retro-alimentação Suporte OpenGL Copy-to-vertex-array GL_ARB_pixel_buffer_object NVIDIA e ATI Render-to-vertex-array Não disponível

76 25 de fevereiro de Estruturas de dados básicas na GPU Implementing Efficient Parallel Data Structures on GPUs Chapter 33, GPU Gems II Low-level details

77 25 de fevereiro de GPU Arrays Large 1D Arrays Limite das GPUs em array 1D até 2048 ou 4096 Empacotados em memória 2D Precisa de mapear o endereço 1D-to-2D

78 25 de fevereiro de GPU Arrays 3D Arrays Problem GPUs não possuem 3D frame buffers Soluções 1. Empilhar fatias 2D 2. Múltiplas fatias de buffers 2D 3. Render-to-slice-of-3D-texture (NVidia G8)

79 25 de fevereiro de 2014 Exemplo: Simulação de Tecido Integration de Verlet Jakobsen, GDC 2001 Evita guardar velocidade explicita new_x = x + (x – old_x)*damping + a*dt*dt Não é exato, mas sim estável! Precisa guardar a posição atual é a anterior para cada partícula 2 RGB float textures O Fragment shader calcula a nova posição e escreve o resultado em outra textura textura (float buffer) Logo, intercambia as texturas atual e anterior

80 25 de fevereiro de 2014 Algoritmo Requer de 4 passos A cada passo renderiza uma quad com o fragment shader: 1.Executa a integração (move as partículas) 2.Aplica restrições (constraints): Restrição de distância entre partículas Colisão com os obstáculos (piso, esfera) 3.Calcula as normais 4. Renderiza a malha do tecido usando VBO

81 25 de fevereiro de 2014 Código da Integração uniform sampler2DRect oldp_tex; uniform sampler2DRect currp_tex; // Verlet integration step void Integrate(inout vec3 x, inout vec3 oldx, vec3 a, float timestep2){ vec3 tmpx = x; x = 2*x - oldx + a*timestep2; oldx = tmpx; } void main() { float timestep = 0.02; vec3 gravity = vec3(0.0, -9.8, 0.0); vec2 uv = gl_TexCoord[0].st; // get current and previous position vec3 oldx = texture2DRect(oldp_tex, uv).rgb; vec3 x = texture2DRect(currp_tex, uv).rgb; // move the particle Integrate(x, oldx, gravity, timestep*timestep); gl_FragColor = vec4(x, 1.0); }

82 25 de fevereiro de 2014 Código das restrições void main(){ const float stiffness = 0.2; // this should really be 0.5 vec2 uv = gl_TexCoord[0].st; vec3 x = texture2DRect(x_tex, uv).rgb; // get current position x = clamp(x, worldMin, worldMax); // satisfy world constraints SphereConstraint(x, spherePos, 1.0); // collision constraint with the sphere // get positions of neighbouring particles vec3 x1 = texture2DRect(x_tex, uv + vec2(1.0, 0.0)).rgb; vec3 x2 = texture2DRect(x_tex, uv + vec2(-1.0, 0.0)).rgb; vec3 x3 = texture2DRect(x_tex, uv + vec2(0.0, 1.0)).rgb; vec3 x4 = texture2DRect(x_tex, uv + vec2(0.0, -1.0)).rgb; vec3 x5 = texture2DRect(x_tex, uv + vec2(-1.0, -1.0)).rgb; vec3 x6 = texture2DRect(x_tex, uv + vec2(1.0, 1.0)).rgb; // apply distance constraints vec3 dx = vec3(0.0); if (uv.x < meshSize.x) dx = DistanceConstraint(x, x1, dist, stiffness); if (uv.x > 0.5) dx = dx + DistanceConstraint(x, x2, dist, stiffness); if (uv.y < meshSize.y) dx = dx + DistanceConstraint(x, x3, dist, stiffness); if (uv.y > 0.5) dx = dx + DistanceConstraint(x, x4, dist, stiffness); if (uv.x > 0.5 && uv.y > 0.5) dx = dx + DistanceConstraint(x, x5, dist2, stiffness); if (uv.x < meshSize.x && uv.y < meshSize.y) dx = dx + DistanceConstraint(x, x6, dist2, stiffness); x = x + dx; gl_FragColor = vec4(x, 1.0); }

83 25 de fevereiro de 2014 Resultado

84 25 de fevereiro de 2014 Objetos deformáveis A abordagem massa-mola usada na simulação de tecido pode ser estendida para simular objetos deformáveis. O objeto é representado por uma malha tetraédrica (sem slivers) Define-se uma restrição de distância (constraint) para cada aresta da malha. Cada vértice requer a lista de arestas incidentes (processo de relaxamento)

85 25 de fevereiro de 2014 Objetos deformáveis

86 25 de fevereiro de 2014 Introdução à API CUDA

87 GeForce 6 Architecture

88 Unidades programáveis Shader unificado GeForce 8800 GPU

89 GPU Architecture

90 CUDA–C Sem limitações dos shaders! Aplicações integradas host + device C program Partes serial e paralelo no código C host Partes totalmente em paralelo no código C device kernel C Código Serial (host)... Kernel Paralelo (device) KernelA >>(args); Código Serial (host) Kernel Paralelo (device) KernelB >>(args);

91

92 IDs de Blocos e IDs de Threads Cada thread usa IDs para decidir os dados com os que deve trabalhar Block ID: 1D ou 2D Thread ID: 1D, 2D, ou 3D Memoria simplificada Endereçamento Dados multidimensionais

93 Visão geral do Modelo de Memória do CUDA Memória Global Permite a comunicação de dados R/W entre host e device Visível a todos os threads Access não é rápido Memória Constante Memória compartilhada Registradores locais Grid Global Memory Block (0, 0) Shared Memory Thread (0, 0) Registers Thread (1, 0) Registers Block (1, 0) Shared Memory Thread (0, 0) Registers Thread (1, 0) Registers Host

94 CUDA Exemplo: Multiplicação de matrizes – Versão Host simples em C M N P WIDTH void MatrixMulOnHost(float* M, float* N, float* P, int Width){ for (int i = 0; i < Width; ++i) for (int j = 0; j < Width; ++j) { double sum = 0; for (int k = 0; k < Width; ++k) { double a = M[i * width + k]; double b = N[k * width + j]; sum += a * b; } P[i * Width + j] = sum; } i k k j

95 void MatrixMulOnDevice(float* M, float* N, float* P, int Width){ int size = Width * Width * sizeof(float); float* Md, Nd, Pd; // Allocate and Load M, N to device memory cudaMalloc(&Md, size); cudaMemcpy(Md, M, size, cudaMemcpyHostToDevice); cudaMalloc(&Nd, size); cudaMemcpy(Nd, N, size, cudaMemcpyHostToDevice); // Allocate P on the device cudaMalloc(&Pd, size); dim3 dimGrid(1, 1); dim3 dimBlock(Width, Width); // Launch the device computation threads! MatrixMulKernel >>(Md, Nd, Pd, Width); cudaMemcpy(P, Pd, size, cudaMemcpyDeviceToHost); // Read P from device cudaFree(Md); cudaFree(Nd); cudaFree (Pd); } CUDA Exemplo: Multiplicação de matrizes – Versão GPU

96 void MatrixMulOnDevice(float* M, float* N, float* P, int Width) { int size = Width * Width * sizeof(float); float* Md, Nd, Pd; // Allocate and Load M, N to device memory cudaMalloc(&Md, size); cudaMemcpy(Md, M, size, cudaMemcpyHostToDevice); cudaMalloc(&Nd, size); cudaMemcpy(Nd, N, size, cudaMemcpyHostToDevice); // Allocate P on the device cudaMalloc(&Pd, size); dim3 dimGrid(1, 1); dim3 dimBlock(Width, Width); // Launch the device computation threads! MatrixMulKernel >>(Md, Nd, Pd, Width); cudaMemcpy(P, Pd, size, cudaMemcpyDeviceToHost); // Read P from device cudaFree(Md); cudaFree(Nd); cudaFree (Pd); } Allocate memory on device CUDA Exemplo: Multiplicação de matrizes – Versão GPU

97 void MatrixMulOnDevice(float* M, float* N, float* P, int Width) { int size = Width * Width * sizeof(float); float* Md, Nd, Pd; // Allocate and Load M, N to device memory cudaMalloc(&Md, size); cudaMemcpy(Md, M, size, cudaMemcpyHostToDevice); cudaMalloc(&Nd, size); cudaMemcpy(Nd, N, size, cudaMemcpyHostToDevice); // Allocate P on the device cudaMalloc(&Pd, size); dim3 dimGrid(1, 1); dim3 dimBlock(Width, Width); // Launch the device computation threads! MatrixMulKernel >>(Md, Nd, Pd, Width); cudaMemcpy(P, Pd, size, cudaMemcpyDeviceToHost); // Read P from device cudaFree(Md); cudaFree(Nd); cudaFree (Pd); } Do Matrix multiplication on device CUDA Exemplo: Multiplicação de matrizes – Versão GPU

98 void MatrixMulOnDevice(float* M, float* N, float* P, int Width) { int size = Width * Width * sizeof(float); float* Md, Nd, Pd; // Allocate and Load M, N to device memory cudaMalloc(&Md, size); cudaMemcpy(Md, M, size, cudaMemcpyHostToDevice); cudaMalloc(&Nd, size); cudaMemcpy(Nd, N, size, cudaMemcpyHostToDevice); // Allocate P on the device cudaMalloc(&Pd, size); dim3 dimGrid(1, 1); dim3 dimBlock(Width, Width); // Launch the device computation threads! MatrixMulKernel >>(Md, Nd, Pd, Width); cudaMemcpy(P, Pd, size, cudaMemcpyDeviceToHost); // Read P from device cudaFree(Md); cudaFree(Nd); cudaFree (Pd); } Free device memory CUDA Exemplo: Multiplicação de matrizes – Versão GPU

99 Nd MdPd WIDTH // Matrix multiplication kernel – per thread code __global__ void MatrixMulKernel(float* Md, float* Nd, float* Pd, int Width) { // Pvalue is used to store the element of the matrix // that is computed by the thread float Pval = 0; for (int k = 0; k < Width; ++k) { float Melement = Md[threadIdx.y*Width+k]; float Nelement = Nd[k*Width+threadIdx.x]; Pval += Melement * Nelement; } Pd[threadIdx.y*Width+threadIdx.x] = Pval; } ty tx ty tx k k CUDA Exemplo: Multiplicação de matrizes – Versão GPU

100 Exemplos

101 25 de fevereiro de 2014 Referências dortmund.de/~goeddeke/gpgpu dortmund.de/~goeddeke/gpgpu


Carregar ppt "25 de fevereiro de 2014 Programação em GPUs (OpenGL/GLSL CUDA) Yalmar Ponce."

Apresentações semelhantes


Anúncios Google