SSAO und ShadowMapping Probleme



  • Hallo!

    Nachdem ich neu hier bin, möchte ich erst mal alle herzlich grüßen und einen schönen Tag wünschen! 🙂
    Da das aber nicht mein einziger Grund ist warum ich hier schreibe, möchte ich auch gleich darauf zu sprechen kommen.
    Ich habe nämlich ein Problem beim zusammenfügen von SSAO und ShadowMapping und wäre daher für jede Art von Hilfe dankbar!
    Was jetzt kommt, ist leider eine ganz schöne Textwall an Code, ich hoffe dass man trotzdem irgendwie was daraus lesen kann!

    http://i59.tinypic.com/bhown.png
    http://i59.tinypic.com/11kwqcj.png

    So siehts bei mir im Moment aus, ich hoffe die links laufen!
    Mein Problem ist dass die Schatten so komplett falsch sind, ShadowMapping läuft eigentlich relativ problemlos, aber sobald ich SSAO dazuschalte, dann siehts aus als würde ein Quadrat davorstehen und alles dahinter verdunkeln, wenn ich zB das Labyrinth aus dem Shadowmapping nehme, dann sieht man auch dass die Schatten ganz anders platziert sind und auch teilweise mehrfach vorkommen.

    Hier folgt nun die CodeWall, angefangen mit der SSAO initialisierung.

    void initSSAO()
    {
            //call shaders
    	ball->bindSSAOs();
    	plane->bindSSAOs();
    	item->bindSSAOs();
    	enemy->bindSSAOs();
    
    	//prepare GEOMETRY: fbo, depth and texture
    	{
    		geoPassShader->useShader();
    		geo_fbo = 0;
    		geo_depth = 0;
    		geo_texture = 0;
    		geo_normal = 0;
    		geo_posdepth = 0;
    
    		// Create the FBO
    		glGenFramebuffers(1, &geo_fbo);
    		glBindFramebuffer(GL_FRAMEBUFFER, geo_fbo);
    
    		// Create the textures - Position + linear depth color buffer
    		glGenTextures(1, &geo_posdepth);
    		glBindTexture(GL_TEXTURE_2D, geo_posdepth);
    		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGB, GL_FLOAT, NULL);
    		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, geo_posdepth, 0);
    
    		// Create the textures - normal color buffer
    		glGenTextures(1, &geo_normal);
    		glBindTexture(GL_TEXTURE_2D, geo_normal);
    		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_FLOAT, NULL);
    		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, geo_normal, 0);
    
    		// Create the textures - Albedo color buffer
    		glGenTextures(1, &geo_texture);
    		glBindTexture(GL_TEXTURE_2D, geo_texture);
    		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_FLOAT, NULL);
    		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, geo_texture, 0);
    
    		// - Tell OpenGL which color attachments we'll use (of this framebuffer) for rendering 
    		GLuint attachments[3] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
    		glDrawBuffers(3, attachments);
    
    		// Create the textures - depth buffer (renderbuffer)
    		glGenRenderbuffers(1, &geo_depth);
    		glBindRenderbuffer(GL_RENDERBUFFER, geo_depth);
    		glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
    		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, geo_depth);
    
    		if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
    			std::cout << "Framebufferstatus not ok" << std::endl;
    			system("PAUSE");
    			exit(EXIT_FAILURE);
    		}
    
    		// restore default FBO
    		glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
    		//glUseProgram(0);
    	}
    
    	//prepare SSAO: fbo, texture
    	{
    		ssaoShader->useShader();
    		ssao_fbo = 0;
    		ssao_texture = 0;
    
    		// Create the FBO
    		glGenFramebuffers(1, &ssao_fbo);
    		glBindFramebuffer(GL_FRAMEBUFFER, ssao_fbo);
    
    		// Create the textures
    		glGenTextures(1, &ssao_texture);
    		glBindTexture(GL_TEXTURE_2D, ssao_texture);
    		glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width, height, 0, GL_RGB, GL_FLOAT, NULL);
    		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ssao_texture, 0);
    
    		if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
    			std::cout << "Framebufferstatus not ok" << std::endl;
    			system("PAUSE");
    			exit(EXIT_FAILURE);
    		}
    
    		// create KERNEL
    		for (int i = 0; i < KERNEL_SIZE; i++)
    		{
    			glm::vec3 tmp;
    			tmp.x = 2.0f * (float)rand() / RAND_MAX - 1.0f;
    			tmp.y = 2.0f * (float)rand() / RAND_MAX - 1.0f;
    			tmp.z = 2.0f * (float)rand() / RAND_MAX - 1.0f;
    
    			// Create a scale value between [0;1[ .
    			GLfloat scale = (GLfloat)i / (GLfloat)KERNEL_SIZE;
    
    			scale = (0.1f + (scale * scale)) * (1.0f - 0.1f);
    
    			tmp *= scale;
    
    			ssaoKernel.push_back(tmp);
    		}
    		//glUseProgram(0);
    	}
    
    	//prepare BLUR: fbo, texture
    	{
    		blurShader->useShader();
    		blur_fbo = 0;
    		blur_texture = 0;
    
    		// Create the FBO
    		glGenFramebuffers(1, &blur_fbo);
    		glBindFramebuffer(GL_FRAMEBUFFER, blur_fbo);
    
    		// Create the textures
    		glGenTextures(1, &blur_texture);
    		glBindTexture(GL_TEXTURE_2D, blur_texture);
    		glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width, height, 0, GL_RGB, GL_FLOAT, NULL);
    		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, blur_texture, 0);
    
    		if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
    			std::cout << "Framebufferstatus not ok" << std::endl;
    			system("PAUSE");
    			exit(EXIT_FAILURE);
    		}
    
    	}
    
    	// restore default FBO
    	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
    
    	// Noise texture
    	{
    		std::vector<glm::vec3> ssaoNoise;
    		for (GLuint i = 0; i < 16; i++)
    		{
    			glm::vec3 tmp;
    			tmp.x = 2.0f * (float)rand() / RAND_MAX - 1.0f;
    			tmp.y = 2.0f * (float)rand() / RAND_MAX - 1.0f;
    			tmp.z = 2.0f * (float)rand() / RAND_MAX - 1.0f;
    
    			ssaoNoise.push_back(tmp);
    		}
    
    		glGenTextures(1, &noise_texture);
    		glBindTexture(GL_TEXTURE_2D, noise_texture);
    		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, 4, 4, 0, GL_RGB, GL_FLOAT, &ssaoNoise[0]);
    		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    	}
    
    	//glUseProgram(0);
    }
    

    --------------------------------------------------------------

    Weiter gehts mit dem periodisch aufgerufenen SSAO execute.

    void ssaoExec()
    {
    	glm::mat4 model;
    	vl = glm::lookAt(cameraPosition, glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
    	pl = glm::perspective(glm::radians(45.0f), 1.0f, 20.0f, 80.0f);
    
    	//------------GEOMETRY--------------
    	geoPassShader->useShader();
    
    	glBindFramebuffer(GL_FRAMEBUFFER, geo_fbo);
    
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    	auto geo_proj = glGetUniformLocation(geoPassShader->programHandle, "projection");
    	glUniformMatrix4fv(geo_proj, 1, GL_FALSE, glm::value_ptr(pl));
    	auto geo_view = glGetUniformLocation(geoPassShader->programHandle, "view");
    	glUniformMatrix4fv(geo_view, 1, GL_FALSE, glm::value_ptr(vl));
    
    	//BALL
    	model = ball->modelMatrix;
    	auto wvp_ball_loc = glGetUniformLocation(geoPassShader->programHandle, "model");
    	glUniformMatrix4fv(wvp_ball_loc, 1, GL_FALSE, glm::value_ptr(model));
    
    	ball->draw();
    
    	//PLANE
    	model = plane->modelMatrix;
    	auto wvp_plane_loc = glGetUniformLocation(geoPassShader->programHandle, "model");
    	glUniformMatrix4fv(wvp_plane_loc, 1, GL_FALSE, glm::value_ptr(model));
    
    	plane->draw();
    
    	//ITEM
    	model = item->modelMatrix;
    	auto wvp_item_loc = glGetUniformLocation(geoPassShader->programHandle, "model");
    	glUniformMatrix4fv(wvp_item_loc, 1, GL_FALSE, glm::value_ptr(model));
    
    	item->draw();
    
    	//ENEMY
    	model = enemy->modelMatrix;
    	auto wvp_enemy_loc = glGetUniformLocation(geoPassShader->programHandle, "model");
    	glUniformMatrix4fv(wvp_enemy_loc, 1, GL_FALSE, glm::value_ptr(model));
    
    	enemy->draw();
    
    	glBindFramebuffer(GL_FRAMEBUFFER, 0);
    	//glUseProgram(0);
    
    	//------------SSAO--------------
    	ssaoShader->useShader();
    
    	glBindFramebuffer(GL_FRAMEBUFFER, ssao_fbo);
    
    	glClear(GL_COLOR_BUFFER_BIT);
    
    	glActiveTexture(GL_TEXTURE0);
    	glBindTexture(GL_TEXTURE_2D, geo_posdepth);
    	glActiveTexture(GL_TEXTURE1);
    	glBindTexture(GL_TEXTURE_2D, geo_normal);
    	glActiveTexture(GL_TEXTURE2);
    	glBindTexture(GL_TEXTURE_2D, noise_texture);
    
    	auto kernel_loc = glGetUniformLocation(ssaoShader->programHandle, "samples");
    	glUniform3fv(kernel_loc, KERNEL_SIZE, (const GLfloat*)&ssaoKernel[0]);
    
    	auto ssao_proj = glGetUniformLocation(ssaoShader->programHandle, "projection");
    	glUniformMatrix4fv(ssao_proj, 1, GL_FALSE, glm::value_ptr(pl));
    	renderQuad();
    
    	glBindFramebuffer(GL_FRAMEBUFFER, 0);
    
    	//-----------BLUR------------
    	blurShader->useShader();
    
    	glBindFramebuffer(GL_FRAMEBUFFER, blur_fbo);
    
    	glClear(GL_COLOR_BUFFER_BIT);
    
    	glActiveTexture(GL_TEXTURE0);
    	glBindTexture(GL_TEXTURE_2D, ssao_texture);
    	renderQuad();
    
    	glBindFramebuffer(GL_FRAMEBUFFER, 0);
    	//glLoadName(-1);
    }
    

    ----------------
    Für alle jene die wissen möchten was renderQuad() macht:

    GLuint quadVAO = 0;
    GLuint quadVBO;
    void renderQuad()
    {
    	if (quadVAO == 0)
    	{
    		GLfloat quadVertices[] = {
    			// Positions        // Texture Coords
    			-1.0f, 1.0f, 0.0f, -1.0f, 1.0f,
    			-1.0f, -1.0f, 0.0f, -1.0f, -1.0f,
    			1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
    			1.0f, -1.0f, 0.0f, 1.0f, -1.0f,
    		};
    		// Setup plane VAO
    		glGenVertexArrays(1, &quadVAO);
    		glGenBuffers(1, &quadVBO);
    		glBindVertexArray(quadVAO);
    		glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
    		glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);
    		glEnableVertexAttribArray(0);
    		glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0);
    		glEnableVertexAttribArray(1);
    		glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
    	}
    	glBindVertexArray(quadVAO);
    	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    	glBindVertexArray(0);
    }
    

    ----------------------------------------------------

    Mein Main.draw():

    void draw(){
    
    	glm::mat4 l(0.5, 0.0, 0.0, 0.0,
    		0.0, 0.5, 0.0, 0.0,
    		0.0, 0.0, 0.5, 0.0,
    		0.5, 0.5, 0.5, 1.0
    		);
    
    	//set up View Frustum
    	/*if (vfc == 1){
    		ExtractFrustum();
    	}
    	glm::vec3 cen;
    	float rad;*/
    
    	shader->useShader();
    
    	auto spotLight_Loc = glGetUniformLocation(shader->programHandle, "spotlightPosition");
    	glUniform4fv(spotLight_Loc, 1, glm::value_ptr(spot));
    
    	/*auto view_loc = glGetUniformLocation(shader->programHandle, "viewMatrix");
    	glUniformMatrix4fv(view_loc, 1, GL_FALSE, glm::value_ptr(item->modelMatrix));*/
    
    	auto tex_loc = glGetUniformLocation(shader->programHandle, "shadowMap");
    	glActiveTexture(GL_TEXTURE1);
    	glBindTexture(GL_TEXTURE_2D, zbufferTex);
    	glUniform1i(tex_loc, 1);
    
    	//----------SSAO------------
    	auto screenSize_loc = glGetUniformLocation(shader->programHandle, "screenSize");
    	glUniform2f(screenSize_loc, (float)width, (float)height);
    
    	auto aoTexture_loc = glGetUniformLocation(shader->programHandle, "gAOMap");
    	glActiveTexture(GL_TEXTURE3);
    	glBindTexture(GL_TEXTURE_2D, blur_texture);
    	glUniform1i(aoTexture_loc, 3);
    	//renderQuad();
    	//-------------------------
    
    	m_vl_pl_l_matrix = l*pl*vl*ball->modelMatrix;
    	auto mvpl_ball_loc = glGetUniformLocation(shader->programHandle, "mvlpllMatrix");
    	glUniformMatrix4fv(mvpl_ball_loc, 1, GL_FALSE, glm::value_ptr(m_vl_pl_l_matrix));
    
    	ball->draw(proj, view);
    
    	m_vl_pl_l_matrix = l*pl*vl*plane->modelMatrix;
    	auto mvpl_plane_loc = glGetUniformLocation(shader->programHandle, "mvlpllMatrix");
    	glUniformMatrix4fv(mvpl_plane_loc, 1, GL_FALSE, glm::value_ptr(m_vl_pl_l_matrix));
    
    	plane->draw(proj, view);
    
    	/*item->bSphere(cen, rad); //check view frustum
    	glm::vec4 tmp =  glm::vec4(cen, 1);
    	tmp = item->modelMatrix * tmp;
    	if (vfc == 0 || SphereInFrustum(glm::vec3(tmp), rad)){*/
    		m_vl_pl_l_matrix = l*pl*vl*item->modelMatrix;
    		auto mvpl_item_loc = glGetUniformLocation(shader->programHandle, "mvlpllMatrix");
    		glUniformMatrix4fv(mvpl_item_loc, 1, GL_FALSE, glm::value_ptr(m_vl_pl_l_matrix));
    
    		item->draw(proj, view);
    	//}
    
    	if (transparent == 1){
    		auto transparent_loc = glGetUniformLocation(shader->programHandle, "transparent");
    		glUniform1i(transparent_loc, 1);
    
    		glEnable(GL_BLEND);
    		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    		glDisable(GL_CULL_FACE);
    
    	}
    
    	/*enemy->bSphere(cen, rad); //check view frustum
    	tmp = glm::vec4(cen, 1);
    	tmp = enemy->modelMatrix * tmp;
    	if (vfc == 0 || SphereInFrustum(glm::vec3(tmp), rad)){*/
    		m_vl_pl_l_matrix = l*pl*vl*enemy->modelMatrix;
    		auto mvpl_enemy_loc = glGetUniformLocation(shader->programHandle, "mvlpllMatrix");
    		glUniformMatrix4fv(mvpl_enemy_loc, 1, GL_FALSE, glm::value_ptr(m_vl_pl_l_matrix));
    
    		enemy->draw(proj, view);
    	//}
    
    	if (transparent == 1){
    
    		glDisable(GL_BLEND);
    		glEnable(GL_CULL_FACE);
    
    	}
    	glUseProgram(0);
    }
    

    -------------------------------------------

    Hier nochmal wie ich bei den Objekten den GeometryShader anwende, ich musste die "normal" auskommentieren, da sonst die ganze Szene zu einem Ball in der Mitte des Screens zusammengefasst wird.

    void Mesh::depthProgramHandle(Shader* depthShader, bool isSSAO)
    {
    	//glGenVertexArrays(1, &vao);
    	glBindVertexArray(vao);
    
    	depthShader->useShader();
    
    	//texID = glGetUniformLocation(depthShader->programHandle, "texture_color");
    
    	glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
    	GLint positionIndex = glGetAttribLocation(depthShader->programHandle, "position");
    	glEnableVertexAttribArray(positionIndex);
    	glVertexAttribPointer(positionIndex, 3, GL_FLOAT, GL_FALSE, 0, 0);
    
    	if (isSSAO)
    	{
    		/*glBindBuffer(GL_ARRAY_BUFFER, normalsBuffer);
    		normalIndex = glGetAttribLocation(depthShader->programHandle, "normal");
    		if (normalIndex != -1){
    			glEnableVertexAttribArray(normalIndex);
    			glVertexAttribPointer(normalIndex, 3, GL_FLOAT, GL_FALSE, 0, 0);
    		}*/
    
    		glBindBuffer(GL_ARRAY_BUFFER, uvBuffer);
    		uvIndex = glGetAttribLocation(depthShader->programHandle, "texCoords");
    		if (uvIndex != -1){
    			glEnableVertexAttribArray(uvIndex);
    			glVertexAttribPointer(uvIndex, 2, GL_FLOAT, GL_FALSE, 0, 0);
    		}
    	}
    
    	glBindVertexArray(0);
    	glBindBuffer(GL_ARRAY_BUFFER, 0);
    	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    }
    

    Hier die draw() Methode wie sie von SSAO und ShadowMapping aufgerufen wird.

    void Mesh::draw()
    {
    	glBindVertexArray(vao);
    
    	glActiveTexture(GL_TEXTURE0);
    	glBindTexture(GL_TEXTURE_2D, texture);
    
    	glDrawArrays(GL_TRIANGLES, 0, indices.size());
    
    	glBindVertexArray(0);
    }
    

    ------------------------------------------------------

    Jetzt folgen die Shader:

    Der Geometry VS

    #version 330
    
    layout (location = 0) in vec3 position;
    layout (location = 1) in vec3 normal;
    layout (location = 2) in vec2 texCoords;
    
    out vec3 FragPos;
    out vec2 TexCoords;
    out vec3 Normal;
    
    uniform mat4 model;
    uniform mat4 view;
    uniform mat4 projection;
    
    void main()
    {
        vec4 viewPos = view * model * vec4(position, 1.0f);
        FragPos = viewPos.xyz; 
        gl_Position = projection * viewPos;
        TexCoords = texCoords;
    
        mat3 normalMatrix = transpose(inverse(mat3(view * model)));
        Normal = normalMatrix * normal;
    }
    

    Geometry FS

    #version 330
    
    layout (location = 0) out vec4 gPositionDepth;
    layout (location = 1) out vec3 gNormal;
    layout (location = 2) out vec4 gAlbedoSpec;
    
    in vec2 TexCoords;
    in vec3 FragPos;
    in vec3 Normal;
    
    const float NEAR = 0.1; // Projection matrix's near plane distance
    const float FAR = 50.0f; // Projection matrix's far plane distance
    float LinearizeDepth(float depth)
    {
        float z = depth * 2.0 - 1.0; // Back to NDC 
        return (2.0 * NEAR * FAR) / (FAR + NEAR - z * (FAR - NEAR));	
    }
    
    void main()
    {    
        // Store the fragment position vector in the first gbuffer texture
        gPositionDepth.xyz = FragPos;
        // And store linear depth into gPositionDepth's alpha component
        gPositionDepth.a = LinearizeDepth(gl_FragCoord.z); // Divide by FAR if you need to store depth in range 0.0 - 1.0 (if not using floating point colorbuffer)
        // Also store the per-fragment normals into the gbuffer
        gNormal = normalize(Normal);
        // And the diffuse per-fragment color
        gAlbedoSpec.rgb = vec3(0.95); // Currently all objects have constant albedo color
    }
    

    SSAO VS

    #version 330
    
    layout (location = 0) in vec3 position;
    layout (location = 1) in vec2 texCoords;
    
    out vec2 TexCoords;
    
    void main()
    {
        gl_Position = vec4(position, 1.0f);
        TexCoords = texCoords;
    }
    

    SSAO FS

    #version 330
    
    out float FragColor;
    in vec2 TexCoords;
    
    uniform sampler2D gPositionDepth;
    uniform sampler2D gNormal;
    uniform sampler2D texNoise;
    
    uniform vec3 samples[64];
    
    // parameters (you'd probably want to use them as uniforms to more easily tweak the effect)
    int kernelSize = 64;
    float radius = 1.0;
    
    // tile noise texture over screen based on screen dimensions divided by noise size
    const vec2 noiseScale = vec2(800.0f/4.0f, 600.0f/4.0f); 
    
    uniform mat4 projection;
    
    void main()
    {
        // Get input for SSAO algorithm
        vec3 fragPos = texture(gPositionDepth, TexCoords).xyz;
        vec3 normal = texture(gNormal, TexCoords).rgb;
        vec3 randomVec = texture(texNoise, TexCoords * noiseScale).xyz;
        // Create TBN change-of-basis matrix: from tangent-space to view-space
        vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal));
        vec3 bitangent = cross(normal, tangent);
        mat3 TBN = mat3(tangent, bitangent, normal);
        // Iterate over the sample kernel and calculate occlusion factor
        float occlusion = 0.0;
        for(int i = 0; i < kernelSize; ++i)
        {
            // get sample position
            vec3 sample = TBN * samples[i]; // From tangent to view-space
            sample = fragPos + sample * radius; 
    
            // project sample position (to sample texture) (to get position on screen/texture)
            vec4 offset = vec4(sample, 1.0);
            offset = projection * offset; // from view to clip-space
            offset.xyz /= offset.w; // perspective divide
            offset.xyz = offset.xyz * 0.5 + 0.5; // transform to range 0.0 - 1.0
    
            // get sample depth
            float sampleDepth = -texture(gPositionDepth, offset.xy).w; // Get depth value of kernel sample
    
            // range check & accumulate
            float rangeCheck = smoothstep(0.0, 1.0, radius / abs(fragPos.z - sampleDepth ));
            occlusion += (sampleDepth >= sample.z ? 1.0 : 0.0) * rangeCheck;           
        }
        occlusion = 1.0 - (occlusion / kernelSize);
    
        FragColor = occlusion;
    }
    

    Blur VS

    #version 330
    
    layout (location = 0) in vec3 position;
    layout (location = 1) in vec2 texCoords;
    
    out vec2 TexCoords;
    
    void main()
    {
        gl_Position = vec4(position, 1.0f);
        TexCoords = texCoords;
    }
    

    Blur FS

    #version 330
    
    in vec2 TexCoords;
    
    out float fragColor;
    
    uniform sampler2D ssaoInput;
    const int blurSize = 4; // use size of noise texture (4x4)
    
    void main() 
    {
       vec2 texelSize = 1.0 / vec2(textureSize(ssaoInput, 0));
       float result = 0.0;
       for (int x = 0; x < blurSize; ++x) 
       {
          for (int y = 0; y < blurSize; ++y) 
          {
             vec2 offset = (vec2(-2.0) + vec2(float(x), float(y))) * texelSize;
             result += texture(ssaoInput, TexCoords + offset).r;
          }
       }
    
       fragColor = result / float(blurSize * blurSize);
    }
    

    LightShader VS

    #version 330 core
    
    in vec3 position;
    in vec3 normal;
    in vec2 uv;
    
    uniform vec3 lightPosition;
    
    uniform mat4 mvpMatrix;
    uniform mat4 mvMatrix;
    uniform mat3 normalMatrix;
    uniform mat4 mvlpllMatrix;
    uniform mat4 viewMatrix;
    uniform vec4 spotlightPosition;
    
    smooth out vec3 varyingNormal;
    smooth out vec3 varyingLightDir;
    smooth out vec3 varyingSpotlightDirection;
    smooth out vec2 uv_varyings;
    out vec4 smCoords;
    out vec4 ecPos;
    
    void main(){
    
    	varyingNormal = normalMatrix * normal;
    
    	ecPos = mvMatrix * vec4(position, 1.0);
    
    	varyingLightDir = vec3(lightPosition - ecPos.xyz);
    	//varyingSpotlightDirection = vec3((viewMatrix*spotlightPosition).xyz- ecPos.xyz);
    	varyingSpotlightDirection = vec3((viewMatrix*vec4(position,1)).xyz - spotlightPosition.xyz);
    	varyingSpotlightDirection = normalize(varyingSpotlightDirection);
    	gl_Position = mvpMatrix * vec4(position, 1.0);
    	smCoords = mvlpllMatrix * vec4(position, 1.0);
    	uv_varyings = uv;
    }
    

    LightShader FS

    #version 330 core
    
    layout(location = 0) out vec4 fragColor;
    
    uniform vec4 ambientColor;
    uniform vec4 diffuseColor;
    
    uniform vec4 ambientSpot;
    uniform vec4 diffuseSpot;
    //texture
    uniform sampler2D texture_color;
    uniform sampler2DShadow shadowMap;
    
    in vec3 varyingNormal;
    in vec3 varyingLightDir;
    in vec2 uv_varyings;
    in vec4 smCoords;
    
    //SSAO
    uniform vec2 screenSize;
    uniform sampler2D gAOMap;
    
    //spotlight
    in vec3 varyingSpotlightDirection;
    uniform vec3 spotLightdirection;
    in vec4 ecPos;
    
    uniform int transparent;
    
    vec2 CalcScreenTexCoord()
    {
        return gl_FragCoord.xy / screenSize;
    }
    
    void main()
    {
    	float shadowMult = textureProj(shadowMap, smCoords);
    
    	float diff = shadowMult * max(0.0, dot(normalize(varyingNormal), normalize(varyingLightDir)));
    	vec4 lightColor = diff * diffuseColor;
    
    	//Spotlight
    
    	float dist = length(normalize(varyingSpotlightDirection));
    	float NdotL = max(dot(normalize(varyingNormal), normalize(-varyingSpotlightDirection)), 0.0);
    
    	float spotEffect  = dot(normalize(spotLightdirection), normalize(varyingSpotlightDirection));
    	float cosTheta = cos(radians(1.0)); //inner cone
    	float cosPhi = cos(radians(3.0)); //outer cone
    
    	vec4 color = vec4(0, 0.0, 0.0, 1.0);
    
    	if (spotEffect > cosTheta) 
    	{
    
    		if(NdotL > 0.0)
    		{
    			color += diffuseSpot * diffuseColor * NdotL;	
    
    			vec3 E = normalize(ecPos.xyz);
    			vec3 R = reflect(-varyingSpotlightDirection, varyingNormal);
    
    			float specular = pow( max(dot(R, E), 0.0), 128 );
    
    			color += specular;	
    		}
    	}
    	else if( spotEffect > cosPhi )
    	{
    		float falloff = (spotEffect - cosPhi) / (cosTheta - cosPhi);
    
    		if(NdotL > 0.0)
    		{
    			color += diffuseSpot * diffuseColor * NdotL * falloff;	
    
    			vec3 E = normalize(ecPos.xyz);
    			vec3 R = reflect(-varyingSpotlightDirection, varyingNormal);
    
    			float specular = pow( max(dot(R, E), 0.0), 128 );
    
    			color += specular * falloff;	
    		}
    	}
    	lightColor += color;
    
    	//if(shadowMult == 1){
    
    		//SSAO
    		float AmbientOcclusion = texture(gAOMap, uv_varyings).r;
    		vec4 ambient = vec4(0.3 * AmbientOcclusion); // <-- this is where we use ambient occlusion
    		lightColor += ambient;
    
    		lightColor += ambientColor * texture(texture_color, uv_varyings.xy);
    
    		vec3 reflection = normalize(reflect(-normalize(varyingLightDir), normalize(varyingNormal)));
    		float spec = max(0.0, dot(normalize(varyingNormal), reflection));	
    
    		if(diff!=0){
    			float fspec = pow(spec, 264.0);
    			lightColor.rgb += vec3(fspec, fspec, fspec);
    		}
    
    		fragColor += lightColor;
    
    	/*}
    	else{
    
    		fragColor += lightColor;
    		fragColor *= texture(texture_color, uv_varyings.xy);
    	*/
    
    	if(transparent == 1){
    		fragColor.a = 0.3;
    	}
    
    }
    

    Ich hab auch mit CodeXL schon herumgespielt um herauszufinden wie denn die Texturen vom SSAO der er mir generiert aussehen, ich hoffe die Links funktionieren.
    Die Texturen von geo_posdepth und geo_texture sehen eigentlich gut aus, hingegen ist geo_normal dort wo das Spielfeld ist komplett weiß und der geo_depth renderBuffer ist sowieso komplett schwarz..
    Beim geo_normal, selbst wenn ich in depthProgramHandle(..) "normal" aktiv habe, im CodeXL ändert sich jedoch nichts.

    http://i59.tinypic.com/33yl6xd.png
    http://i59.tinypic.com/6yi63k.png
    http://i60.tinypic.com/281hicg.png

    Ich wäre wirklich über jede Art von Hilfe dankbar und vielen Dank!

    LG schmidi87


Anmelden zum Antworten