Opengl 4.3:在Vertex&;中使用一个SSBO对象;片段着色器
一段时间以来,我一直在尝试将着色器存储缓冲区对象(SSBO)与opengl 4.3内核结合使用,但我甚至无法让着色器程序链接 下面是我的顶点着色器的代码Opengl 4.3:在Vertex&;中使用一个SSBO对象;片段着色器,opengl,Opengl,一段时间以来,我一直在尝试将着色器存储缓冲区对象(SSBO)与opengl 4.3内核结合使用,但我甚至无法让着色器程序链接 下面是我的顶点着色器的代码 # version 430 core in vec3 vertex; uniform mat4 perspectiveMatrix, viewMatrix, modelMatrix; in vec3 normal; out vec3 lightVectors[3]; out vec3 vertexNormal; out vec3 camer
# 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;
}
这是我用于照明计算的SSBO
我需要在顶点和片段着色器中使用这一个缓冲区,因为在我的顶点着色器中,这是代码的一部分
lightVectors[i]=buf1.positions[i]-worldVertex.xyz;
使用SSBO中定义的灯光位置
在片段着色器中
float getAtten(i) and
vec3 computeLight()
方法使用缓冲区颜色[3]和衰减[3]“阵列”来计算漫反射和镜面反射分量
但是我无法使用上面的SSBO定义链接顶点和碎片着色器
而且着色器信息日志是空的,所以我也不知道错误
有没有一种方法可以在顶点和碎片着色器中使用上述定义的SSBO,而不创建两个单独的SSBO,即一个用于顶点着色器,另一个用于碎片着色器
这是我的着色器类。我的所有着色器都扩展到此类以实现
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);
}
}
我使用的是LWJGL2.9.3JavaOpenGL版本
该程序编译得很好,但是glLinkprogram()不正确
返回false,着色器信息日志为空
我甚至没有创建任何类型的缓冲区对象,我只是在学习语法
任何帮助都将不胜感激,请提前向您和在评论中帮助过我的人表示感谢,但我现在非常沮丧在您的代码中,我发现链接器错误: 错误:SSBO(命名灯光)着色器之间的绑定不匹配 对于不同着色器阶段中的相同命名缓冲区对象,必须使用相同的绑定点 在顶点着色器中:
layout(std430, binding=1) buffer Lights
{
vec3 positions[3];
vec3 attenuations[3];
vec3 colors[3];
} buf1;
Lights
列出缓冲区的外部可见名称,buf1
是着色器中块的名称
这意味着您必须为片段着色器中的缓冲区对象灯光使用相同的绑定点:
layout(std430,binding=1) buffer Lights // <---- binding=1 instead of binding=2
{
vec3 positions[3];
vec3 attenuations[3];
vec3 colors[3];
}buf2;
是的,这是可能的。链接失败时,链接器信息日志不太可能是空的,因此您可能希望首先查看该日志(或在此处显示代码)。上面给出的着色器代码总是打印编译/链接错误并退出应用程序。我希望这对那些从谷歌来寻找如何初始化SSBO的简单解决方案的人有所帮助,它的工作原理与UBO完全相同,只是您将GL_UNIFORM_BUFFER
更改为GL_着色器_STORAGE_BUFFER
。着色器代码也相同,只是std430
和buffer
而不是std140
和uniform
。SSBO没有太多内容,但有很多关于UBOs的学习资料。你是对的,它确实显示了绑定不匹配错误。我没有正确地看到它,这是我的错误。但是现在当我运行程序时,信息日志是空的。我要更新我的问题,谢谢你的提示,但仍然没有任何工作,因为我没有使用任何缓冲区对象,只是着色器代码。目前还没有创建和使用缓冲区,我只是在学习语法。程序在链接阶段崩溃
layout(std430, binding=1) buffer Lights
{
vec3 positions[3];
vec3 attenuations[3];
vec3 colors[3];
} buf1;
layout(std430,binding=1) buffer Lights // <---- binding=1 instead of binding=2
{
vec3 positions[3];
vec3 attenuations[3];
vec3 colors[3];
}buf2;
// 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