2017-12-02 3 views
1

Ich habe versucht, Shader Speicher Buffer Objects (SSBO) mit opengl 4.3 Kern für einige Zeit zu verwenden, aber kann nicht einmal mein Shader-Programm erhalten LinkOpengl 4.3: Mit One SSBO Objekt in Vertex & Fragment Shader

Hier ist der Code für meine Vertex Shader

# version 430 core 

in vec3 vertex; 
uniform mat4 
perspectiveMatrix, 
viewMatrix, 
modelMatrix; 

in vec3 normal; 
out vec3 lightVectors[3]; 
out vec3 vertexNormal; 
out vec3 cameraVector; 

layout(std430,binding=1)buffer Lights 
{ 
    vec3 positions[3]; 
    vec3 attenuations[3]; 
    vec3 colors[3]; 
}buf1; 

void main() 
{ 
vec4 worldVertex=modelMatrix*vec4(vertex,1.0); 
gl_Position=perspectiveMatrix*viewMatrix*worldVertex; 

vertexNormal=(modelMatrix*vec4(normal,0)).xyz; 
for(int i=0;i<3;i++){ 
    lightVectors[i]=buf1.positions[i]-worldVertex.xyz; 
} 
cameraVector=(inverse(viewMatrix)*vec4(0,0,0,1)).xyz-worldVertex.xyz; 

} 

Und hier ist der Code für mein Fragment Shader

# version 430 core 

in vec3 vertexNormal; 
in vec3 cameraVector; 
in vec3 lightVectors[3]; 

out vec4 pixelColor; 

layout(std430,binding=1)buffer Lights 
{ 
    vec3 positions[3]; 
    vec3 attenuations[3]; 
    vec3 colors[3]; 
}buf2; 

uniform Material 
{ 
vec3 diffuseMat; 
vec3 specularMat; 
float reflectivity; 
float shininess; 
}; 

float getAtten(int i) 
{ 
float l=length(lightVectors[i]); 
float atten=(buf2.attenuations[i].x*l) 
+((buf2.attenuations[i].y)*(l*l)) 
+((buf2.attenuations[i].z)*(l*l*l)); 
return atten; 
} 

vec3 computeLightColor() 
{ 
vec3 unitNormal=normalize(vertexNormal); 
vec3 unitCam=normalize(cameraVector); 

vec3 diffuse,specular,lightColor; 
for(int i=0;i<3;i++) 
{ 
vec3 unitLight=normalize(lightVectors[i]); 
float atten=getAtten(i); 

float nDiffuseDot=dot(unitLight,unitNormal); 
float diffuseIntencity=max(0,nDiffuseDot); 
diffuse+=(buf2.colors[i]*diffuseMat*diffuseIntencity)/atten; 

vec3 reflectedLight=reflect(-unitLight,unitNormal); 
float nSpecularDot=dot(reflectedLight,unitCam); 
float specularIntencity=pow(max(0,nSpecularDot),reflectivity)*shininess; 
specular+=(buf2.colors[i]*specularMat*specularIntencity)/atten; 
} 
lightColor=diffuse+specular; 

return lightColor; 
} 

void main() 
{ 
pixelColor=vec4(computeLightColor(),1)*0.7; 
} 

der Kodex gemeinsam diese beiden Shaders ist

layout(std430,binding=1)buffer Lights 
{ 
    vec3 positions[3]; 
    vec3 attenuations[3]; 
    vec3 colors[3]; 
}; 

Dies ist ein SSBO ich für meine Beleuchtung Berechnungen bin mit

ich diesen einen einzigen Puffer in beiden Vertex & Fragment Shader verwenden müssen, weil in meinem Vertex Shader Dieser Teil des Codes

lightVectors[i]=buf1.positions[i]-worldVertex.xyz; 

verwendet das Licht Positionen im SSBO definiert

Und im Fragment Shader der

float getAtten(i) and 
vec3 computeLight() 

Methode verwendet die Puffer Farben [3] und Dämpfungen [3] "Arrays" diffuse und spiegelnde Komponenten

berechnen Aber ich kann die Vertex & Bruchstück Shader unter Verwendung der oben SSBO Definition And The Shader Info-Link Log ist leer So kenne ich den Fehler entweder

Gibt es eine Möglichkeit, die oben definierte SSBO in der Vertex und Frage Shader ohne Erstellen von 2 separate SSBO dh eine für Vertex Shader und eine für Frage Shader?

Dies ist meine Shader-Klasse. All My Shaders Verlängert zu dieser Klasse für die Implementierung

public abstract class StaticShader extends Shader3D 
{ 
private int  
vertexShaderID=-1, 
fragmentShaderID=-1; 

private boolean alive=false; 
private boolean isActive=false; 

public StaticShader(Object vertexShader,Object fragmentShader) 
{ 
    programID=GL20.glCreateProgram(); 
    vertexShaderID=loadShader(vertexShader,GL20.GL_VERTEX_SHADER); 
    fragmentShaderID=loadShader(fragmentShader,GL20.GL_FRAGMENT_SHADER); 

    GL20.glAttachShader(programID,vertexShaderID); 
    GL20.glAttachShader(programID,fragmentShaderID); 
    bindAttributes(); 

    activateShader(); 
    } 

private int loadShader(Object src,int shaderType) 
{ 
    StringBuilder source=super.loadSource(src); 

    int shaderID=GL20.glCreateShader(shaderType); 
    GL20.glShaderSource(shaderID,source); 
    GL20.glCompileShader(shaderID); 

    if(GL20.glGetShaderi(shaderID,GL20.GL_COMPILE_STATUS)==GL11.GL_FALSE) 
    { 
     infoLogSize=GL20.glGetShaderi(shaderID,GL20.GL_INFO_LOG_LENGTH); 
     System.err.println(GL20.glGetShaderInfoLog(shaderID,infoLogSize)); 
     System.err.println("COULD NOT COMPILE SHADER"); 
     System.exit(-1); 
    }  

    return shaderID; 
} 

protected void activateShader() 
{ 
    GL20.glLinkProgram(programID); 
    if(GL20.glGetProgrami(programID,GL20.GL_LINK_STATUS)==GL11.GL_FALSE) 
    { 
    infoLogSize=GL20.glGetProgrami(programID,GL20.GL_INFO_LOG_LENGTH); 
    System.err.println(GL20.glGetProgramInfoLog(programID,infoLogSize)); 
    System.err.println("COULD NOT LINK SHADER"); 
    System.exit(-1); 
    } 

    GL20.glValidateProgram(programID); 
    if(GL20.glGetProgrami(programID,GL20.GL_VALIDATE_STATUS)==GL11.GL_FALSE) 
    { 
    infoLogSize=GL20.glGetProgrami(programID,GL20.GL_INFO_LOG_LENGTH); 
    System.err.println(GL20.glGetProgramInfoLog(programID,infoLogSize)); 
    System.err.println("COULD NOT VALIDATE SHADER"); 
    System.exit(-1); 
    } 
} 

public void dispose() 
{ 
    GL20.glUseProgram(0); 

    GL20.glDetachShader(programID,vertexShaderID); 
    GL20.glDetachShader(programID,fragmentShaderID); 

    GL20.glDeleteShader(vertexShaderID); 
    GL20.glDeleteShader(fragmentShaderID); 

    GL20.glDeleteProgram(programID); 
}   
} 

Ich verwende LWJGL 2.9.3 Jogl Version

Das Programm kompiliert gut, aber glLinkProgram() return false und der Shader info log ist leer

ich habe nicht einmal ein Puffer-Objekt jeglicher Art erstellt ich lerne gerade die Syntax zur Zeit

jede Hilfe wird sehr danken u im Voraus erkannt werden, und die, die mir in den commen geholfen haben ts, aber ich bin stark im Moment

+1

Ja, das ist möglich. Es ist sehr unwahrscheinlich, dass das Linker-Info-Protokoll leer ist, wenn die Verbindung fehlschlägt. Sie sollten also zunächst damit beginnen (oder den Code hier anzuzeigen). – BDL

+0

Der oben angegebene Shader-Code hat immer Compile/Linking Errors gedruckt und beendet die Anwendung, wenn es mir hoffentlich hilft –

Antwort

2

In youre Code erhalte ich die Linker-Fehler frustriert:

error: binding mismatch between shaders for SSBO (named Lights)

Sie müssen verwenden die gleiche Bindungsstelle für gleich benannte Puffer Objekte in den verschiedenen Shader-Stufen.

In Ihrem Vertex-Shader:

layout(std430, binding=1) buffer Lights 
{ 
    vec3 positions[3]; 
    vec3 attenuations[3]; 
    vec3 colors[3]; 
} buf1; 

Lights ist die äußerlich sichtbaren Namen des Puffers und buf1 ist der Name des Blocks innerhalb des Shader.

Dies bedeutet, dass Sie die gleiche Bindungsstelle für das Puffer-Objekt Lights im Fragment-Shader verwenden:

layout(std430,binding=1) buffer Lights // <---- binding=1 instead of binding=2 
{ 
    vec3 positions[3]; 
    vec3 attenuations[3]; 
    vec3 colors[3]; 
}buf2; 

Siehe auch:

The buffer qualifier is used to declare global variables whose values are stored in the data store of a buffer object bound through the OpenGL API.

// use buffer to create a buffer block (shader storage block) 
buffer BufferName { // externally visible name of buffer 
    int count; // typed, shared memory... 
    ... // ... 
    vec4 v[]; // last member may be an array that is not sized 
       // until after link time (dynamically sized) 
} Name; // name of block within the shader 
+2

Sie hatten Recht Es zeigte die Binding Mismatch-Fehler Ich habe es nicht richtig gesehen mein Bad.but jetzt, wenn ich laufe Das Programm Das Info-Protokoll ist für echte leer. Ich werde meine Frage aktualisieren Danke für den Tipp, aber immer noch nichts funktioniert –

+0

Ich habe auch kein Puffer-Objekt nur den Shader-Code verwendet. Es wurde kein Puffer erstellt und verwendet, da ich gerade die Syntax lerne. Das Programm stürzt bei der Verbindungsphase –

+0

Ich machte eine sehr interessante Beobachtung in My Shader Programs. Wenn ich die Puffer-Objekte in meinen Hauptmethoden nicht verwende, zB Scheitelpunkt- und Fragment-Shader (ohne den SSBO-Code oben zu ändern/zu entfernen) Das Programm verlinkt und funktioniert gut Aber so bald wie ich die Pufferobjekt-Verknüpfung nicht verwenden kann !! Irgendetwas verdächtiges passiert hier? Wie zuvor, bevor ich kein Pufferobjekt erstellt habe und nichts an den SSBO in My Shaders gebunden habe. Aber ich kann die Stücke nicht zusammenfügen. –

Verwandte Themen