GLSL Random Black Screen when Rendering IBL Irradiance Map

I’m trying to implement image based lighting in my renderer, but when I try to (pre) render my irradiance map, the whole screen becomes black on startup. It works once and once it doesn’t.
The odd thing about it is that, everything works just fine when I just stream the original cube map into the irradiance map.

And the code’s below.

irradiance.glsl


@vertex
#version 330 core

layout(location=0)in vec3 aVertex;

out vec3 vFragPos;

uniform mat4 uViewMatrix;
uniform mat4 uProjectionMatrix;

void main() {
	vFragPos = aVertex;
	
	gl_Position = uProjectionMatrix * uViewMatrix * vec4(vFragPos, 1.0);
}



@fragment
#version 330 core
#define PI 3.14159265359
#define SAMPLE_COUNT 512u

in vec3 vFragPos;

layout(location=0)out vec3 oAlbedo;

uniform samplerCube uCubeMap;
uniform float uRoughness;

vec3 importanceSampleGGX(vec2 Xi, vec3 N, float roughness) {
	float roughness2 = roughness * roughness;

	float phi = 2.0 * PI * Xi.x;
	float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (roughness2 * roughness2 - 1.0) * Xi.y));
	float sinTheta = sqrt(1.0 - cosTheta * cosTheta);

	vec3 H;
	H.x = sinTheta * cos(phi);
	H.y = sinTheta * sin(phi);
	H.z = cosTheta;

	vec3 up = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
	vec3 tangent = normalize(cross(up, N));
	vec3 bitangent = cross(N, tangent);

	return tangent * H.x + bitangent * H.y + N * H.z;
}

float radicalInverse_VdC(uint bits) {
	bits = (bits << 16u) | (bits >> 16u);
	bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
	bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
	bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
	bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
	return float(bits) * 2.3283064365386963e-10; // / 0x100000000
}

vec2 hammersley(uint i, uint N) {
	return vec2(float(i) / float(N), radicalInverse_VdC(i));
}

void main() {
	vec3 N = normalize(vFragPos);

	vec4 irradiance = vec4(0.0);

	for(uint sample=0u; sample<SAMPLE_COUNT; sample++) {
		vec2 xi = hammersley(sample, SAMPLE_COUNT);
		vec3 H = importanceSampleGGX(xi, N, uRoughness);
		vec3 V = N;
		vec3 L = normalize(2.0 * dot(V, H) * H - V);
		
		float NdotL = max(0.0, dot(N, L));

		if(NdotL > 0.0) {
			irradiance.xyz += texture(uCubeMap, L).xyz * NdotL;
			irradiance.w += NdotL;
		}
	}
	irradiance.xyz /= irradiance.w;

	oAlbedo = irradiance.xyz; //black screen at random
	//oAlbedo = texture(uCubeMap, vFragPos).xyz; //works fine
}

IrradianceTexture.h


#include "../../resource/mesh/Mesh.h"
#include "../../resource/mesh/CubeMesh.h"
#include "../../resource/texture/CubeMapTexture.h"
#include "../../resource/Shader.h"
#include "../../util/Math.h"
#include "../../util/Matrix4.h"
#include "../../util/Vector3.h"

class IrradianceTexture : public CubeMapTexture {
public:
    IrradianceTexture(CubeMapTexture *cubeMap, int quadSize) {
        //CREATE CUBE
        Mesh *cube = new CubeMesh(2, true);
        cube->bind();
        Shader *shader = new Shader("shaders/irradiance.glsl");
        shader->bind();
        Shader::setUniform(shader->getUniformLocation("uCubeMap"), 0);
        Shader::setUniform(shader->getUniformLocation("uProjectionMatrix"), Matrix4::perspective(90, 1, 0.1, 10));
        int viewMatrixLocation = shader->getUniformLocation("uViewMatrix");
        int roughnessLocation = shader->getUniformLocation("uRoughness");
        //CREATE FRAMEBUFFER AND THE CUBEMAP
        unsigned int framebuffer;
        glGenFramebuffers(1, &framebuffer);
        glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
        glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
        for(unsigned int i=0; i<6; i++) {
            glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, quadSize, quadSize, 0, GL_RGB, GL_FLOAT, nullptr);
        }
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
        //RENDER THE CUBEMAP
        Matrix4 viewMatrices[6] = {
                Matrix4::transform(Vector3(0), Vector3(  0, -90, 180), Vector3(1)),
                Matrix4::transform(Vector3(0), Vector3(  0,  90, 180), Vector3(1)),
                Matrix4::transform(Vector3(0), Vector3(-90,   0,   0), Vector3(1)),
                Matrix4::transform(Vector3(0), Vector3( 90,   0,   0), Vector3(1)),
                Matrix4::transform(Vector3(0), Vector3(  0, 180, 180), Vector3(1)),
                Matrix4::transform(Vector3(0), Vector3(  0,   0, 180), Vector3(1))
        };
        glDisable(GL_DEPTH_TEST);
        glDisable(GL_BLEND);
        glDisable(GL_CULL_FACE);
        glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
        glActiveTexture(GL_TEXTURE0);
        cubeMap->bind();
        unsigned int mipmapLevels = 5;
        for(unsigned int level=0; level<mipmapLevels; level++) {
            glViewport(0, 0, quadSize*Math::pow(0.5, level), quadSize*Math::pow(0.5, level));
            Shader::setUniform(roughnessLocation, (float)level / (mipmapLevels - 1));
            for(unsigned int i=0; i<6; i++) {
                Shader::setUniform(viewMatrixLocation, viewMatrices[i]);
                glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, texture, level);
                glDrawElements(GL_TRIANGLES, cube->getIndexCount(), GL_UNSIGNED_INT, 0);
            }
        }
        //CLEAN UP
        delete cube;
        delete shader;
        glDeleteFramebuffers(1, &framebuffer);
    }
};

I just want to add that, I’ll use IBL specular irradiance map mipmap level 4 as diffuse irradiance map, so I won’t have to render same texture again.

[QUOTE=Crimz8n;1293623]I’m trying to implement image based lighting in my renderer, but when I try to (pre) render my irradiance map, the whole screen becomes black on startup. It works once and once it doesn’t.
The odd thing about it is that, everything works just fine when I just stream the original cube map into the irradiance map.[/QUOTE]
Does glMemoryBarrier() help?

I’m using OpenGL 3.3… And I don’t even know when to call it… :confused:

When the screen is black, the framerate boosts to 800 FPS. And glGetError returns GL_NO_ERROR… :dejection:

My render code:


    void render(Scene *scene, Environment *environment) {
        //GATHER REQUIRED VALUES
        Matrix4 cameraTransform = scene->camera->getGlobalTransform();
        Matrix4 viewMatrix = cameraTransform.inverse();
        Matrix4 projectionMatrix = scene->camera->getProjection();
        Vector3 cameraPosition = Vector3(cameraTransform * Vector4(0, 0, 0, 1));
        //RENDER MATERIAL DATA
        glViewport(0, 0, width, height);
        glClearColor(0, 0, 0, 1);
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_CULL_FACE);
        glEnable(GL_BLEND);
        glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
        glDepthFunc(GL_LEQUAL);
        glCullFace(GL_BACK);
        glBlendFunc(GL_ONE, GL_ZERO);

        glBindFramebuffer(GL_FRAMEBUFFER, gBuffers[0]);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        for(Model *model : scene->getModels()) {
            model->material->bind(model->getGlobalTransform(), viewMatrix, projectionMatrix);
            if(!model->material->cullFace)glDisable(GL_CULL_FACE);
            else glEnable(GL_CULL_FACE);
            model->mesh->bind();
            glDrawElements(GL_TRIANGLES, model->mesh->getIndexCount(), GL_UNSIGNED_INT, 0); //It looks like GL just skips this code...
            printf("DEBUG
"); //Prints "DEBUG
" when the screen is black... Works just like expected...
        }
        //CALCULATE IMAGE BASED LIGHTING
        glDisable(GL_DEPTH_TEST);
        glBlendFunc(GL_ONE, GL_ONE);

        glBindFramebuffer(GL_FRAMEBUFFER, gBuffers[1]);
        glClear(GL_COLOR_BUFFER_BIT);
        plane->bind();
        bindGBufferTextures(0);
        glActiveTexture(GL_TEXTURE5);
        environment->getIrradianceMap()->bind(); //Irradiance map could be nullptr, but windows would show NOT RESPONDING error then...
        IBLShader->bind();
        Shader::setUniform(IBLShaderCameraPositionLocation, cameraPosition);
        glDrawElements(GL_TRIANGLES, plane->getIndexCount(), GL_UNSIGNED_INT, 0);
        //CALCULATE ACTUAL LIGHTING
        lightingShader->bind();
        Shader::setUniform(cameraPositionLocation, cameraPosition);
        Shader::setUniform(lightTypeLocation, 0);
        for(DirectionalLight *light : scene->getDirectionalLights()) {
            Shader::setUniform(lightColorLocation, light->color);
            Shader::setUniform(lightAmbientLocation, light->ambient);
            Shader::setUniform(lightDirectionLocation, Vector3(light->getGlobalTransform()*Vector4(0,0,-1,0)));
            glDrawElements(GL_TRIANGLES, plane->getIndexCount(), GL_UNSIGNED_INT, 0);
        }

        glBlendFunc(GL_ONE, GL_ZERO);
        //SKYBOX RENDERING
        if(environment->getBackground()) {
            glEnable(GL_DEPTH_TEST);
            glDisable(GL_CULL_FACE);

            glBindFramebuffer(GL_READ_FRAMEBUFFER, gBuffers[0]);
            glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
            glBindFramebuffer(GL_READ_FRAMEBUFFER, gBuffers[1]);

            skyboxShader->bind();
            skyboxShader->setUniform(skyboxShaderViewMatrixLocation, viewMatrix);
            skyboxShader->setUniform(skyboxShaderProjectionMatrixLocation, projectionMatrix);
            glActiveTexture(GL_TEXTURE0);
            environment->getBackground()->bind();
            cube->bind();
            glDrawElements(GL_TRIANGLES, cube->getIndexCount(), GL_UNSIGNED_INT, 0);

            glDisable(GL_DEPTH_TEST);
            glEnable(GL_CULL_FACE);
        }
        //POST PROCESSING USING PING-PONG BUFFERS
        for(int i=0; i<environment->effects.length(); i++) {
            glBindFramebuffer(GL_FRAMEBUFFER, gBuffers[i%2]);
            bindGBufferTextures((i+1)%2);
            environment->effects[i]->bind();
            glDrawElements(GL_TRIANGLES, plane->getIndexCount(), GL_UNSIGNED_INT, 0);
        }
        //COPY THE RESULT TO THE WINDOW
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
        glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
    }