DGL
https://delphigl.com/forum/

sampler2D Arrays
https://delphigl.com/forum/viewtopic.php?f=20&t=11280
Seite 1 von 2

Autor:  mathias [ Mo Nov 03, 2014 20:18 ]
Betreff des Beitrags:  sampler2D Arrays

Ich habe folgenden Code, welcher auch funktioniert:
Code:
  1. glUniform1i(UniformLocation('myTextureSampler[0]'), 0);
  2. glUniform1i(UniformLocation('myTextureSampler[1]'), 1);
  3. glUniform1i(UniformLocation('myTextureSampler[2]'), 2);
  4. glUniform1i(UniformLocation('myTextureSampler[3]'), 3); 

Code:
  1. uniform sampler2D myTextureSampler[4];


Da der Wert 0-4 immer gleich ist, dachte ich, ich könnte im Shader direkt zuweisen.
Code:
  1. uniform sampler2D myTextureSampler[4] = {0, 1, 2, 3};

Nur motzt der Shader-Compiler.
Code:
  1. ERROR: 0:13: 'sampler2D' : cannot construct this type
  2. ERROR: 0:13: '=' :  cannot convert from 'const 4-element array of float' to 'uniform 4-element array of sampler2D'


Ich habe auch versucht 0, 1.... durch 0.0, 1.0 zu ersetzen.

Code:
  1. uniform int test[4] = {0, 1, 2, 3};

Dies frisst der Compiler.

Ist samper2D etwas besonders ?

Autor:  Sascha Willems [ Di Nov 04, 2014 07:50 ]
Betreff des Beitrags:  Re: Textur Nummern;

Welche GLSL-Version setzt du im Shader voraus. Sampler Arrays gehen afaik ab GLSL 1.3 (mit Einschränkungen, man kann z.B. nicht im Code über das Array iterieren) und ab 4.00 kann man die dann wie jedes Array verwenden.

Autor:  mathias [ Di Nov 04, 2014 18:07 ]
Betreff des Beitrags:  Re: Textur Nummern;

Zitat:
Welche GLSL-Version setzt du im Shader voraus ?

Ich habe es von 1.3 bis 4.0 probiert.

Aber bei dieser Zeile scheitern alle.
Code:
  1. uniform sampler2D myTextureSampler[4] = {0, 1, 2, 3};


Eine Array wird erkannt, sonst würde diese Zeile auch nicht gehen.
Code:
  1. uniform sampler2D myTextureSampler[8];


Aber wenigsten konnte ich diese Zeilen vereinfachen.
Code:
  1. glUniform1i(UniformLocation('myTextureSampler[0]'), 0);
  2. glUniform1i(UniformLocation('myTextureSampler[1]'), 1);
  3. glUniform1i(UniformLocation('myTextureSampler[2]'), 2);
  4. glUniform1i(UniformLocation('myTextureSampler[3]'), 3);


So geht einfacher.
Code:
  1. const
  2.   ia: array[0..7] of integer = (0, 1, 2, 3, 4, 5, 6, 7);      
  3. ...
  4. glUniform1iv(UniformLocation('myTextureSampler'), 8, ia);  

Autor:  damadmax [ Do Nov 06, 2014 06:54 ]
Betreff des Beitrags:  Re: Textur Nummern;

Zitat:
Da der Wert 0-4 immer gleich ist, dachte ich, ich könnte im Shader direkt zuweisen.


Afaik hat ein sampler2d aber nichts mit GL_TEXTUREx zu tun. Deshalb verstehe ich den ganzen Thread nicht.

Die Fehlermeldung sagt eigentlich alles:
Code:
  1. ERROR: 0:13: 'sampler2D' : cannot construct this type

Autor:  glAwesome [ Do Nov 06, 2014 12:21 ]
Betreff des Beitrags:  Re: Textur Nummern;

mathias hat geschrieben:
Code:
  1. uniform int test[4] = {0, 1, 2, 3};

Dies frisst der Compiler.

Das muss er aber nicht. Ich hatte gerade einen Compilerfehler bei einem ähnlichen Code:
Code:
  1. const vec2 offsets[9] = {vec2(0.0),
  2.                         vec2( 0.290, 1.000), vec2(-0.806, 0.000), vec2( 1.000,-0.484), vec2( 0.000, 0.935),
  3.                         vec2(-0.484, 0.484), vec2( 0.097,-0.742), vec2(-0.419,-0.226), vec2( 0.613, 0.290)};

Intel hat's geschluckt, Nvidia nicht. Fehlermeldung:
Zitat:
error C7549: OpenGL does not allow C style initializers

Eine korrekte Array-Initialisierung sieht in GLSL so aus:
Code:
  1. const vec2 offsets[9] = vec2[](vec2(0.0),  // zwischen die eckigen Klammern kann man optional auch nochmal die 9 schreiben
  2.                                vec2( 0.290, 1.000), vec2(-0.806, 0.000), vec2( 1.000,-0.484), vec2( 0.000, 0.935),
  3.                                vec2(-0.484, 0.484), vec2( 0.097,-0.742), vec2(-0.419,-0.226), vec2( 0.613, 0.290));

Wenn ich mich richtig erinnere, hattest du neulich auch so ein Array-Problem hier im Forum gepostet, jedoch finde ich das gerade nicht wieder. Vielleicht erklärt das was.

Autor:  mathias [ Do Nov 06, 2014 18:27 ]
Betreff des Beitrags:  Re: Textur Nummern;

Zitat:
Eine korrekte Array-Initialisierung sieht in GLSL so aus:


Ich habe folgendes probiert, uniform geht, const nicht.
Code:
  1. uniform int test1[4] = int[4](0, 1, 2, 3); // geht
  2. const int test2[4] = int[4](0, 1, 2, 3); // fehler
  3.  
  4. uniform sampler2D myTextureSampler[8] = sampler2D[8](0, 1, 2, 3, 4 ,5 ,6 ,7);  // dies geht immer noch nicht


Link steht es mir der Array-Daklaration, unterster Code.

Zitat:
Afaik hat ein sampler2d aber nichts mit GL_TEXTUREx zu tun. Deshalb verstehe ich den ganzen Thread nicht.

Wieso nicht ?

Autor:  glAwesome [ Do Nov 06, 2014 19:46 ]
Betreff des Beitrags:  Re: Textur Nummern;

mathias hat geschrieben:
Code:
  1. const int test2[4] = int[4](0, 1, 2, 3); // fehler
Welcher Fehler kommt denn? Ich habe es gerade bei mir ausprobiert, keiner der beiden Shader-Compiler hat was zu meckern und meiner Meinung nach ist es exakt so, wie in der GLSL-Spezifikation.

mathias hat geschrieben:
Code:
  1. uniform sampler2D myTextureSampler[8] = sampler2D[8](0, 1, 2, 3, 4 ,5 ,6 ,7);  // dies geht immer noch nicht
Das wirst du mit derzeitigen GLSL-Versionen wohl auch nicht hinbekommen.

Autor:  mathias [ Do Nov 06, 2014 20:11 ]
Betreff des Beitrags:  Re: Textur Nummern;

Zitat:
Welcher Fehler kommt denn?


Code:
  1. ERROR: 0:14: 'const 4-element array of int' : cannot declare arrays of this qualifier
  2. ERROR: 0:14: 'const' :  non-matching types (using implicit conversion) for const initializer  


Ich habe gerade festgestellt, das es an der Shader-Version liegt.
Mit 3.3 gehts, mit 1.3 nicht.

Autor:  damadmax [ Do Nov 06, 2014 22:56 ]
Betreff des Beitrags:  Re: Textur Nummern;

Ich zitiere mal das DGL Wiki:

Zitat:
[...]Dies ist also unbedingt zu machen, sobald ein Texturensampler eine Textureinheit > GL_TEXTURE_0 adressieren will. Die Textureneinheit des Samplers lässt sich also nicht im Shader selbst festlegen.
Link

Autor:  mathias [ Do Nov 06, 2014 23:13 ]
Betreff des Beitrags:  Re: Textur Nummern;

Wenigstens, kann man die Texturensampler in eine Array packen.

Code:
  1. uniform sampler2D myTextureSampler[8];


Pascal Code:
Code:
  1. const
  2.   ia: array[0..7] of integer = (0, 1, 2, 3, 4, 5, 6, 7);
  3. begin
  4.   ...
  5.   glUniform1iv(glGetUniformLocation(Program_ID, 'myTextureSampler'), 8, ia);
  6.   ...

Autor:  mathias [ Fr Nov 21, 2014 21:53 ]
Betreff des Beitrags:  Re: Textur Nummern;

Auf meinem Intel funktioniert folgender Shader ohne Probleme, aber auf einem Nvidia Ion (Intel Atom CPU) kommt ein Fehler wie im Anhang.

Irgendwie kommt er mit der Sampler Array nicht zu recht.
Bei diesem Code könnte ich auf die Array verzichten, aber ich habe ein Programm welches die Array braucht.

Code:
  1. #version 330
  2.  
  3. in vec2 vUV0;
  4.  
  5. uniform sampler2D myTextureSampler[8];
  6.  
  7. out vec4 FragColor;
  8.  
  9. void main()
  10. {
  11.   FragColor = texture( myTextureSampler[0], vUV0 );
  12. }  


Folgende Info liefert die Versionsabfrage.
Code:
  1. GL_VENDOR: NVIDIA Corporation
  2. GL_RENDERER: ION/integrated/SSE2
  3. GL_VERSION: 3.3.0
  4. GL_SHADING_LANGUAGE_VERSION: 3.30 NVIDIA via Cg compiler


PS: Intel hat bei der Fehlerausgabe die Nase vorn, die Meldungen haben viel mehr Informationen.

Dateianhänge:
Unbenannt.png
Unbenannt.png [ 5.91 KiB | 23350-mal betrachtet ]

Autor:  mathias [ So Nov 23, 2014 17:15 ]
Betreff des Beitrags:  Re: Textur Nummern;

Gemäss Google müsste dies funktionieren, aber warum bleibt bei mir der Körper schwarz ?
Code:
  1. #version 330
  2.  
  3. in vec2 vUV0;
  4.  
  5. //uniform sampler2D myTextureSampler[8];
  6. uniform sampler2DArray myTextureSampler;
  7.  
  8. out vec4 FragColor;
  9.  
  10. void main()
  11. {
  12.   FragColor = texture( myTextureSampler, vec3(vUV0, 0));
  13. }    


Code:
  1. glUniform1i(glGetUniformLocation(Shader.Program_ID, 'myTextureSampler'), 0);

Autor:  mathias [ So Nov 23, 2014 20:30 ]
Betreff des Beitrags:  Re: Textur Nummern;

Ich bin unterdessen eine Schritt weiter gekommen, an dieser Zeile liegt es nicht uniform sampler2D myTextureSampler[8]

Der NVidia kann diese beiden Shader nicht zusammenlinken

Vertex:
Code:
  1. #version 330
  2.  
  3. layout (location = 0) in vec3 inPos;
  4. layout (location = 1) in vec3 inNormal;
  5.  
  6. layout (location = 10) in vec2 inVertexUV;
  7.  
  8. out vec3 Pos;
  9. out vec3 Normal;
  10.  
  11. out vec2 UV;
  12.  
  13. uniform mat4 WorldMatrix;
  14.  
  15. void main()
  16. {
  17.   gl_Position = WorldMatrix * vec4(inPos, 1.0);
  18.  
  19.   UV = inVertexUV;
  20.  
  21.   Pos = vec3(WorldMatrix * vec4(inPos, 1.0));
  22.   Normal = normalize(mat3(WorldMatrix) * inNormal);
  23. }


Fragment:
Code:
  1. #version 330
  2. in vec3 Pos;
  3. in vec3 Normal;
  4.  
  5. in vec2 UV;
  6.  
  7. out vec4 OutColor;
  8.  
  9. uniform sampler2D myTextureSampler[8];
  10.  
  11. uniform int anzTextures = 0;
  12.  
  13. $light.glsl
  14.  
  15. void main()
  16. {
  17.   {
  18.     vec4 col = vec4(0.0, 0.0, 0.0, 0.0);
  19.     for (int i = 1; i <= anzTextures; i++ )
  20.     {
  21.       col += texture2D( myTextureSampler[i - 1], UV );
  22.     }
  23.     OutColor = col / anzTextures;
  24.   }
  25.  
  26.   float cdummy = OutColor.a;
  27.  
  28.   OutColor = OutColor * (diffuse(LightPosition) + specular(LightPosition));
  29.  
  30.   OutColor.a = cdummy;
  31. }


Bei $light.glsl kommt noch folgendes, an dem kann es nicht liegen, sonst würde die restlichen Shader nicht funktionieren.
Code:
  1. uniform vec3 LightPosition = vec3(0.0, 0.0, 0.4);
  2.  
  3. float diffuse(vec3 LightPosition)
  4. {
  5.   return 0.0;
  6. }
  7.  
  8. float specular(vec3 LightPosition)
  9. {
  10.   return 1.0;
  11. }                    

Autor:  mathias [ So Nov 23, 2014 23:09 ]
Betreff des Beitrags:  Re: Textur Nummern;

Ich habe den Fehler gefunden.
Ich kann keine Variable Sampler[i] schreiben, er frisst nur eine Konstante Sampler[0]

Nun zur nächsten Frage, wie kann ich dies umgehen ?

Code:
  1. #version 330
  2.  
  3. in vec2 UV0;
  4.  
  5. uniform sampler2D Sampler[8];
  6.  
  7. uniform int anzTextures = 1;
  8.  
  9. out vec4 FragColor;
  10.  
  11. void main()
  12. {
  13.     vec4 col = vec4(0.0, 0.0, 0.0, 0.0);
  14.     for (int i = 0; i < anzTextures; i++ )
  15.     {
  16.       col += texture( Sampler[0], UV0 );  // geht
  17.       col += texture( Sampler[i], UV0 );   // geht nicht :(
  18.     }
  19.     FragColor = col / anzTextures;
  20. }

Autor:  glAwesome [ Mo Nov 24, 2014 11:06 ]
Betreff des Beitrags:  Re: Textur Nummern;

Mit #version 330 eigentlich gar nicht, wie weiter oben im Thread schon erwähnt wurde:
Sascha Willems hat geschrieben:
man kann z.B. nicht im Code über das Array iterieren

Auf dieses Problem bin ich auch schon gestoßen. In meinem Beleuchtungsshader sollte jede Lichtquelle einen Shadowsampler bekommen und über die Lichtquellen sollte natürlich mit einer for-Schleife iteriert werden. Als Pseudo-Workaround kompiliere ich den Shader für verschiedene Anzahlen von Lichtquellen und rolle dabei die for-Schleife aus. Also statt
Code:
  1. for(int i=0; i<2; ++i){
  2.   texture(texMap[i], coords);
  3. }
mache ich sowas:
Code:
  1. {
  2.   texture(texMap[0], coords);
  3. }
  4. {
  5.   texture(texMap[1], coords);
  6. }

Wobei der zweite Code selbstverständlich nicht handgetippt, sondern automatisiert erstellt wird. Das ist auch genau der Ansatz, der vom glsl PreCompiler unterstützt wird, wenn ich das richtig verstanden habe.

Seite 1 von 2 Alle Zeiten sind UTC + 1 Stunde
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/