Reputation: 13
I'm writing a deferred shading code.
I have a FBO with 4 color attachments (texture) and a depth attachment (renderbuffer).
I render my scene with a shader, that writes to these 4 color attachments.
The problem is, that the data for the 0th color attachment is also written to the others.
Below is my code:
Renderer_Deferred.java
public class Renderer_Deferred
{
private final int FBO;
private final int depthbuffer;
public final int positiontexture, diffusetexture, normaltexture, bumpmap;
Renderer_Deferred()
{
System.out.println("Setting up the deferrer..");
positiontexture = GL11.glGenTextures();
diffusetexture = GL11.glGenTextures();
normaltexture = GL11.glGenTextures();
bumpmap = GL11.glGenTextures();
FBO = glGenFramebuffers();
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
GL11.glBindTexture(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, positiontexture);
GL11.glTexParameterf(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
GL11.glTexParameterf(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
GL11.glTexImage2D(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, 0, GL30.GL_RGB32F, Configuration.displayWidth, Configuration.displayheight, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, (java.nio.ByteBuffer) null);
GL11.glBindTexture(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, 0);
GL11.glBindTexture(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, diffusetexture);
GL11.glTexParameterf(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
GL11.glTexParameterf(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
GL11.glTexImage2D(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, 0, GL11.GL_RGBA, Configuration.displayWidth, Configuration.displayheight, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, (java.nio.ByteBuffer) null);
GL11.glBindTexture(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, 0);
GL11.glBindTexture(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, normaltexture);
GL11.glTexParameterf(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
GL11.glTexParameterf(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
GL11.glTexImage2D(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, 0, GL30.GL_RGB16F, Configuration.displayWidth, Configuration.displayheight, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, (java.nio.ByteBuffer) null);
GL11.glBindTexture(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, 0);
GL11.glBindTexture(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, bumpmap);
GL11.glTexParameterf(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
GL11.glTexParameterf(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
GL11.glTexImage2D(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, 0, GL11.GL_RGBA, Configuration.displayWidth, Configuration.displayheight, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, (java.nio.ByteBuffer) null);
GL11.glBindTexture(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, 0);
GL11.glViewport(0, 0, Configuration.displayWidth, Configuration.displayheight);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, positiontexture, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, diffusetexture, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, normaltexture, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, bumpmap, 0);
depthbuffer = glGenRenderbuffers();
glBindRenderbuffer(GL_RENDERBUFFER, depthbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL14.GL_DEPTH_COMPONENT24, Configuration.displayWidth, Configuration.displayheight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
System.err.println("Generating the deferred FBO failed!");
System.exit(5321);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0); ////////////////////////////////////////////////////////
}
public void startRendering()
{
// CLEAR AND HOOK UP TEXTURES
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
IntBuffer buf = BufferUtils.createIntBuffer(4);
buf.put(GL_COLOR_ATTACHMENT0);
buf.put(GL_COLOR_ATTACHMENT1);
buf.put(GL_COLOR_ATTACHMENT2);
buf.put(GL_COLOR_ATTACHMENT3);
buf.flip();
GL20.glDrawBuffers(buf);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
System.err.println("Deferred renderer failed to setup correctly!");
}
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glDepthFunc(GL11.GL_LEQUAL);
GL11.glViewport(0, 0, Configuration.displayWidth, Configuration.displayheight);
GL11.glClearColor(SimpleCraft.world.skycolor.x, SimpleCraft.world.skycolor.y, SimpleCraft.world.skycolor.z, 0f);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
}
public void stopRendering()
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
}
Above is my code, that activates and deactivates the deferred renderer. After this is done, the postprocessor activates:
public class Renderer_Postprocessor
{
PostprocessingObject postprocessor;
public static int loc_pos, loc_diffuse, loc_normal, loc_bump, loc_ambient;
public static int loc_viewingdistance, loc_modelviewmatrix;
Renderer_Postprocessor()
{
postprocessor = new PostprocessingObject();
}
public void postprocess(int pos, int diffuse, int normal, int bump)
{
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL20.glUseProgram(Shaders.PROGRAM_POSTPROCESSOR);
GL20.glDrawBuffers(GL11.GL_BACK);
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL11.glBindTexture(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, pos);
GL13.glActiveTexture(GL13.GL_TEXTURE1);
GL11.glBindTexture(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, diffuse);
GL13.glActiveTexture(GL13.GL_TEXTURE2);
GL11.glBindTexture(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, normal);
GL13.glActiveTexture(GL13.GL_TEXTURE3);
GL11.glBindTexture(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, bump);
GLUtility.uploadToShader(Configuration.viewDistanceInBlocks, loc_viewingdistance);
GLUtility.uploadToShader(Camera.getModelViewMatrix(new Matrix4f(), Camera.getViewMatrix()), loc_modelviewmatrix);
GL30.glBindVertexArray(postprocessor.getVAO());
GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, 6);
GL30.glBindVertexArray(0);
GL20.glUseProgram(0);
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL11.glBindTexture(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, 0);
GL13.glActiveTexture(GL13.GL_TEXTURE1);
GL11.glBindTexture(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, 0);
GL13.glActiveTexture(GL13.GL_TEXTURE2);
GL11.glBindTexture(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, 0);
GL13.glActiveTexture(GL13.GL_TEXTURE3);
GL11.glBindTexture(ARBTextureRectangle.GL_TEXTURE_RECTANGLE_ARB, 0);
GL11.glEnable(GL11.GL_DEPTH_TEST);
}
}
Below are my fragment shaders for the deferrer and the postprocessor:
Deferred_Fragment.frag
#version 330 core
#extension GL_ARB_explicit_uniform_location : require
layout(location=0) uniform sampler2DArray texture_diffuse;
layout(location=1) uniform sampler2DArray texture_normal;
uniform vec3 pass_EyeVector;
in vec4 pass_Position;
in vec3 pass_TextureCoord;
in vec3 pass_Normal;
layout(location = 0) out vec4 pos;
layout(location = 1) out vec4 dif;
layout(location = 2) out vec4 nor;
layout(location = 3) out vec4 bum;
void main(void)
{
pos = texture(texture_diffuse, pass_TextureCoord); // Transform from -1 / 1 to 0 / 1
dif = pass_Position;
nor = vec4(pass_Normal, 1.0);
bum = texture(texture_normal, pass_TextureCoord);
}
And the postprocessor.frag
#version 330 core
#extension GL_ARB_explicit_uniform_location : require
layout(location=0) uniform sampler2DRect positiontexture;
layout(location=1) uniform sampler2DRect diffusetexture;
layout(location=2) uniform sampler2DRect normaltexture;
layout(location=3) uniform sampler2DRect bumpmap;
in vec2 pass_TextureCoord;
out vec4 out_Color;
void main(void)
{
out_Color = texture(diffusetexture, pass_TextureCoord);
}
Upvotes: 0
Views: 748
Reputation: 39
You should use layout binding instead of layout location for binding samplers. You should probably also recheck your binding points because you have multiple samplers bound to the same location. If you bind your texture to TEXTURE0, specify it as binding=0.
Try to change it to:
layout(binding=0) uniform sampler2DArray texture_diffuse;
layout(binding=1) uniform sampler2DArray texture_normal;
layout(binding=0) uniform sampler2DRect positiontexture;
layout(binding=1) uniform sampler2DRect diffusetexture;
layout(binding=2) uniform sampler2DRect normaltexture;
layout(binding=3) uniform sampler2DRect bumpmap;
Upvotes: 0
Reputation: 54592
You're trying to use the location
layout qualifier for uniform variables:
layout(location=0) uniform sampler2DArray texture_diffuse;
layout(location=1) uniform sampler2DArray texture_normal;
layout(location=0) uniform sampler2DRect positiontexture;
layout(location=1) uniform sampler2DRect diffusetexture;
layout(location=2) uniform sampler2DRect normaltexture;
layout(location=3) uniform sampler2DRect bumpmap;
I have been unable to find anything in the GLSL specs suggesting that this is supported. At least in 330, only vertex shader inputs and fragment shader outputs are listed to support location
. In later versions, it also seems to be supported for in
/out
variables of other shader stages, but I still don't see any mention of it for uniforms.
You probably intended to set the texture unit of the samplers with this qualifier. There is a binding
qualifier, which looks like this:
layout(binding=0) uniform sampler2DArray texture_diffuse;
layout(binding=1) uniform sampler2DArray texture_normal;
This is only supported in OpenGL 4.2 (GLSL version 420) and later, though. If you want to stick with GLSL 330, you will need to set the texture unit of the sampler uniforms in the old fashioned way, using glGetUniformLocaction()
and glUniform1i()
.
Upvotes: 1