Télécharger la présentation
La présentation est en train de télécharger. S'il vous plaît, attendez
1
Programmation GPU avec Cg et GLSL
Olivier NOCENT
2
Introduction «Cg (C for Graphics) is a high level shading language for programmable GPUs» (Bill Mark, nVIDIA) Qu’est ce que c’est ? Pour quoi faire ? Comment ça marche ? IUT de Reims [ ]
3
High level shading language
Qu’est ce que c’est ? Shading language: langage de description des interactions, simples ou complexes, entre la lumière et la matière. IUT de Reims [ ]
4
1984 : «Shade Trees» par Rob Cook (Lucasfilm Ltd.)
Final Color Copper Color Weight of Ambient Components Ambient Weight of Specular Components Specular Normal Viewer Surface Roughness Chaque feuille de l’arbre représente une valeur. (couleur, vecteur, coefficient, …) Chaque nœud de l’arbre représente une opération. (addition, multiplication, produit scalaire, …) IUT de Reims [ ]
5
Premiers « Shading Languages »
Plus de souplesse dans la description des interactions Lumière/Matière. Prise en compte des aspects «dynamiques» (textures procédurales) 1988 : «Renderman» par Pat Hanrahan (Pixar) 2000 : «Interactive Shading Language» (SGI) 2001 : «Stanford Real-Time Shading Language» IUT de Reims [ ]
6
Arbre généalogique des « Shading Languages »
C (AT&T, 1970) Langage généraliste Shading Language API graphique Langage GPU Shade Trees (Cook, 1984) C++ (AT&T, 1983) Renderman (Pixar, 1988) OpenGL (ARB, 1992) DirectX (Microsoft, 1995) Interactive Shading Language (SGI, 2000) Real-Time Shading Language (Stanford, 2001) C for Graphics (nVIDIA, 2002) HLSL (Microsoft, 2003) GL Shading Language (3Dlabs, 2004) IUT de Reims [ ]
7
Références bibliographiques
Shade Trees Robert Cook (SIGGRAPH 1984) RenderMan : a Language for Shading and Lighting Calculations Pat Hanrahan and Jim Lawson (SIGGRAPH 1990) A Shading Language on Graphics Hardware: The Pixel Flow Shading System Marc Olano and Anselmo Lastra (SIGGRAPH 1998) A Real-Time Procedural Shading System for Programmable Graphics Hardware Kekoa Proudfoot, Bill Mark and Svetoslav Tzvetkov (SIGGRAPH 2001) IUT de Reims [ ]
8
High level shading language for GPUs
Pour quoi faire ? IUT de Reims [ ]
9
Graphics Pipeline Application OpenGL DirectX Uniform parameters (Matrices, light positions, blend factors, …) Vertex operations Transform Lighting Fragment operations Texture mapping Primitive Assembly Rasterization & Interpolation Frame-Buffer Tests Textures Vertex indices Graphics pipeline: enchaînement d’opérations appliquées aux données géométriques afin de produire l’affichage d’une scène 3D. IUT de Reims [ ]
10
Rasterization & Interpolation
Graphics Pipeline Position Position Vertex Operations Transform & Lighting Primitive assembly Normal Color Texture Coords Texture Coords Pixel Operations Texture Mapping Rasterization & Interpolation Color Color Texture Coords Depth IUT de Reims [ ]
11
1998/1999 : la première génération.
Application OpenGL DirectX Uniform parameters (Matrices, light positions, blend factors, …) Vertex operations Transform Lighting Fragment operations Texture mapping Primitive Assembly Rasterization & Interpolation Frame-Buffer Tests Textures Vertex indices CPU GPU Rasterization + texture mapping (DirectX 6, OpenGL) nVidia TNT2 ATI Rage 3dfx Voodoo3 IUT de Reims [ ]
12
1999/2000 : la deuxième génération.
Application OpenGL DirectX Uniform parameters (Matrices, light positions, blend factors, …) Vertex operations Transform Lighting Fragment operations Texture mapping Primitive Assembly Rasterization & Interpolation Frame-Buffer Tests Textures Vertex indices CPU GPU Transform & Lighting (DirectX 7, OpenGL) nVidia GeForce 256 ATI Radeon 7500 S3 Savage3D IUT de Reims [ ]
13
2001/2002 : la troisième génération.
Application OpenGL DirectX Uniform parameters (Matrices, light positions, blend factors, …) Vertex operations Transform Lighting Custom Vertex Program Fragment operations Texture mapping Primitive Assembly Rasterization & Interpolation Frame-Buffer Tests Textures Vertex indices CPU GPU Vertex programmability ( DirectX 8, OpenGL NV_vertex_program ) nVidia GeForce 3, GeForce 4 Ti ATI Radeon 8500 IUT de Reims [ ]
14
2003/? : la quatrième et dernière génération.
Application OpenGL DirectX Uniform parameters (Matrices, light positions, blend factors, …) Custom Fragment Program Vertex operations Transform Lighting Custom Vertex Program Fragment operations Texture mapping Primitive Assembly Rasterization & Interpolation Frame-Buffer Tests Textures Vertex indices CPU GPU Vertex & Pixel programmability (DirectX 9, OpenGL ARB_shader_object ) nVidia GeForce FX, GeForce 6800 ATI Radeon 9700 IUT de Reims [ ]
15
3 appels au Vertex Program n appels au Fragment Program
Graphic Pipeline 3 appels au Vertex Program Position Position Primitive assembly Vertex Operations Transform & Lighting Normal Color Texture Coords Texture Coords n appels au Fragment Program Rasterization & Interpolation Pixel Operations Texture Mapping Color Color Texture Coords Depth IUT de Reims [ ]
16
Quelques chiffres… Génération Année Gamme Transistors Fill rate Polygon rate 1ère Fin 1998 RIVA TNT 7 M 50 M/s 6 M/s Début 1999 RIVA TNT2 9 M 75 M/s 9 M/s 2ème Fin 1999 GeForce 256 23 M 120 M/s 15 M/s Début 2000 GeForce 2 25 M 200 M/s 25 M/s 3ème Début 2001 GeForce 3 57 M 800 M/s 30 M/s Début 2002 GeForce 4 Ti 63 M 1200 M/s 60 M/s 4ème Début 2003 GeForce FX 125 M 2000 M/s NB: le microprocesseur Pentium 4 d’Intel contient 55 M de transistors. IUT de Reims [ ]
17
Encore quelques chiffres…
Comparaison des performances CPU et GPU réalisée par Mark Harris [1]. Processeur GFLOPS* Débit Pentium GHz 6 (théorique) 5.96 Go/s GeForce FX 5900 20 (observée) 25.6 Go/s GeForce 6800 Ultra 40 (observée) 35.2 Go/s * GFLOPS : Giga floating point operations per second Loi de Moore (CPU) : Croissance sur 10 ans ~ 60× GPU : Croissance sur 10 ans > 1000× [1] «GPGPU: General-Purpose Computation on GPUs» par Mark Harris (NVIDIA Developer Technology Group) présenté à EuroGraphics’2004 IUT de Reims [ ]
18
1995 SEGA Virtua Fighter 50.000 polygones/s 1 M píxels/s
IUT de Reims [ ]
19
2001 100 M polygones/s 1 G píxels/s
IUT de Reims [ ]
20
Doom (1993) IUT de Reims [ ]
21
Doom II (1994) IUT de Reims [ ]
22
Doom III (2004) IUT de Reims [ ]
23
Doom III (2004) IUT de Reims [ ]
24
High level shading language for GPUs
Comment ça marche ? IUT de Reims [ ]
25
Chronologie DirectX 9 HLSL High Level Shading Language
OpenGL 1.5 GLSLang OpenGL Shading Language Fin 2002 Début 2003 Début 2004 IUT de Reims [ ]
26
Références bibliographiques
The Cg Tutorial: The Definitive Guide to Programmable Real-Time Graphics Randima Fernando, Mark J. Kilgard Addison-Wesley Professional edition February 26, 2003 384 pages ISBN: IUT de Reims [ ]
27
Références bibliographiques
OpenGL(R) Shading Language Randi J. Rost Addison-Wesley Professional February 12, 2004) 608 pages ISBN: IUT de Reims [ ]
28
Références bibliographiques
GPU Gems: Programming Techniques, Tips, and Tricks for Real-Time Graphics Randima Fernando Addison-Wesley Professional edition March 22, 2004 816 pages ISBN: IUT de Reims [ ]
29
Références bibliographiques
GPU Gems 2 : Programming Techniques for High-Performance Graphics and General-Purpose Computation Matt Pharr, Randima Fernando Addison-Wesley Professional edition March 3, 2005 880 pages ISBN: IUT de Reims [ ]
30
Références bibliographiques
Metaprogramming GPUs with Sh Michael McCool, Stefanus DuToit AK Peters, Ltd. July 29, 2004 307 pages ISBN: IUT de Reims [ ]
31
Sur le web Cg http://developer.nvidia.com DirectX 9 HLSL
OpenGL Shading Language Programmation GPU IUT de Reims [ ]
32
High level shading language for GPUs
: C for Graphics IUT de Reims [ ]
33
Compilateur Cg (runtime)
Cg : principe général Cg shader Compilateur Cg (runtime) IUT de Reims [ ]
34
Cg : du code source au code exécutable
Application DirectX Opengl OpenGL DirectX driver Graphics Hardware (GPU) Shader Source Shader Object Assembly Program Cg API Cg Compiler Assembler IUT de Reims [ ]
35
Acte I : présentation des acteurs.
C/C++ Program main CPU GPU Vertex Processor Fragment Processor IUT de Reims [ ]
36
Acte II : contexte de communication entre le CPU et le GPU.
C/C++ Program main CPU GPU Vertex Processor Fragment Processor CGcontext* Context = cgCreateContext(); IUT de Reims [ ]
37
Acte III : compilation et chargement du « shader ».
Context C/C++ Program main VProgram Vertex Program myvp Fragment Program myfp CPU GPU Vertex Processor Fragment Processor VProgram = cgCreateProgramFromFile(Context,CG_SOURCE, "pixel_true_phong.cg",CG_PROFILE_VP30,"myvp",NULL); cgGLLoadProgram(VProgram); IUT de Reims [ ]
38
Acte IV : association et passage de paramètres.
Context C/C++ Program main VProgram LightPosition Vertex Program myvp Fragment Program myfp CPU GPU Vertex Processor Fragment Processor LightPositionBind = cgGetNamedParameter(VProgram, "LightPosition"); cgGLSetParameter4f(LightPositionBind, x, y, z, w); IUT de Reims [ ]
39
Acte V : activation/désactivation du programme.
Context C/C++ Program main VProgram LightPosition Vertex Program myvp Fragment Program myfp CPU GPU Vertex Processor Fragment Processor cgGLEnableProfile(CG_PROFILE_VP30); cgGLBindProgram(VProgram); ... cgGLDisableProfile(CG_PROFILE_VP30); IUT de Reims [ ]
40
« Semantics » Vertex Program Fragment Program POSITION POSITION NORMAL
glVertex3f(…) Vertex Program POSITION POSITION glNormal3f(…) NORMAL COLOR glMultiTexCoord(0,…) TEXCOORD0 TEXCOORD0 glMultiTexCoord(1,…) TEXCOORD1 TEXCOORD1 Fragment Program COLOR COLOR TEXCOORD0 DEPTH TEXCOORD1 IUT de Reims [ ]
41
High level shading language for GPUs
GLSL OpenGL Shading Language IUT de Reims [ ]
42
OpenGL Shading Language : principe général
GLSL shader Compilateur GLSL (runtime) IUT de Reims [ ]
43
GLSL : du code source au code exécutable
Application OpenGL only OpenGL driver Graphics Hardware (GPU) Shader Source Shader Object Program Object OpenGL API Compiler Linker IUT de Reims [ ]
44
Acte I : présentation des acteurs.
C/C++ Program main CPU GPU Vertex Processor Fragment Processor IUT de Reims [ ]
45
Acte II : compilation et chargement du « shader ».
Program C/C++ Program main Vertex Program main Fragment Program main CPU GPU Vertex Processor Fragment Processor VShader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB); glShaderSourceARB(VShader, 1, (const GLcharARB**) &VSource, NULL); glCompileShaderARB(VShader); FShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB); glShaderSourceARB(FShader, 1, (const GLcharARB**) &FSource, NULL); glCompileShaderARB(FShader); Program = glCreateProgramObjectARB(); glAttachObjectARB(Program, VShader); glAttachObjectARB(Program, FShader); glLinkProgramARB(Program); IUT de Reims [ ]
46
Acte III : association et passage de paramètres.
C/C++ Program main Program LightPosition Vertex Program main Fragment Program main CPU GPU Vertex Processor Fragment Processor GLint LightPositionloc = glGetUniformLocationARB(Program, "LightPosition"); glUniform4fARB(LightPositionloc , x, y, z, w); IUT de Reims [ ]
47
Acte IV : activation/désactivation du programme.
C/C++ Program main Program LightPosition Vertex Program main Fragment Program main CPU GPU Vertex Processor Fragment Processor glUseProgramObjectARB(Program); ... glUseProgramObjectARB(0); IUT de Reims [ ]
48
« Built-in » variables Vertex Program Fragment Program gl_Vertex
glVertex3f Vertex Program gl_Vertex gl_Position glNormal3f gl_Normal gl_FrontColor glMultiTexCoord(0,…) gl_MultiTexCoord0 gl_MultiTexCoord0 glMultiTexCoord(1,…) gl_MultiTexCoord1 gl_MultiTexCoord1 Fragment Program gl_Color gl_FragColor gl_TexCoord[0] gl_FragDepth gl_TexCoord[1] IUT de Reims [ ]
49
GLOOSE: Object Oriented Shading Environment for OpenGL
Un phare dans la brume des Shading Languages (Cg, GLSL) ShaderObject createFromVertexSourceFile(const char*) createFromFragmentSourceFile(const char*) createFromSourceFiles(const char*, const char*) enable() disable() setParameter1f(const char*, float) setParameter2f(const char*, float, float) setParameter3f(const char* ParameterName, float, float, float) ... CGGLShaderObject ... GLSLShaderObject ... IUT de Reims [ ]
50
GLOOSE en action !! IUT de Reims [ olivier.nocent@univ-reims.fr ]
#define CGGL //#define GLSL #include <cggl_shader_object.h> #include <glsl_shader_object.h> ShaderObject* Shader; void display() { ... Shader->enable(); Shader->setParameter1f("twisting", Twisting); Shader->disable(); } int main() { #ifdef CGGL Shader = new CGGLShaderObject(arb1); Shader->createFromVertexSourceFile("shaders/Cg/twisting.cg"); #endif #ifdef GLSL Shader = new GLSLShaderObject(); Shader->createFromVertexSourceFile("shaders/GLSL/twisting.vert"); IUT de Reims [ ]
51
« Un code source vaut dix mille mots » (vieux proverbe informatique)
Epilogue « Un code source vaut dix mille mots » (vieux proverbe informatique) IUT de Reims [ ]
52
P ’ = RotationZ( twist x ||P|| ) x P
Twisting P ’ = RotationZ( twist x ||P|| ) x P twist = 0 twist = 3 IUT de Reims [ ]
53
twisting.cg [Cg] IUT de Reims [ olivier.nocent@univ-reims.fr ]
struct myvertin { float4 Position : POSITION; float4 Color : COLOR; }; struct myvertout { myvertout main(myvertin IN, uniform float twisting, uniform float4x4 ModelViewProjectionMatrix) { myvertout OUT; float angle = twisting*length(IN.Position); float cosLength, sinLength; sincos(angle, sinLength, cosLength); OUT.Position.x = cosLength*IN.Position.x - sinLength*IN.Position.y; OUT.Position.y = sinLength*IN.Position.x + cosLength*IN.Position.y; OUT.Position.z = 0.0f; OUT.Position.w = 1.0f; OUT.Position = mul(ModelViewProjectionMatrix, OUT.Position); OUT.Color = IN.Color; return OUT; } IUT de Reims [ ]
54
twisting.vert [GLSL] uniform float twisting; void main(void) {
float angle = twisting*length(gl_Vertex); float cosLength = cos(angle); float sinLength = sin(angle); gl_Position.x = cosLength*gl_Vertex.x - sinLength*gl_Vertex.y; gl_Position.y = sinLength*gl_Vertex.x + cosLength*gl_Vertex.y; gl_Position.z = 0.0; gl_Position.w = 1.0; gl_Position = gl_ModelViewProjectionMatrix * gl_Position; gl_FrontColor = gl_Color; } IUT de Reims [ ]
55
Simple Phong shading (OpenGL ou DirectX)
V N Color = AmbientColor + DiffuseColor x ( N . L ) + SpecularColor x ( N . H )n H = ( V + L )/2 (half vector) IUT de Reims [ ]
56
True Phong shading L R V N
Color = AmbientColor + DiffuseColor x ( N . L ) + SpecularColor x ( R . V )n R : Reflected light vector IUT de Reims [ ]
57
vp_per_vertex_true_phong.cg [Cg]
struct myvertin { float4 Position : POSITION; float4 Normal : NORMAL; }; struct myvertout { float4 Position : POSITION; float4 Color : COLOR; myvertout main(myvertin IN, uniform float4x4 ProjectionMatrix, uniform float4x4 ModelViewMatrix, uniform float4x4 ModelViewMatrixIT, uniform float4 LightPosition, uniform float4 DiffuseMaterial, uniform float4 SpecularMaterial) { myvertout OUT; OUT.Position = mul(ModelViewMatrix, IN.Position); // Vertex position in View space. float3 N = normalize(mul(ModelViewMatrixIT, IN.Normal).xyz); // Vertex normal in View space. float3 L = normalize((LightPosition - OUT.Position).xyz); // Light vector in View space. OUT.Color = DiffuseMaterial * 0.4; // Ambient component. float diffuse = dot(N, L); if (diffuse>0) { OUT.Color += DiffuseMaterial * diffuse; // Diffuse component. float3 R = reflect(-L, N); // Reflected light vector in View space. float3 V = normalize(-OUT.Position.xyz); // Reflected light vector in View space. float specular = dot(V, R); if (specular>0) OUT.Color += SpecularMaterial * pow(specular, 40); // Specular component. } OUT.Position = mul(ProjectionMatrix, OUT.Position); // Vertex position in Screen space. return OUT; IUT de Reims [ ]
58
per_vertex_true_phong.vert [GLSL]
uniform vec4 LightPosition; uniform vec4 DiffuseMaterial; uniform vec4 SpecularMaterial; void main() { gl_Position = gl_ModelViewMatrix * gl_Vertex; // Vertex position in View space. vec3 N = normalize(gl_NormalMatrix * gl_Normal); // Vertex normal in View space. vec3 L = normalize((LightPosition - gl_Position).xyz); // Light vector in View space. gl_FrontColor = DiffuseMaterial * 0.4; // Ambient component. float diffuse = dot(N, L); if (diffuse>0) { gl_FrontColor += DiffuseMaterial * diffuse; // Diffuse component. vec3 R = reflect(-L, N); // Reflected light vector in View space. vec3 V = normalize(-gl_Position .xyz); // View vector in View space. float specular = dot(V, R); if (specular>0) gl_FrontColor += SpecularMaterial * pow(specular, 40); // Specular component. } gl_Position = gl_ProjectionMatrix * gl_Position; // Vertex position in Screen space. IUT de Reims [ ]
59
Per vertex true phong shading (1)
IUT de Reims [ ]
60
Per vertex true phong shading (2)
IUT de Reims [ ]
61
Comparaison des deux modèles.
IUT de Reims [ ]
62
vp_per_pixel_true_phong.cg [Cg]
struct myvertin { float4 Position : POSITION; float4 Normal : NORMAL; }; struct myvertout { float4 ProjPosition : POSITION; float4 Position : TEXCOORD0; float4 Normal : TEXCOORD1; myvertout main(myvertin IN, uniform float4x4 ModelViewProjectionMatrix, uniform float4x4 ModelViewMatrix, uniform float4x4 ModelViewMatrixIT) { myvertout OUT; // Vertex position in Screen space. OUT.ProjPosition = mul(ModelViewProjectionMatrix, IN.Position); // Vertex position in View space. OUT.Position = mul(ModelViewMatrix, IN.Position); // Vertex normal in View space. OUT.Normal = mul(ModelViewMatrixIT, IN.Normal); return OUT; } IUT de Reims [ ]
63
fp_per_pixel_true_phong.cg [Cg]
struct myfragin { float4 Position : TEXCOORD0; float4 Normal : TEXCOORD1; }; struct myfragout { float4 Color : COLOR; myfragout main(myfragin IN, uniform float4 LightPosition, uniform float4 DiffuseMaterial, uniform float4 SpecularMaterial) { myfragout OUT; float3 N = normalize(IN.Normal.xyz); float3 L = normalize((LightPosition - IN.Position).xyz); OUT.Color = DiffuseMaterial * 0.4; float diffuse = dot(N, L); if (diffuse>0) { OUT.Color += DiffuseMaterial * diffuse; float3 R = reflect(-L, N); float3 V = normalize(-IN.Position.xyz); float specular = dot(V, R); If (specular>0) OUT.Color += SpecularMaterial * pow(specular, 40); } return OUT; IUT de Reims [ ]
64
per_pixel_true_phong.vert [GLSL]
void main() { // Vertex position in Screen space. gl_Position = ftransform(); // Vertex position in View space. gl_TexCoord[0] = gl_ModelViewMatrix * gl_Vertex; // Vertex normal in View space. gl_TexCoord[1] = vec4(gl_NormalMatrix * gl_Normal, 0); } IUT de Reims [ ]
65
per_pixel_true_phong.frag [GLSL]
uniform vec4 LightPosition; // Light position in View space. uniform vec4 DiffuseMaterial; // Material. uniform vec4 SpecularMaterial; void main() { // Vertex normal in View space. vec3 N = normalize(gl_NormalMatrix * gl_TexCoord[1].xyz); // Light vector in View space. vec3 L = normalize((LightPosition - gl_ModelViewMatrix * gl_TexCoord[0]).xyz); // Ambient component. gl_FragColor = DiffuseMaterial * 0.4; float diffuse = dot(N, L); if (diffuse>0) { // Diffuse component. gl_FragColor += DiffuseMaterial * diffuse; // Reflected light vector in View space. vec3 R = reflect(-L, N); // View vector in View space. vec3 V = normalize(-gl_TexCoord[0].xyz); // Specular component. float specular = dot(V, R); if (specular>0) gl_FragColor += SpecularMaterial * specular; } IUT de Reims [ ]
66
Toon Shading IUT de Reims [ ]
67
Toon Shading C C N.L N.L IUT de Reims [ ]
68
vp_toon_shading.cg [Cg]
struct myvertin { float4 Position : POSITION; float4 Normal : NORMAL; }; struct myvertout { float4 Position : POSITION; float DiffuseComponent : TEXCOORD0; float SpecularComponent : TEXCOORD1; float Edge : TEXCOORD2; myvertout main(myvertin IN, uniform float4 LightPosition, uniform float4x4 ModelViewMatrix, uniform float4x4 ModelViewMatrixIT, uniform float4x4 ProjectionMatrix) { myvertout OUT; OUT.Position = mul(ModelViewMatrix, IN.Position); // Output vertex position in View space. float3 N = normalize(mul(ModelViewMatrixIT, IN.Normal).xyz); // Vertex normal in View space. float3 L = normalize(LightPosition.xyz - OUT.Position.xyz); // Light vector in View space. float3 V = normalize(-OUT.Position.xyz); // View vector in View space. OUT.Edge = max(dot(N, V), 0); // Perform edge detection OUT.DiffuseComponent = dot(N, L); // Compute diffuse component. if (OUT.DiffuseComponent > 0) { float3 H = normalize(L + V); // Half vector in View space. OUT.SpecularComponent = pow(max(dot(N, H), 0), 40); } else { OUT.DiffuseComponent = 0; OUT.SpecularComponent = 0; } OUT.Position = mul(ProjectionMatrix, OUT.Position); // Output vertex position in Screen space. return OUT; IUT de Reims [ ]
69
fp_toon_shading.cg [Cg]
struct myfragin { float DiffuseComponent : TEXCOORD0; float SpecularComponent : TEXCOORD1; float Edge : TEXCOORD2; }; struct myfragout { float4 Color : COLOR; myfragout main(myfragin IN) { myfragout OUT; if (IN.Edge < 0.2) OUT.Color = float4(0, 0, 0, 1); else { if (IN.DiffuseComponent < 0.2) IN.DiffuseComponent = 0.3; else IN.DiffuseComponent = 1.0; if (IN.SpecularComponent < 0.5) IN.SpecularComponent = 0.0; IN.SpecularComponent = 1.0; OUT.Color = float4(1, 0, 0, 1)*IN.DiffuseComponent + float4(1, 1, 1, 1)*IN.SpecularComponent; } return OUT; IUT de Reims [ ]
70
toon_shading.vert [GLSL]
uniform vec4 LightPosition; void main() { gl_Position = gl_ModelViewMatrix * gl_Vertex; // Vertex position in View space. vec3 N = normalize(gl_NormalMatrix * gl_Normal); // Vertex normal in View space. vec3 L = normalize((LightPosition - gl_Position).xyz); // Light vector in View space. vec3 V = normalize(-gl_Position.xyz); // View vector in View space. gl_TexCoord[0].x = max(dot(N, V), 0.0); // Perform edge detection. gl_TexCoord[0].y = dot(N, L); // Diffuse component. if (gl_TexCoord[0].y>0) { vec3 H = normalize(L + V); // Half vector in View space. gl_TexCoord[0].z = pow(max(dot(N, H), 0.0), 40); } else { gl_TexCoord[0].y = 0.0; gl_TexCoord[0].z = 0.0; gl_Position = gl_ProjectionMatrix * gl_Position; // Vertex position in Screen space. IUT de Reims [ ]
71
toon_shading.frag [GLSL]
void main() { float diffuse, specular; if (gl_TexCoord[0].x< 0.1) gl_FragColor = vec4(0, 0, 0, 1); else { // Compute final color with fixed diffuse and specular materials. if (gl_TexCoord[0].y< 0.2) diffuse = 0.3; else diffuse = 1.0; if (gl_TexCoord[0].z<0.5) specular = 0.0; specular = 1.0; gl_FragColor = vec4(1, 0, 0, 1)*diffuse + vec4(1, 1, 1, 1)*specular; } IUT de Reims [ ]
72
Rendu Raytracing High Dynamic Range Rendering
IUT de Reims [ ]
73
Simulation physique Simulation de fluides Animation de vêtements
IUT de Reims [ ]
74
Traitement Numérique des Images
Calcul d’histogrammes Détection de contours IUT de Reims [ ]
75
GLIP: Image Processing with OpenGL
Objectif de GLIP Utilisation du processeur graphique pour le traitement numérique des images. Nécessité d’adapter les algorithmes classiques du traitement des images aux contraintes de la programmation GPU. Un processeur graphique manipule des données géométriques uniquement (triangles, lignes, points). Gestion des images ? Un processeur graphique génère des résultats sous la forme d’une image 2D (rendu de la géométrie 3D selon un point de vue donné). Calcul d’histogramme, calcul de moments ? IUT de Reims [ ]
76
Principe général du TI sur GPU (1)
(0,0) (w,h) Texture (Image en entrée) Forme géométrique (Quad) (0,0) (w,h) GPU // // Threshold operator ... Color = texRECT(image, Position); float l = min(min(Color.r,Color.g), Color.b); if (l>=threshold) OUT.Color = float4(1,1,1,1); else OUT.Color = float4(0,0,0,1); Résultat du rendu (Image en sortie) Fragment shader (Traitement) [2] «GPU Image Processing» par Frank Jargstorff (NVIDIA Corporation) présenté à SIGGRAPH 2004. IUT de Reims [ ]
77
Principe général du TI sur GPU (2)
Passe 1 Flou Passe 2 Seuillage [2] «GPU Image Processing» par Frank Jargstorff (NVIDIA Corporation) présenté à SIGGRAPH 2004. IUT de Reims [ ]
78
Principe général du TI sur GPU (3)
Etapes clés Dessin de rectangles Utilisation du texture mapping (images de taille quelconque via l’extension GL_ARB_texture_rectangle) Compilation, chargement et exécution de shaders Conversion du résultat du rendu en texture Le but de la bibliothèque GLIP est de libérer le programmeur de ces étapes ‘bas niveau’ en les encapsulant dans des classes C++. IUT de Reims [ ]
79
Architecture logicielle de GLIP
Image + width() + height() + download() + upload() + getHue() + setHue() ColorizeFilter + process() UnaryFilter ThresholdFilter + getThreshold() + setThreshold() MeanFilter + getHalfSize() + setHalfSize() SeparableUnaryFilter + process() SeparableMeanFilter + getHalfSize() + setHalfSize() + process() BinaryFilter AddFilter SubFilter IUT de Reims [ ]
80
Analogie avec le modèle flot/noyau (stream/kernel)
Modèle flot/noyau : un même traitement (noyau) appliqué à chaque élément du flot d’entrée (image source) pour générer un flot de sortie de même taille (image destination). Approche adaptée aux traitements locaux : Un pixel : seuillage, changement d’espace couleur (RGB, HSV, …) Un voisinage de pixel : Convolution (flou gaussien, gradient, …) Morphologie mathématique (érosion, dilatation, ouverture, fermeture, …) Limitation d’une approche basée flot/noyau : Calcul d’histogramme, de moments Filtres récursifs IUT de Reims [ ]
81
Gestion de la mémoire vidéo (1)
Comment convertir l’image de sortie du calcul précédent en image d’entrée pour le calcul suivant ? Passe 1 ? Flou Passe 2 Seuillage IUT de Reims [ ]
82
Gestion de la mémoire vidéo (2)
Il existe actuellement 3 stratégies différentes [4] : Copie du Frame Buffer vers une texture à l’aide de la fonction glCopyTexSubImage2D. Solution multi plateforme mais lente. Utilisation des Pixel Buffers avec les extensions WGL_ARB_pbuffer et WGL_ARB_render_texture. Solution plus rapide mais plus coûteuse en mémoire (contextes de rendu multiples) et disponible uniquement sous Windows. Utilisation des Frame Buffer Object avec l’extension GL_EXT_framebuffer_object. Solution optimale mais encore expérimentale : disponible uniquement sur les pilotes bêta pour Windows de NVIDIA (76.50) [4] «The OpenGL Frame Buffer Object Extension» par Simon Green (NVIDIA Corporation) présenté à Game Developer Conference 2005 IUT de Reims [ ]
83
Principe des Frame Buffer Object
Pouvoir créer un nouveau Frame Buffer (Color Buffers, Depth Buffer et Stencil Buffer) en y attachant des images : Des textures pour chaque Color Buffer. Des Render Buffer pour les Depth Buffer et Stencil Buffer. Texture 0 Frame Buffer Object Texture 1 Color Attachment 0 Color Attachment 1 Render Buffer 0 … Render Buffer 1 Color Attachment n Stencil Attachment Depth Attachment IUT de Reims [ ]
84
Comparatif « Copie vers une texture » vs. FBO
Dimensions glCopyTexSubImage2D FPS* Frame Buffer Object FPS Ratio 256x256 (1 Mo) 14 1720 122.8 800x600 (7,5 Mo) 2 260 130.8 * FPS : Frames per second Configuration Processeur AMD Athlon 64 bits 1 Go de RAM GeForce 6600 GT sur port PCI Express 16x IUT de Reims [ ]
85
Utilisation de filtres séparables
Exemple de l’érosion : calcul du minimum des luminances dans un voisinage carré de taille 3. Version non séparable : 8 5 3 8 5 3 3x3 9 6 2 9 1 2 4 8 1 4 8 1 Version séparable : 8 5 3 8 3 3 8 5 3 3 3 9 6 2 9 2 2 9 1 2 4 8 1 4 1 1 4 8 1 IUT de Reims [ ]
86
Utilisation de filtres séparables
Image couleur 256256 Taille du noyau n Version non sép. FPS [ n 2 ] Version séparable FPS [ 2n ] Ratio 3 305 [9] 422 [6] 1.38 7 70 [49] 225 [14] 3.21 15 16 [225] 117 [30] 7.31 29 4 [841] 63 [58] 15.75 73 Ø [5329] 26 [146] 255 Ø [65025] 8 [510] IUT de Reims [ ]
87
Utilisation de filtres séparables
Image couleur 800600 Taille du noyau n Version non sép. FPS [ n 2 ] Version séparable FPS [ 2n ] Ratio 3 41 [9] 60 [6] 1.46 7 9 [49] 30 [14] 3.33 15 2 [225] 15 [30] 29 0 [841] 8 [58] 16 73 Ø [5329] 3 [146] 255 Ø [65025] 1 [510] IUT de Reims [ ]
88
Calcul d’histogramme sur CPU
Principe : calcul de la table de fréquences des luminances (256 niveaux de gris) dans une image. image : adresse de début de l’image size : nombre de pixels de l’image h : histogramme (tableau de 256 cases) unsigned long h[256]; unsigned char* ptr = image; for (int n=size; n--;) H[*(ptr++)]++; IUT de Reims [ ]
89
Calcul d’histogramme sur GPU (1)
Accès en écriture « aléatoire » for (int n=size; n--;) H[*(ptr++)]++; Dans un fragment shader, l’emplacement d’écriture est imposé par le pipeline. Il faut donc intervenir plus tôt dans le pipeline, au niveau du vertex shader Par conséquent, transformation de l’image en modèle géométrique (tableau de sommets) IUT de Reims [ ]
90
Calcul d’histogramme sur GPU (2)
Structure mémoire de l’image … 45 127 1 octet Structure mémoire du tableau de sommets … 45 127 4 octets IUT de Reims [ ]
91
Calcul d’histogramme sur GPU (3)
Modifier le mode de mélange de couleurs (addition de couleurs) Pour chaque sommet du tableau (pixel de l’image) déplacer le sommet sur l’horizontale en fonction de sa coordonnée en x (luminance) et lui attribuer une couleur égale à (1,0,0,0). Grâce au mode de mélange additif, le résultat du rendu correspond à une ligne de largeur 256 dont chaque pixel contient la fréquence correspondante. IUT de Reims [ ]
92
Calcul d’histogramme sur GPU (4)
Mode de mélange est limité a une précision de 16 bits en virgule flottante dont 9 bits pour la mantisse. plus grande valeur entière est de 2048. Pour pallier au manque de précision, décomposer la structure géométrique en paquets de 2048 sommets et faire plusieurs histogrammes intermédiaires sur plusieurs lignes. Nécessité d’une deuxième passe pour faire la somme sur chaque colonne. (fragment shader en précision 32 bits dont 23 bits pour la mantisse. Valeur maximale > ). IUT de Reims [ ]
Présentations similaires
© 2024 SlidePlayer.fr Inc.
All rights reserved.