Deferred shading

Started by RealSomebody, May 11, 2018, 19:14:55

Previous topic - Next topic

RealSomebody

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"):


Output of that shader:


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!