LWJGL Forum

Programming => Lightweight Java Gaming Library => Topic started by: RealSomebody on May 11, 2018, 19:14:55

Title: Deferred shading
Post by: RealSomebody on May 11, 2018, 19:14:55
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!