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

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

Yalmar Ponce Simulação de Sistemas de Partículas com GPU.

Apresentações semelhantes


Apresentação em tema: "Yalmar Ponce Simulação de Sistemas de Partículas com GPU."— Transcrição da apresentação:

1 Yalmar Ponce Simulação de Sistemas de Partículas com GPU

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 primitivas de 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 –  t passo do tempo –a aceleração –v velocidade –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 –v n a velocidade normal –v t a velocidade tangencial v n = (v’.n)v’v t = v’-v n Fricção pode ser aplicado vnvn v n vtvt

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 1.Obter um contexto valido HDC hdc = wglGetCurrentDC(); 2.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 3.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 4.Conseguir o dispositivo de contexto para o PBuffer hpbufdc = wglGetPBufferDCARB( hbuf ); 5.Conseguir um contexto de renderizado para o PBbuffer: Criar um novo –PBbuffer consegue seu próprio estado GL: hpbufglrc = wglCreateContext( hpbufdc ); 6.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 1.Apagar o contexto de rederizado 2.Liberar o dispositivo de contexto do PBuffer 3.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 2 m x 2 n 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 v oid 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


Carregar ppt "Yalmar Ponce Simulação de Sistemas de Partículas com GPU."

Apresentações semelhantes


Anúncios Google