1 / 41

Simulação de Sistemas de Partículas com GPU

Simulação de Sistemas de Partículas com GPU. Yalmar Ponce. Visão Geral (roteiro). Sistemas de Partículas Que é um sistema de partículas? Usos dos sistemas de partículas Simulação básica de sistemas de partículas Métodos de integração Sistemas de partículas no GPU

javen
Download Presentation

Simulação de Sistemas de Partículas com GPU

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Simulação deSistemas de Partículas comGPU Yalmar Ponce

  2. Visão Geral (roteiro) • Sistemas de Partículas • Que é um sistema de partículas? • Usos dos sistemas de partículas • Simulação básica de sistemas de partículas • Métodos de integração • Sistemas de partículas no GPU • Simulação e renderização sem manter o estado • Simulação física preservando o estado • Alguns métodos para transferência de dados de textura para dados de vértices

  3. Sistemas de Partículas • As primeiras aplicações foram em jogos • 1962 “Spacewar” • Uso de nuvens de pixeis para simular explosões • O movimento é randômico • 1978 “Asteroides” • Explosões usando movimentos de vetores • Provavelmente o primeiro jogo que usou “física” na simulação • 1983 “Star Trek II” • Simulação do movimento com efeitos especiais • O primeiro artigo de CG sobre sistemas de partículas • Ate hoje os conceitos não foram alterados

  4. Que é um sistema de partículas? • Pontos de massa individuais que se movem no espaço 2D/3D • Forças e restrições definem o movimento • Alguns valores iniciais (e.g. posições) são obtidos usando métodos randômicos ou construídos. • Freqüentemente renderizados como primitivasde geometria individuais.

  5. Usos dos sistemas de partículas • Explosões • Água • Fogo • Fumaça • neblina • Simulação de corpos • Efeitos após do impacto

  6. Simulação básica de sistemas de partículas • Partículas são pontos no espaço 2D/3D • Forças (e.g. gravidade, vento, de impacto) aceleram uma partícula • Aceleração muda a velocidade • Velocidade muda a posição

  7. Integrador de Euler • Precisa das seguintes propriedades • tpasso do tempo • a aceleração • vvelocidade • v´ velocidade anterior • p posição • p´ posição anterior • Integrando a velocidade v = v´ + a.t

  8. Integrador de Euler • Integrando a posição p = p´ + v.t • Computacionalmente simples • Precisa armazenar a posição e velocidade da partícula

  9. Integrador de Verlet • Integrando a posição p = 2.p´ - p´´+ v.t² • Onde p´´ e a posição previa à anterior • Não precisa armazenar a velocidade • O passo de tempo precisa ser (quase) constante • A velocidade pode ser aproximada

  10. Sistemas de partículas no GPU • Simulação sem estado • Efeitos simples • Feita no “vertex shader” • Disponível desde a primeira geração de GPUs programáveis • Simulação preservando o estado das partículas • Recentemente pesquisado (2003+) • Simulação é feita com o auxilio de texturas • Freqüentemente o processo é feito no “fragment shader” • Disponivel só nas GPUs NVIDIA FX 5xxx+ e ATI 9500+

  11. Simulação sem estado • Não armazena variações de estado nas partículas • Avalia funções fechadas que descrevem as mudanças do movimento/atributos • Dados computados dependem só de valores iniciais e uma descrição estática do ambiente

  12. Simulação preservando o estado • Posições e velocidades devem ser armazenadas em texturas • Estas texturas em cada passo de tempo da simulação são renderizadas em outras texturas de igual tamanho • O “Fragment shader” executa a integração iterativa • Posições de textura são “re-interpretados” como dados de vértices e pode-se renderizar grupos de vértices, triângulos ou retângulos

  13. Armazenamento do estado de uma partícula • Textura de posições • Textura de velocidades

  14. Armazenamento do estado de uma partícula • Posição e velocidade são armazenados em texturas • Texturas 1D, 2D ou 3D podem ser usadas dependendo da aplicação e os requerimentos • Precisão: • GL_FLOAT

  15. Operações de velocidade • Atualizar a textura de velocidades com varias operações: • Forças globais (vento, gravidade) • Forças locais (baseada em distancia, e.g. molas) • Forças de amortecimento • Forças de impacto • Após de ter a força total aplica-se a segunda lei de Newton (F = m.a) para obter a acelerção • Idêntico se as partículas tem massa unitária

  16. Operações de velocidade • Impacto / Colisão em GPU é limitada para ter maior eficiência • Quadricas • Mapas de altura, e.g. terrenos • Algoritmo • Detectar colisão • Determinar normal à superfície no ponto de impacto • Determinar profundidade de penetração • Resposta à colisão alterando a velocidade

  17. Resposta à colisão • Velocidade é dividida em duas partes • vn a velocidade normal • vt a velocidade tangencial vn = (v’.n)v’ vt = v’-vn Fricção pode ser aplicado n v vt vn

  18. Atualização da posição • Integração Euler • Integração Verlet • Acumular as forças (força total) • Atualizar posições • Resolver restrições de distância • Colisão é tratado por projeção (e.g. partículas fora do mundo são projetados para dentro)

  19. Transferindo dados de textura para dados de vértice • Após um passo da simulação precisamos transferir os dados da textura de posições para dados geométricos • Sistemas de partículas simples permitem uma eficiente transferência • Se o sistema de partículas representa um corpo pode ser preciso replicar vértices para interpretar o corpo • Existem diversos métodos para transferência de dados

  20. Uber-Buffer (também chamado Super Buffer) • Armazena dados na memória da placa gráfica • Copia de um buffer (textura) para outro buffer (vertex buffer) • Disponible em placas NVIDIA GF FXxxxx+ e ATI R9xxx+ • Precisa de varias extensões OpenGL: • ARB_super_buffer, • NV_pixel_buffer_object • NV_pixel_data_range

  21. Texturas de vértices • Acesso a texturas desde vertex shaders • (Problemas na placa gráfica ATI ???) • Vertex shader lê as posições das partículas • Disponible em OpenGL com (ARB_vertex_shader/GLSL)

  22. Métodos alternativos • Como renderizar imagens de saída numa textura? • glReadPixels()  glTexImage*() ? Lento. • glCopyTexImage*() Melhor. • glCopyTexSubImage*() Melhor ainda. • Renderizar diretamente em Texture (wglBindTexImageARB ) Elimina “copia de textura” potencialmente eficiente

  23. Renderizando diretamente em Textura • Não faz parte do coração do OpenGL, mas as extensões ARB o tornam possível na maioria de GPUs. • Extensões requeridas: • WGL_ARB_extensions_string • WGL_ARB_render_texture • WGL_ARG_PBUFFER • WGL_ARB_pixel_format • Disponíveis em todas as placas gráficas NVIDIA GeForce

  24. Renderizando diretamente em Textura: “Uma visão geral” • A idéia básica: • Um p-buffer para ser ligado como uma textura • Criar um objeto de textura • Criar um “Textura para renderizar” (quer dizer, um pixel buffer) • Algoritmo: • O PBuffer deve ser o destino atual para renderizar • Renderizar uma imagen • A janela deve ser destino atual para renderizar • Ligar o PBuffer para que seja o objeto texture • Usar o objeto textura como se fosse qualquer outro • Desligar o PBuffer do objeto texture

  25. Criando o objeto textura • Exatamente como se fosse uma textura –não precisa especificar os dados da textura // Create a render texture object glGenTextures( 1, &render_texture ); glBindTexture( GL_TEXTURE_2D, render_texture ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );

  26. Criando o PBuffer • Visão Geral • Obter um contexto valido HDC hdc = wglGetCurrentDC(); • Escolher um pixel format • Especificamente um conjunto minimo de atributos • Color bits, Depth bits, Stencil bits, single/double, etc. • Deve-se especificar também • WGL_DRAW_TO_PBUFFER and algum de • WGL_BIND_TO_TEXTURE_RGB_ARB or • WGL_BIND_TO_TEXTURE_RGBA_ARB como TRUE. • Então executamos wglChoosePixelFormat()

  27. Criando o PBuffer • Retorna uma lista of formatos o qual é adequado aos requerimentos minimos • Escolha um formato na lista • Criar o PBbuffer HPBuffer hbuf = wglCreatePBufferARB( hdc, fid, width, height, attr ); width e height são as dimensões do PBuffer “attr” é uma lista de outros atributos para o PBuffer. • Ajustar WGL_TEXTURE_FORMAT_ARB: • WGL_TEXTURE_RGB_ARB ou WGL_TEXTURE_RGBA_ARB • Ajustar WGL_TEXTURE_TARGET_ARB: • WGL_TEXTURE_1D_ARB, WGL_TEXTURE_2D_ARB, ou WGL_TEXTURE_CUBE_MAP_ARB • Ajustar WGL_MIPMAP_TEXTURE_ARB a um valor não zero para pedir espaço para os mipmaps. • Ajustar WGL_PBUFFER_LARGEST_ARB a um valor não zero para obter um PBuffer tão grande quanto possível.

  28. Criando o PBuffer • Conseguir o dispositivo de contexto para o PBuffer hpbufdc = wglGetPBufferDCARB( hbuf ); • Conseguir um contexto de renderizado para o PBbuffer: • Criar um novo • PBbuffer consegue seu próprio estado GL: hpbufglrc = wglCreateContext( hpbufdc ); • Consultar as dimensões atuais do PBbuffer criado wglQueryPBufferARB( hbuf, WGL_PBUFFER_WIDTH_ARB, width ); wglQueryPBufferARB( hbuf,WGL_PBUFFER_HEIGHT_ARB, height );

  29. Renderizar na textura • Pode ser feito a qualquer hora após de que a criação do PBuffer for completada • InitGL, DisplayGL, IdleGL, etc. • Deve-se selecionar o contexto de renderizado para o PBuffer corrente usando wglMakeCurrent: wglMakeCurrent( hpbufdc, hpbufglrc ); • Para voltar ao contexto da janela OpenGL wglMakeCurrent( hwindc, hwinglrc );

  30. Renderizar na textura • O mecanismo para renderizar textura permite renderizar em regiões especificas de uma textura: • Um nível especifico de uma textura mipmapped • Uma face especifica de um textura cube map • Um especifico nível mip de uma face especifica de uma textura cube map • Pode-se usar wglSetPBufferAttribARB() para escolher qual face do cube map ou nível do mipmap para renderizar. BOOL wglSetPBufferAttribARB (HPBufferARB hPBuffer, const int *piAttribList);

  31. Ligando o PBuffer ao objeto textura • Depois de ligar o objeto textura … • Executamos wglBindTexImageARB para ligar o PBuffer ao objeto textura. BOOL wglBindTexImageARB ( HPBufferARB hPBuffer, int iBuffer ); Ajutar “iBuffer” para WGL_FRONT_LEFT_ARB ou WGL_BACK_LEFT_ARB dependendo de qual buffer foi usado para renderizar a textura

  32. Desligando o PBuffer do objeto texture • ***Deve-se desligar (liberar) o PBuffer da textura antes de tentar renderizar novamente na janela OpenGL*** • Executamos wglReleaseTexImageARB para desligar o PBbuffer da textura. BOOL wglReleaseTexImageARB ( HPBufferARB hPBuffer, int iBuffer)

  33. Liberar tudo • Quando terminarmos de usar renderizado em textura, é importante garantir a liberação dos recursos consumidos pelo PBuffer. • Passos do processo de liberação • Apagar o contexto de rederizado • Liberar o dispositivo de contexto do PBuffer • Destruir o PBuffer wglDeleteContext( hpbufglrc ); wglReleasePBufferDCARB( hbuf, hpbufdc ); wglDestroyPBufferARB( hbuf );

  34. Texturas não restritas a potencia de 2 “Non-Power-of-Two Textures” (NPTT) • OpenGL só suporta texturas com resolução 2m x 2n • Mas texturas NPTT podem ser usadas • Adequar a alguma resolução de tela ou limite que não necessariamente seja potencia de 2 (800x600) • Restrição elevada:windows/NVIDIA Extensão WGL_NV_render_texture_rectangle • NPTT • Coordenadas de textura direfentes • Âmbito s,t : [0,Width], [0,Height] respectivamente em vez do âmbito [0,1], [0,1]. • Sem filtro mipmap • Não suporta texels sem borda ou textura com modos de repeatição

  35. Texturas não restritas a potencia de 2 “Non-Power-of-Two Textures” (NPTT) • Durante o processo de criação do PBuffer, para usar uma textura retangular de renderizado, deve-se especificar: WGL_BIND_TO_TEXTURE_RECTANGLE_RGB[A]_NV como TRUE na hora de escolher os atributos do formato de pixel e WGL_TEXTURE_TARGET_ARB como WGL_TEXTURE_RECTANGLE_NV na hora de criar o PBbuffer

  36. Múltiplas texturas de partículas • Problema: Não se pode mudar texturas enquanto se esta desenhando uma seqüência de partículas • Após de renderizar a textura de posições deve-se atualizar as texturas de posição atual e anterior para a proxima iteração.

  37. Resultados • Existe diversas incompatibilidades entre extenções de OpenGL: • De windows para linux • De NVIDIA para ATI • Os experimentos foram feitos numa ATI 9800 no windows usando GLUT • Para aproveitar o GPU foi usado renderizado em textura

  38. Resultados • O ajuste para selecionar um formato de pixel na ATI é: GLint pixelFormat; const int standardIAttribList[]={ WGL_RED_BITS_ARB, 16, WGL_GREEN_BITS_ARB, 16, WGL_BLUE_BITS_ARB, 16, WGL_ALPHA_BITS_ARB, 16, WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_FLOAT_ATI, WGL_STENCIL_BITS_ARB,8, WGL_DEPTH_BITS_ARB,24, WGL_DRAW_TO_PBUFFER_ARB, GL_TRUE, WGL_BIND_TO_TEXTURE_RGBA_ARB, GL_TRUE, 0}; wglChoosePixelFormatARB(hCurrentDC,standardIAttribList, fAttribList, 1, &pixelFormat, &numFormats)

  39. Resultados • Tendo o formato de pixel podemos criar um PBuffer com os seguintes atributos: int PBufferFlags[]={ WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB, WGL_MIPMAP_TEXTURE_ARB, GL_TRUE, WGL_PBUFFER_LARGEST_ARB, GL_TRUE, 0}; wglCreatePbufferARB(hCurrentDC, pixelFormat, width, height, PBufferFlags);

  40. Resultados • Para a simulação de partículas foi usado o integrador de Verlet, então três são texturas • O vertex shader void main(void) { texcoord = vec2(gl_Vertex); gl_TexCoord[0] = gl_MultiTexCoord0; gl_Position = ftransform(); } • O fragment-shader void main(void) { vec2 pos = gl_FragCoord.xy; vec3 oldPos = texture2D(oldPositionsTexture, getCoord(int(pos.x),int(pos.y))).rgb; vec3 currPos = texture2D(currentPositionsTexture, getCoord(int(pos.x),int(pos.y))).rgb; vec3 position = 2.0*currPos - oldPos +gravity*timestep*timestep; position = insideWorld(position); gl_FragColor = vec4(position, 1.0); }

  41. Resultados

More Related