Programação em GPUs (OpenGL/GLSL CUDA)
-
Upload
brody-ayers -
Category
Documents
-
view
31 -
download
0
description
Transcript of Programação em GPUs (OpenGL/GLSL CUDA)
20 de abril de 2023
Programação em GPUs(OpenGL/GLSL
CUDA)
Yalmar Ponce
April 20, 2023
Roteiro
IntroduçãoTipos 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)
April 20, 2023
Introdução
AplicaçõesRenderização em tempo realEfeitosJogos
April 20, 2023
Introdução
GPUs são rápidas...3.0 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/sPreço: 499 dólares
April 20, 2023
Introdução
Versão simplificada da pipeline
GPUCPU
ApplicationApplication Transform& Light
Transform& Light RasterizeRasterize ShadeShade Video
Memory(Textures)
VideoMemory
(Textures)
Xfo
rmed, Lit V
ertice
s (2
D)
Graphics State
Render-to-texture
AssemblePrimitivesAssemblePrimitives
Vertice
s (3
D)
Scre
ensp
ace
triangle
s (2
D)
Fra
gm
ents (p
re-p
ixels)
Fin
al P
ixels (C
olo
r, D
epth
)
April 20, 2023
Introdução
Processador deVértices Programável
GPU
Transform& Light
Transform& Light
CPU
ApplicationApplication RasterizeRasterize ShadeShade VideoMemory
(Textures)
VideoMemory
(Textures)
Xfo
rmed, Lit V
ertice
s (2
D)
Graphics State
Render-to-texture
AssemblePrimitivesAssemblePrimitives
Vertice
s (3
D)
Scre
ensp
ace
triangle
s (2
D)
Fra
gm
ents (p
re-p
ixels)
Fin
al P
ixels (C
olo
r, D
epth
)
FragmentProcessorFragmentProcessor
VertexProcessor
VertexProcessor
Processador defragmentosProgramável
April 20, 2023
Introdução
Geração de geometria programável
GPUCPU
ApplicationApplication VertexProcessor
VertexProcessor RasterizeRasterize Fragment
ProcessorFragmentProcessor
VideoMemory
(Textures)
VideoMemory
(Textures)
Xfo
rmed, Lit V
ertice
s (2
D)
Graphics State
Render-to-texture
Vertice
s (3
D)
Scre
ensp
ace
triangle
s (2
D)
Fra
gm
ents (p
re-p
ixels)
Fin
al P
ixels (C
olo
r, D
epth
)
AssemblePrimitivesAssemblePrimitives
GeometryProcessorGeometryProcessor
Acesso a memória mais flexível
April 20, 2023
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)
April 20, 2023
Shaders
No caso:Vertex shader – Vertex ProcessorFragment shader – Fragment ProcessorGeometry shader – Geometry Processor
April 20, 2023
Shaders
Vertex ProcessorTransforma do espaço de mundo para o espaço de telaCalcula iluminação per-vertex
April 20, 2023
Shaders
Geometry ProcessorComo os vértices se conectam para formar a geometriaOperações por primitiva
April 20, 2023
Shaders
Fragment ProcessorCalcula a cor de cada pixelObtém cores de texturas
April 20, 2023
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 LanguageHLSL – High Level Shader LanguageCg – C for Graphics
April 20, 2023
Shaders
Temos algumas ferramentas que servem tanto para criação e edição de shaders:
NVIDIA FX Composer 2.5RenderMonkey ATI
April 20, 2023
Shaders
April 20, 2023
Shaders
April 20, 2023
Tipos de dados
Estruturas bem intuitivas
Vetores:vec2, vec3 e vec4 – floating pointivec2, ivec3 e ivec4 – intergerbvec2, bvec3 e bvec4 – boolean
Matrizesmat2, mat3 e mat4 – floating point
April 20, 2023
Tipos de dados
TexturasSampler1D, Sampler2D, Sampler3D -
texturas 1D, 2D e 3DSamplerCube – Cube map texturesSampler1Dshadow, Sampler2DShadow –
mapa de profundidade 1D e 2D
April 20, 2023
Input/Output
Existem 3 tipos de input em um shader:UniformsVaryingsAttributes
April 20, 2023
Input/Output
UniformsNão mudam durante o renderingEx: Posição da luz ou cor da luzEsta presente em todos os tipos de shader
VaryingsUsado para passar dados do vertex shader para o
fragment shader ou geometry shader
April 20, 2023
Input/Output
VaryingsSão read-only no fragment e geometry shader mas
read/write no vertex shaderDeve-se declarar a mesma varying em todos os
programas
AttributesEstão presentes apenas nos Vertex shadersSão valores (possivelmente diferentes) associados a cada
vértice
April 20, 2023
Input/Output
AttributesEx: Posição do vértice ou normaisSão apenas read-only
April 20, 2023
Input/Output
Exemplos de Attributes no vertex shadergl_Vertex – vetor 4D, posição do vérticegl_Normal – vetor 3D, Normal do vérticegl_Color – vetor 4D, cor do vérticegl_MultiTexCoordX – vetor 4D, coordenada de textura na
unit X
Existem vários outros atributos
April 20, 2023
Input/Output
Exemplos de Uniforms gl_ModelViewMatrixgl_ModelViewProjectionMatrixgl_NormalMatrix
April 20, 2023
Input/Output
Exemplos de Varyings gl_FrontColor - vetor 4D com a cor frontal das primitivasgl_BackColor – vetor 4D com a cor de trás das primitivasgl_TexCoord[N] – vetor 4D representando a n-ésima
coordenada de textura
April 20, 2023
Input/Output
Exemplos de output:gl_Position – vetor 4D representando a posição final do
vérticegl_FragColor – vetor 4D representando a cor final que
será escrita no frame buffergl_FragDepth – float representando o depth que será
escrito do depth buffer
April 20, 2023
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;
April 20, 2023
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;
April 20, 2023
Funções e Estruturas de Controle
Similar a linguagem C
Suporta estruturas de repetição e decisãoIf/elseForDo/whileBreakContinue
April 20, 2023
Funções e Estruturas de Controle
Possui funções como:Seno (sin)Cosseno (cos)Tangente (tan)Potencia (pow)Logaritmo (log)Logaritmo (log2)Raiz (sqrt)
April 20, 2023
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
April 20, 2023
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);
}
20 de abril de 2023
Exemplos simples
April 20, 2023
Hello World
O código shader mais simplesVertex Shadervoid main() {
gl_Position = ftransform();
} Fragment Shadervoid main(){
gl_FragColor = vec4(0.4,0.4,0.8,1.0);
}
April 20, 2023
Modificando a geometria
Achatar o modelo 3D, ou seja, z = 0void main(void) {
vec4 v = vec4(gl_Vertex);v.z = 0.0;
gl_Position = gl_ModelViewProjectionMatrix * v;}
April 20, 2023
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;
}
April 20, 2023
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
April 20, 2023
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_ModelViewProjectionMatrix*v;
}
A função de render:
void renderScene(void){
...
glUniform1fARB(loc, time);
glutSolidTeapot(1);
time+=0.01;
glutSwapBuffers();
}
April 20, 2023
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]
April 20, 2023
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 Shadervoid main(){
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}
April 20, 2023
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;
April 20, 2023
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)
April 20, 2023
Manipulação de Texturas
Vertex Shadervoid main(){
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}
Fragment shaderuniform sampler2D tex;
void main() {
vec4 color = texture2D(tex,gl_TexCoord[0].st);
gl_FragColor = color;
}
April 20, 2023
Múltiplas Texturas
Definir as texturasglGenTextures(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
April 20, 2023
Múltiplas Texturas
Multi TexturingglEnable (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);
April 20, 2023
GLSL e Multi-Textura
Cada textura que será usada no programa GLSL deve ser associada a uma textura na aplicação OpenGL.
Vertex/Fragment Shaderuniform 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 0glUniform1i(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
April 20, 2023
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);
20 de abril de 2023
Exemplos mais complexos
April 20, 2023
Efeito tijolo
Vertex Shaderhttp://www.3dshaders.com/shaders
2ndEd/CH06-brick.vert.txt
Fragment Shaderhttp://www.3dshaders.com/shaders
2ndEd/CH06-brick.frag.txt
April 20, 2023
Effeito madeira
Vertex Shaderhttp://www.3dshaders.com/
shaders2ndEd/CH15-wood.vert.txt
Fragment Shaderhttp://www.3dshaders.com/
shaders2ndEd/CH15-wood.frag.txt
April 20, 2023
Efeito nuvem
Vertex Shaderhttp://www.3dshaders.
com/shaders2ndEd/CH15-cloud.vert.txt
Fragment Shaderhttp://www.3dshaders.com/sha
ders2ndEd/CH15-cloud.frag.txt
20 de abril de 2023
Geometry Shader
April 20, 2023
Geometry Shader Permite mudar a geometria de entrada
Necessário especificar a geometria de entrada e saidaglProgramParameteriEXT(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 criadosglGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT,&temp);
glProgramParameteriEXT(GLhandleARB program, GL_GEOMETRY_VERTICES_OUT_EXT,temp);
April 20, 2023
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_MaxTextureCoordsvarying 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];
April 20, 2023
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(); }
April 20, 2023
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); }
April 20, 2023
Conclusões
Diversos tipos de aplicações
April 20, 2023
Conclusões
April 20, 2023
Classe C++ para o Setup GLSLLCG Toolkit
http://code.google.com/u/andmax/
April 20, 2023
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);
20 de abril de 2023
Framebuffers
April 20, 2023
Frame bufferFrame buffer
Escrita em memória é feito pelo processador de fragmentos
Memória GPU apenas de escrita
Vertex BufferVertex
ProcessorRasterizer
FragmentProcessor
Texture
Frame Buffer(s)
VS 3.0 GPUs
April 20, 2023 63
OpenGL Framebuffer OpenGL Framebuffer ObjectsObjects 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)
FramebufferObject
April 20, 2023 64
Framebuffer ObjectsFramebuffer 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
April 20, 2023 65
Framebuffer Objects (FBOs)Framebuffer Objects (FBOs)
OpenGL extension Habilita render-to-texture in OpenGL Mix-and-match depth/stencil buffers Substitui pbuffers! Platform-independent
http://oss.sgi.com/projects/ogl-sample/registry/EXT/framebuffer_object.txt
April 20, 2023 66
Framebuffer ObjectsFramebuffer Objects
Quais tipos de memória podem ser associados a um FBO? Textures Renderbuffers
Depth, stencil, color Framebuffers de escrita tradicionais
April 20, 2023 67
Que é um Renderbuffer?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
April 20, 2023 68
RenderbufferRenderbuffer
Operações suportadas CPU interface
Allocate Free Copia GPU CPU Associar para acesos write-only no framebuffer
April 20, 2023 69
Framebuffer ObjectsFramebuffer 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
April 20, 2023 70
Framebuffer ObjectsFramebuffer 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
April 20, 2023 71
Framebuffer ObjectFramebuffer Object
Exemplos e maiores detalhes Classes C++ de FBO e Renderbuffer
http://gpgpu.sourceforge.net/
OpenGL Spechttp://oss.sgi.com/projects/ogl-sample/registry/EXT/framebuffer_object.txt
April 20, 2023 72
Pixel Buffer ObjectsPixel Buffer Objects
Mecanismo eficiente para transferir pixel data API parecido com vertex buffer objects
Vertex BufferVertex
ProcessorRasterizer
FragmentProcessor
Texture
Frame Buffer(s)
VS 3.0 GPUs
April 20, 2023 73
Pixel Buffer ObjectsPixel 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
April 20, 2023
Resumo : Render-to-TextureResumo : 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
April 20, 2023 75
Resumo : Render-To-Vertex-ArrayResumo : 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
April 20, 2023 76
Estruturas de dados básicas na GPUEstruturas de dados básicas na GPU
“Implementing Efficient Parallel Data Structures on GPUs” Chapter 33, GPU Gems II
Low-level details
April 20, 2023 77
GPU ArraysGPU 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
April 20, 2023 78
GPU ArraysGPU 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)
April 20, 2023
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
April 20, 2023
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
April 20, 2023
Código da Integraçãouniform sampler2DRect oldp_tex;uniform sampler2DRect currp_tex;
// Verlet integration stepvoid 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);}
April 20, 2023
Código das restriçõesvoid 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);}
April 20, 2023
Resultado
April 20, 2023
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)
April 20, 2023
Objetos deformáveis
20 de abril de 2023
Introdução à API CUDA
April 20, 2023
GeForce 6 Architecture
April 20, 2023
Unidades programáveis
Shader unificado
GeForce 8800 GPU
April 20, 2023
GPU Architecture
April 20, 2023
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<<< nBlk, nTid >>>(args);
Código Serial (host)
Kernel Paralelo (device)
KernelB<<< nBlk, nTid >>>(args);
April 20, 2023
April 20, 2023
Host
Kernel 1
Kernel 2
Device
Grid 1
Block(0, 0)
Block(1, 0)
Block(0, 1)
Block(1, 1)
Grid 2
Courtesy: NDVIA
Figure 3.2. An Example of CUDA Thread Organization.
Block (1, 1)
Thread(0,1,0)
Thread(1,1,0)
Thread(2,1,0)
Thread(3,1,0)
Thread(0,0,0)
Thread(1,0,0)
Thread(2,0,0)
Thread(3,0,0)
(0,0,1) (1,0,1) (2,0,1) (3,0,1)
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
April 20, 2023
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
April 20, 2023
CUDA Exemplo: Multiplicação de matrizes – Versão Host simples em C
M
N
P
WID
TH
WID
TH
WIDTH 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
April 20, 2023
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<<<dimGrid, dimBlock>>>(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
April 20, 2023
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<<<dimGrid, dimBlock>>>(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
April 20, 2023
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<<<dimGrid, dimBlock>>>(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
April 20, 2023
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<<<dimGrid, dimBlock>>>(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
April 20, 2023
Nd
Md Pd
WID
TH
WID
TH
WIDTH 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
April 20, 2023
Exemplos
April 20, 2023
Referências
http://www.mathematik.uni-dortmund.de/~goeddeke/gpgpu
http://www.gpgpu.org
http://developer.nvidia.com/object/sdk_home
http://www.nvidia.com/object/cuda_home.html