Bonjour,
Je rencontre actuellement un problème assez facheux sur ma Radeon 9800 Pro lors de l'écriture d'un shader en GLSL. Je semble effectuer tout ce que les cartes PS2.0 détestent, à savoir : beaucoup de lookups sur des textures, une boucle for et un if :/. Hélas je vois pas comment régler ça. Voici le shader en question :
Pour le pos2, c'est parceque le gl_FragCoord est très très mal supporté sur toutes les cartes ATi... Egalement, le vertex shader n'effectue quasiment rien, aucun if, aucune boucle, pas de lookup sur des textures.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 varying float dist; varying vec4 posXY; uniform vec2 haltonPoints [20]; uniform sampler2DRect PosTextureLight; uniform sampler2DRect MatTextureLight; uniform sampler2DRect PosCamera; uniform sampler2DRect PosNormal; uniform sampler2DRect PosMaterials; void main() { vec2 pos2 = (posXY.xy) * 0.5 + 0.5; pos2.x *= 800.0; pos2.y *= 600.0; // TODO add specular vec4 final; vec4 indirect; vec4 indirectNeg; vec4 n = normalize(texture2DRect(PosNormal, pos2.xy)); vec4 position = vec4(texture2DRect (PosCamera, pos2.xy)); vec4 diffuse = texture2DRect(PosMaterials, pos2.xy); for (int i = 0 ; i != 20 ; ++i) { vec4 lightPosition = texture2DRect (PosTextureLight, haltonPoints[i].xy); vec4 lightDiffuse = texture2DRect (MatTextureLight, haltonPoints[i].xy); vec4 toLight = lightPosition - position; float dis = length(toLight); toLight = normalize(toLight); float att; float spotAtt; float nDotL= max(0.0, dot(n,toLight)); if (nDotL > 0.0) { att = 1.0 / (4.0 + 1.0 * dis + 0.25 * dis * dis); final += att * (diffuse * nDotL); } } gl_FragColor = final; }
En décommantant la ligne final += att... dans le if de la fin, pas de soucis, ça compile sans soucis en mode hardware. en décommentant cette ligne, misère, les shaders fonctionnent en mode software, et m'indique que le nombre d'instructions sur les textures a été dépassé, alors que bizarrement en décommentant le final += att... qui n'utilise aucune instruction sur des textures, ça fonctionne en mode hardware.
D'autre part, j'ai fait des tests et ça fonctionne en mode software à partir de i < 5,... or il me faudrait effectuer cette boucle au moins une centaine de fois... Alosr je ne sais pas comment faire. J'ai testé de "dérouler" la boucle à la main et ça fonctionne, mais alors vlà le bordel à gérer et la longueur du shader si je dois exécuter ce code 100 fois...
Quelqu'un a des techniques pour limiter ce phénomène ? Je ne vois pas comment je pourrais supprimer ces accès aux textures...
Partager