Hello,
I am currently having problems with deferred shading. I used this tutorial as a guidance for my code: https://lwjglgamedev.gitbooks.io/3d-game-development-with-lwjgl/content/chapter28/chapter28.html
I tried my best do fit his tutorial to my code, since I didn't follow his previous steps (which lead me to remove/ignore some stuff from his tutorial that is related to his previous tutorials).
When I try to light the scene with a directional light source, the output of that shader is transparent so I don't see anything at all. I tried debugging with a tool called "RenderDoc". These are the results:
Input to my light shader ("Text" stands for "Texture"):
(http://i.epvpimg.com/oOwmeab.png)
Output of that shader:
(http://i.epvpimg.com/DR9eeab.png)
It isn't actually black. Black is the color I am using in glClearColor (I changed it to blue and the output was blue as well. Thus I think, that the output is completely transparent or not even drawed to the texture as well).
I also tried to just write a plain "vec4(1, 1, 1, 1)" to the output with the same results. Nothing on that texture. So I assume, that something is wrong with the way I bind the texture or something.
SceneBuffer.java
public class SceneBuffer {
@Getter private int sceneBufferId;
@Getter private int textureId;
public SceneBuffer(Window window) {
this.sceneBufferId = glGenFramebuffers();
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, this.sceneBufferId);
int[] textureIds = new int[1];
glGenTextures(textureIds);
this.textureId = textureIds[0];
glBindTexture(GL_TEXTURE_2D, this.textureId);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, window.getWidth(), window.getHeight(), 0, GL_RGB, GL_FLOAT, (ByteBuffer) null);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, this.textureId, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
public void cleanUp() {
glDeleteTextures(this.textureId);
glDeleteFramebuffers(this.sceneBufferId);
}
}
GBuffer.java
public class GBuffer {
private static final int TOTAL_TEXTURES = 5;
@Getter private int gBufferId;
@Getter private int[] textureIds;
@Getter private int width;
@Getter private int height;
public GBuffer(Window window) {
this.gBufferId = glGenFramebuffers();
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, this.gBufferId);
this.textureIds = new int[TOTAL_TEXTURES];
glGenTextures(this.textureIds);
this.width = window.getWidth();
this.height = window.getHeight();
for (int i = 0; i < TOTAL_TEXTURES; i++) {
glBindTexture(GL_TEXTURE_2D, this.textureIds[i]);
int attachmentType;
switch (i) {
case TOTAL_TEXTURES - 1:
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, this.width, this.height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, (ByteBuffer) null);
attachmentType = GL_DEPTH_ATTACHMENT;
break;
default:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, this.width, this.height, 0, GL_RGB, GL_FLOAT, (ByteBuffer) null);
attachmentType = GL_COLOR_ATTACHMENT0 + i;
break;
}
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, attachmentType, GL_TEXTURE_2D, this.textureIds[i], 0);
}
try (MemoryStack stack = MemoryStack.stackPush()) {
IntBuffer intBuf = stack.mallocInt(TOTAL_TEXTURES);
int[] values = new int[] { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 };
intBuf.put(values).flip();
glDrawBuffers(intBuf);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
public void cleanUp() {
glDeleteFramebuffers(this.gBufferId);
if (this.textureIds != null) {
glDeleteTextures(this.textureIds);
}
}
}
directional_light_fragment.glsl
#version 330
out vec4 fragColor;
struct DirectionalLight {
vec3 color;
vec3 direction;
float intensity;
};
uniform sampler2D positionText;
uniform sampler2D diffuseText;
uniform sampler2D specularText;
uniform sampler2D normalText;
uniform vec2 screenSize;
uniform float specularPower;
uniform vec3 ambientLight;
uniform DirectionalLight directionalLight;
vec2 getUvCoord() {
return gl_FragCoord.xy / screenSize;
}
vec4 calcLightColor(vec4 diffuseC, vec4 specularC, vec3 lightColor, float lightIntensity, vec3 position, vec3 toLightDir, vec3 normal) {
vec4 diffuseColor = vec4(0, 0, 0, 1);
vec4 specularColor = vec4(0, 0, 0, 1);
float diffuseFactor = max(dot(normal, toLightDir), 0.0);
diffuseColor = diffuseC * vec4(lightColor, 1.0) * lightIntensity * diffuseFactor;
vec3 cameraDirection = normalize(-position);
vec3 fromLightDir = -toLightDir;
vec3 reflectedLight = normalize(reflect(fromLightDir, normal));
float specularFactor = max(dot(cameraDirection, reflectedLight), 0.0);
specularFactor = pow(specularFactor, specularPower);
specularColor = specularC * lightIntensity * specularFactor * vec4(lightColor, 1.0);
return (diffuseColor + specularColor);
}
vec4 calcDirectionalLight(vec4 diffuseC, vec4 specularC, DirectionalLight light, vec3 position, vec3 normal) {
return calcLightColor(diffuseC, specularC, light.color, light.intensity, position, normalize(light.direction), normal);
}
void main() {
vec2 uvCoord = getUvCoord();
vec3 worldPos = texture(positionText, uvCoord).xyz;
vec4 diffuseC = texture(diffuseText, uvCoord);
vec4 specularC = texture(specularText, uvCoord);
vec3 normal = texture(normalText, uvCoord).xyz;
vec4 diffuseSpecularComp = calcDirectionalLight(diffuseC, specularC, directionalLight, worldPos, normal);
fragColor = clamp(diffuseC * vec4(ambientLight, 1.0) + diffuseSpecularComp, 0, 1);
}
DirectionalLightRenderer.java
public class DirLightRenderer {
private static final Matrix4f MODEL_MATRIX = new Matrix4f();
private static final float SPECULAR_POWER = 10.0f;
private static DirectionalLight bufferSun;
private static Vector4f bufferDirection = new Vector4f();
private ShaderProgram dirLightShader;
private SceneModel sceneModel;
private GBuffer gBuffer;
private DirectionalLight sunLight;
private Vector3f ambientLight;
public DirLightRenderer(SceneModel sceneModel, GBuffer gBuffer, DirectionalLight sunLight, Vector3f ambientLight) throws IOException {
this.sceneModel = sceneModel;
this.gBuffer = gBuffer;
this.sunLight = sunLight;
this.ambientLight = ambientLight;
this.dirLightShader = new ShaderProgram();
this.dirLightShader.createVertexShader(ResourceLoader.loadResource("/resources/shaders/lightVertex.glsl"));
this.dirLightShader.createFragmentShader(ResourceLoader.loadResource("/resources/shaders/dirLightFragment.glsl"));
this.dirLightShader.link();
this.dirLightShader.createUniform("modelMatrix");
this.dirLightShader.createUniform("projectionMatrix");
this.dirLightShader.createUniform("screenSize");
this.dirLightShader.createUniform("positionText");
this.dirLightShader.createUniform("diffuseText");
this.dirLightShader.createUniform("specularText");
this.dirLightShader.createUniform("normalText");
this.dirLightShader.createUniform("specularPower");
this.dirLightShader.createUniform("ambientLight");
this.dirLightShader.createUniform("directionalLight.color");
this.dirLightShader.createUniform("directionalLight.direction");
this.dirLightShader.createUniform("directionalLight.intensity");
}
public void render(Matrix4f viewMatrix, Matrix4f projectionMatrix) {
glBindFramebuffer(GL_FRAMEBUFFER, this.sceneBuffer.getSceneBufferId());
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_ONE, GL_ONE);
glBindFramebuffer(GL_READ_FRAMEBUFFER, this.gBuffer.getGBufferId());
this.dirLightShader.bind();
this.dirLightShader.setUniform("modelMatrix", MODEL_MATRIX);
this.dirLightShader.setUniform("projectionMatrix", projectionMatrix);
this.dirLightShader.setUniform("specularPower", SPECULAR_POWER);
int[] textureIds = this.gBuffer.getTextureIds();
int numTextures = textureIds != null ? textureIds.length : 0;
for (int n = 0; n < numTextures; n++) {
glActiveTexture(GL_TEXTURE0 + n);
glBindTexture(GL_TEXTURE_2D, textureIds[n]);
}
this.dirLightShader.setUniform("positionText", 0);
this.dirLightShader.setUniform("diffuseText", 1);
this.dirLightShader.setUniform("specularText", 2);
this.dirLightShader.setUniform("normalText", 3);
this.dirLightShader.setUniform("screenSize", (float) this.gBuffer.getWidth(), (float) this.gBuffer.getHeight());
this.dirLightShader.setUniform("ambientLight", this.ambientLight);
bufferSun = new DirectionalLight(this.sunLight);
bufferDirection.set(bufferSun.getDirection(), 0);
bufferDirection.mul(viewMatrix);
bufferSun.setDirection4f(bufferDirection);
this.dirLightShader.setUniform("directionalLight.color", bufferSun.getColor());
this.dirLightShader.setUniform("directionalLight.direction", bufferSun.getDirection());
this.dirLightShader.setUniform("directionalLight.intensity", bufferSun.getIntensity());
this.sceneModel.render();
this.dirLightShader.unbind();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glEnable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
}
public void cleanUp() {
this.dirLightShader.cleanUp();
}
}
I am currently stuck at this problem for several days. I also rewrote the whole thing several times and had the same results every time. I have absolutely no clue where that mistake is.
Thanks in advance!