DGL
https://delphigl.com/forum/

Texturübergabe an Shader
https://delphigl.com/forum/viewtopic.php?f=20&t=11217
Seite 1 von 1

Autor:  Robocolder [ Fr Aug 01, 2014 10:06 ]
Betreff des Beitrags:  Texturübergabe an Shader

Hallo :-),
Ich habe vor kurzem angefangen mich mit Shadern auseinander zu setzt und wolle in einem Testprogramm den BumpmapShader aus dem Wiki verwenden.
Leider habe ich keines Problem der Texturübergabe per glUniform1iARB, das gezeichnete Objekt erscheint immer schwarz unabhängig vom Licht.

Ich bin mir nicht sicher ob die Texturen im Shader ankommen oder ich sie falsch binde/übergebe, ich habe schon ein paar Einträge
im Forum zu diesem Thema gefunden, aber leider konnte mir keiner helfen. Hier meine Renderschleife:

Code:
  1.  
  2.   wglMakeCurrent(FDC, FRC);
  3.   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  4.  
  5.   glUseProgram(FShader);
  6.  
  7.   glActiveTexture(GL_TEXTURE0);
  8.   glEnable(GL_TEXTURE_2D);
  9.   FTextures[0].Bind;
  10.   glUniform1iARB(glGetUniformLocationARB(FShader, PGLCharARB('Tex0')), 0);
  11.  
  12.   glActiveTexture(GL_TEXTURE1);
  13.   glEnable(GL_TEXTURE_2D);
  14.   FTextures[1].Bind;
  15.   glUniform1iARB(glGetUniformLocationARB(FShader, PGLCharARB('Tex1')), 1);
  16.  
  17.   glMatrixMode(GL_PROJECTION);
  18.   glLoadIdentity;
  19.   gluPerspective(45.0, ClientWidth/ClientHeight, NearClipping, FarClipping);
  20.  
  21.   glMatrixMode(GL_MODELVIEW);
  22.   glLoadIdentity;
  23.  
  24.   glEnable(GL_LIGHTING);
  25.   SetupLight(0);
  26.  
  27.   glTranslatef(0,0,-FScale);
  28.  
  29.   glPushMatrix;
  30.     glRotatef(FRotPos.Y,1,0,0);
  31.     glRotatef(FRotPos.X,0,1,0);
  32.     SetupLight(1);
  33.   glPopMatrix;
  34.  
  35.   glPushMatrix;
  36.     glTranslatef(0, 0, 0);
  37.     glRotatef(EarthAngle, 0.4, 0.8, 0.6);
  38.     DrawObject(10,10,10);
  39.   glPopMatrix;
  40.  
  41.   glDisable(GL_LIGHTING);
  42.   glDisable(GL_LIGHT0);
  43.   glDisable(GL_LIGHT1);
  44.  
  45.   glUseProgram(0);
  46.  
  47.   SwapBuffers(FDC);
  48.  


Beim kompelieren oder linken der Shader treten keine Fehler auf. Ich hoffe Ihr könnt mir bei dem Problem helfen.
Ich bedanke mich schonmal im Voraus! :-)

Autor:  Sascha Willems [ Fr Aug 01, 2014 16:29 ]
Betreff des Beitrags:  Re: Texturübergabe an Shader

Was liefern die glGetUniformLocationARB? Da muss ein sinniger Wert drinstehen (> -1) der dann dem Bindingpoint im Shader entspricht.

Ansonsten bräuchte man den Shader um zu sehen wo es hapert.

P.S. : Das ARB am Ende kann man weglassen, sind alle längt im Kern.

Autor:  damadmax [ Fr Aug 01, 2014 18:06 ]
Betreff des Beitrags:  Re: Texturübergabe an Shader

Robocolder hat geschrieben:
das gezeichnete Objekt erscheint immer schwarz unabhängig vom Licht.


Und ohne Licht?

Autor:  mathias [ Sa Aug 02, 2014 16:33 ]
Betreff des Beitrags:  Re: Texturübergabe an Shader

Zitat:
und wolle in einem Testprogramm den BumpmapShader aus dem Wiki verwenden.

Im Wiki steht Texture0 und du hast Tex0.

Am besten du postest den Shader, warscheinlich hat es dort eine Fehler.

Autor:  glAwesome [ Sa Aug 02, 2014 17:14 ]
Betreff des Beitrags:  Re: Texturübergabe an Shader

Sascha Willems hat geschrieben:
Das ARB am Ende kann man weglassen, sind alle längt im Kern.
Aber wenn man es weglässt, sollte man es überall tun. Daraus können sonst "unerklärliche" Fehler entstehen. Im oben geposteten Quelltext wurde es z.B. bei glUseProgram weggelassen, bei glUniform jedoch nicht.

Autor:  mathias [ Sa Aug 02, 2014 19:04 ]
Betreff des Beitrags:  Re: Texturübergabe an Shader

Diese Zeile kann man auch einfacher schreiben.
Code:
  1.  glUniform1iARB(glGetUniformLocationARB(FShader, PGLCharARB('Tex1'));
  2. // ersetzten durch
  3.  glUniform1i(glGetUniformLocationARB(FShader, 'Tex1');

Autor:  OpenglerF [ Sa Aug 02, 2014 23:03 ]
Betreff des Beitrags:  Re: Texturübergabe an Shader

Man sollte sogar ARB nicht mehr verwenden, die Erweiterungen sind schließlich ziemlich alt.

Autor:  TAK2004 [ Mo Aug 04, 2014 05:56 ]
Betreff des Beitrags:  Re: Texturübergabe an Shader

Man kann sich sehr sicher sein, dass die ARB Funktionen auf OpenGL Client Treiber Seite eine eigenen Funkion sind aber auf Server Seite die geiche Routine ansprechen und damit auch kompatibel sind. AMD und NVidia sind da sehr hinterher unnötigen Code raus zu bekommen.

Allerdings sollte man die ARB nicht mit Core mischen, weil man ja bereits davon aus geht, dass diese im Kern verfügbar sind und ein anderer Programmierer dann Rätselt ob es nun erwartet werden darf oder ob Fallback Lösungen verfügbar sein müssen.

Ich kann noch eine Empfehlung für NSight, CodeXL und GPU-Perfstudio geben.
Mit den Tools kann man sehr genau sehen, was der eigene OpenGL Code eigentlich tut.

Autor:  Robocolder [ Mo Aug 04, 2014 07:46 ]
Betreff des Beitrags:  Re: Texturübergabe an Shader

Hier ist der Vertexshader:
Code:
  1.  
  2. const int LIGHT_COUNT = 3;
  3. varying vec3 N;
  4. varying vec3 V;
  5. varying vec3 lightvec[8];
  6. void main(void)
  7. {
  8.     gl_TexCoord[0]  = gl_MultiTexCoord0;
  9.     N               = normalize(gl_NormalMatrix * gl_Normal);
  10.     V               = vec3(gl_ModelViewMatrix * gl_Vertex);
  11.     for(int i = 0; i < LIGHT_COUNT; i++){
  12.         lightvec[i] = normalize(gl_LightSource[i].position.xyz - V);
  13.     }
  14.     gl_Position     = gl_ModelViewProjectionMatrix * gl_Vertex;
  15. }


Und hier der Fragmentshader:
Code:
  1.  
  2. const int LIGHT_COUNT = 1;
  3. const float PI = 3.14159265;
  4. varying vec3 N;
  5. varying vec3 V;
  6. varying vec3 lightvec[LIGHT_COUNT];
  7. uniform sampler2D Tex0;
  8. uniform sampler2D Tex1;
  9.  
  10. void main(void){
  11.     vec2 TexCoord = vec2(gl_TexCoord[0]);
  12.     vec3 Eye = normalize(-V);
  13.  
  14.     vec3 q0 = dFdx(Eye.xyz);
  15.     vec3 q1 = dFdy(Eye.xyz);
  16.     vec2 st0 = dFdx(TexCoord.st);
  17.     vec2 st1 = dFdy(TexCoord.st);
  18.    
  19.     vec3 S = normalize( q0 * st1.t - q1 * st0.t);
  20.     vec3 T = normalize(-q0 * st1.s + q1 * st0.s);
  21.    
  22.     mat3 M = mat3(-T, -S, N);
  23.     vec3 normal = normalize(M * (vec3(texture2D(Tex1, TexCoord)) - vec3(0.5, 0.5, 0.5)));
  24.    
  25.     vec4 EndColor = vec4(0.0, 0.0, 0.0, 0.0);
  26.     vec4 EndSpec  = vec4(0.0, 0.0, 0.0, 0.0);
  27.     for(int i = 0; i < LIGHT_COUNT; i++){
  28.         vec3 Reflected = normalize(reflect(-lightvec[i], normal));
  29.         vec4 IAmbient  = gl_LightSource[i].ambient  * gl_FrontMaterial.ambient;
  30.         vec4 IDiffuse  = gl_LightSource[i].diffuse  * gl_FrontMaterial.diffuse  * max(dot(normal, lightvec[i]), 0.0);
  31.         vec4 ISpecular = gl_LightSource[i].specular * gl_FrontMaterial.specular * pow(max(dot(Reflected, Eye), 0.0), gl_FrontMaterial.shininess);
  32.         EndColor += (IAmbient+IDiffuse);
  33.         EndSpec  += ISpecular;
  34.     }
  35.     EndColor += gl_FrontMaterial.emission;
  36.  
  37.     gl_FragColor = (gl_FrontLightModelProduct.sceneColor + EndColor + EndSpec) * texture2D(Tex0, TexCoord);
  38. }


Zitat:
Was liefern die glGetUniformLocationARB? Da muss ein sinniger Wert drinstehen (> -1) der dann dem Bindingpoint im Shader entspricht.

glGetUniformLocationARB sowie glGetUniformLocation geben bei "tex0" einen "0" und bei "tex1" eine "1" zurück.

Zitat:
Und ohne Licht?

Auch ohne Licht erscheint das gezeichnete Objekt in schwarz.

Autor:  Robocolder [ Mo Aug 04, 2014 07:53 ]
Betreff des Beitrags:  Re: Texturübergabe an Shader

Hier noch ein Screenshot der Szene :-)

Bild

Autor:  damadmax [ Mo Aug 04, 2014 08:22 ]
Betreff des Beitrags:  Re: Texturübergabe an Shader

Du hast kein Material gesetzt. Im Shader werden aber glFrontMaterial etc verwendet. Ich sehe aber im Programmquellcode keinerlei glMaterial Aufrufe.

Außerdem bin ich mir nicht sicher ob
Zitat:
varying vec3 lightvec[LIGHT_COUNT];

im Fragmentshader (LIGHT_COUNT=1) die gleiche Größe wie im Vertexshader (LIGHT_COUNT=3) haben sollte.

Autor:  Robocolder [ Mo Aug 04, 2014 08:36 ]
Betreff des Beitrags:  Re: Texturübergabe an Shader

Hab meinen Fehler gefunden :roll:
Ich habe den alten Shader von Bergmann89 aus diesem Beitrag benutzt. :(

Jedoch sind mit dem original Shader aus dem Wiki ein weiters Problem aufgetaucht. Die Textur wird immer in Blau ausgezeigt.
Hier ein paar Screenshots:

Bild

Base Textur:

Bild

Bumpmap Textur:

Bild

Danke schon mal für eure schnelle Hilfe :-).

Autor:  Lord Horazont [ Mo Aug 04, 2014 18:18 ]
Betreff des Beitrags:  Re: Texturübergabe an Shader

Könntest du den verwendeten Shadercode nochmal posten (oder ist das der gleiche wie oben)?

viele Grüße,
Horazont

Autor:  Robocolder [ Di Aug 05, 2014 11:41 ]
Betreff des Beitrags:  Re: Texturübergabe an Shader

Hier sind noch mal meine Shader, sind die auf dem Wiki. :-)

Fragmentshader:
Code:
  1.  
  2. const int LIGHT_COUNT = 1;
  3. const float PI = 3.14159265;
  4. varying vec3 N;
  5. varying vec3 V;
  6. varying vec3 lightvec[LIGHT_COUNT];
  7. uniform sampler2D Tex0;
  8. uniform sampler2D Tex1;
  9.  
  10. void main(void){
  11.     vec2 TexCoord = vec2(gl_TexCoord[0]);
  12.     vec3 Eye = normalize(-V);
  13.  
  14.     vec3 q0 = dFdx(Eye.xyz);
  15.     vec3 q1 = dFdy(Eye.xyz);
  16.     vec2 st0 = dFdx(TexCoord.st);
  17.     vec2 st1 = dFdy(TexCoord.st);
  18.  
  19.     vec3 S = normalize( q0 * st1.t - q1 * st0.t);
  20.     vec3 T = normalize(-q0 * st1.s + q1 * st0.s);
  21.  
  22.     mat3 M = mat3(-T, -S, N);
  23.     vec3 normal = normalize(M * (vec3(texture2D(Texture1, TexCoord)) - vec3(0.5, 0.5, 0.5)));
  24.  
  25.     vec4 EndColor = vec4(0.0, 0.0, 0.0, 0.0);
  26.     vec4 EndSpec  = vec4(0.0, 0.0, 0.0, 0.0);
  27.     for(int i = 0; i < LIGHT_COUNT; i++){
  28.         vec3 Reflected = normalize(reflect(-lightvec[i], normal));
  29.         vec4 IAmbient  = gl_LightSource[i].ambient  * gl_FrontMaterial.ambient;
  30.         vec4 IDiffuse  = gl_LightSource[i].diffuse  * gl_FrontMaterial.diffuse  * max(dot(normal, lightvec[i]), 0.0);
  31.         vec4 ISpecular = gl_LightSource[i].specular * gl_FrontMaterial.specular * pow(max(dot(Reflected, Eye), 0.0), gl_FrontMaterial.shininess);
  32.         EndColor += (IAmbient+IDiffuse);
  33.         EndSpec  += ISpecular;
  34.     }
  35.     EndColor += gl_FrontMaterial.emission;
  36.  
  37.     gl_FragColor = (gl_FrontLightModelProduct.sceneColor + EndColor + EndSpec) * texture2D(Texture0, TexCoord);
  38. }
  39.  


VertexShader:
Code:
  1.  
  2. const int LIGHT_COUNT = 1;          //Anzahl der berücksichtigten Lichter
  3. varying vec3 N;             //NormalenVektor
  4. varying vec3 V;             //VertexVektor 
  5. varying vec3 lightvec[LIGHT_COUNT]; //LichtVektor(en)
  6. void main(void)
  7. {
  8.     gl_TexCoord[0]  = gl_MultiTexCoord0;
  9.     N           = normalize(gl_NormalMatrix * gl_Normal);
  10.     V       = vec3(gl_ModelViewMatrix * gl_Vertex);
  11.     for(int i = 0; i < LIGHT_COUNT; i++){
  12.         lightvec[i] = normalize(gl_LightSource[i].position.xyz - V);
  13.     }
  14.     gl_Position     = gl_ModelViewProjectionMatrix * gl_Vertex;
  15. }
  16.  

Autor:  Lord Horazont [ Di Aug 05, 2014 17:39 ]
Betreff des Beitrags:  Re: Texturübergabe an Shader

Ich würde mal schrittweise testen, Teile des Codes zu deaktivieren (und die berechneten Farben mit weiß zu ersetzen). Z.B. den Beleuchtungskram mal kurz rauszupacken, um festzustellen, ob einfach irgendein Licht unfug macht.

grüße,
Horazont

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