Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Generation of FBOs
- m_ssaoFBO = new FBO();
- m_ssaoBlurFBO = new FBO();
- m_ssaoFBO->bind();
- glGenTextures(1, &m_ssaoColorBuffer);
- glBindTexture(GL_TEXTURE_2D, m_ssaoColorBuffer);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, GAME_WIN_W, GAME_WIN_H, 0, GL_RED, GL_FLOAT, nullptr);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- m_ssaoFBO->storeTexture2D(GL_COLOR_ATTACHMENT0, m_ssaoColorBuffer, 0);
- m_ssaoFBO->unbind();
- m_ssaoBlurFBO->bind();
- glGenTextures(1, &m_ssaoColorBufferBlur);
- glBindTexture(GL_TEXTURE_2D, m_ssaoColorBufferBlur);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, GAME_WIN_W, GAME_WIN_H, 0, GL_RED, GL_FLOAT, nullptr);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- m_ssaoBlurFBO->storeTexture2D(GL_COLOR_ATTACHMENT0, m_ssaoColorBufferBlur, 0);
- m_ssaoBlurFBO->unbind();
- Noise and kernels
- std::uniform_real_distribution<GLfloat> randomFloats(0.0, 1.0);
- std::default_random_engine generator;
- for (unsigned int i = 0; i < 64; ++i) {
- glm::vec3 sample(randomFloats(generator) * 2.0 - 1.0, randomFloats(generator) * 2.0 - 1.0,
- randomFloats(generator));
- sample = glm::normalize(sample);
- sample *= randomFloats(generator);
- float scale = float(i) / 64.0f;
- scale = lerp(0.1f, 1.0f, scale * scale);
- sample *= scale;
- m_ssaoKernel.push_back(sample);
- }
- for (unsigned int i = 0; i < 16; i++) {
- glm::vec3 noise(randomFloats(generator) * 2.0 - 1.0, randomFloats(generator) * 2.0 - 1.0, 0.0f);
- m_ssaoNoise.push_back(noise);
- }
- glGenTextures(1, &m_noiseTexture);
- glBindTexture(GL_TEXTURE_2D, m_noiseTexture);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 4, 4, 0, GL_RGB, GL_FLOAT, &m_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);
- SSAO pass with blur immediately after geometry pass
- m_gBuffer->unbind();
- m_ssaoFBO->bind();
- glClear(GL_COLOR_BUFFER_BIT);
- m_ssaoShader->use();
- for (unsigned int i = 0; i < 64; ++i) {
- m_ssaoShader->uniform3f("samples[" + std::to_string(i) + "]", m_ssaoKernel[i].x, m_ssaoKernel[i].y,
- m_ssaoKernel[i].z);
- }
- m_ssaoShader->uniformMatrix4fv(glProjectionMatrixUniform, value_ptr(m_projectionMatrix), false);
- m_ssaoShader->uniform1i("gPosition", 0);
- m_ssaoShader->uniform1i("gNormal", 1);
- m_ssaoShader->uniform1i("tex_noise", 2);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, m_gPosition);
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, m_gNormal);
- glActiveTexture(GL_TEXTURE2);
- glBindTexture(GL_TEXTURE_2D, m_noiseTexture);
- renderQuad();
- m_ssaoFBO->unbind();
- m_ssaoBlurFBO->bind();
- glClear(GL_COLOR_BUFFER_BIT);
- m_ssaoBlurShader->use();
- m_ssaoBlurShader->uniform1i("ssao_input", 0);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, m_ssaoColorBuffer);
- renderQuad();
- m_ssaoBlurFBO->unbind();
- Here comes the lightning pass
- SSAO fragment shader
- #version 150
- out float out_color;
- in vec2 frag_uv;
- uniform sampler2D gPosition;
- uniform sampler2D gNormal;
- uniform sampler2D tex_noise;
- uniform vec3 samples[64];
- uniform mat4 projection_matrix;
- int kernelSize = 64;
- float radius = 0.5;
- float bias = 0.025;
- const vec2 noiseScale = vec2(800.0 / 4.0, 600.0 / 4.0);
- void main()
- {
- vec3 fragPos = texture(gPosition, frag_uv).xyz;
- vec3 normal = normalize(texture(gNormal, frag_uv).rgb);
- vec3 randomVec = normalize(texture(tex_noise, frag_uv * noiseScale).xyz);
- vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal));
- vec3 bitangent = cross(normal, tangent);
- mat3 TBN = mat3(tangent, bitangent, normal);
- float occlusion = 0.0;
- for (int i = 0; i < kernelSize; ++i)
- {
- vec3 samplePos = TBN * samples[i];
- samplePos = fragPos + samplePos * radius;
- vec4 offset = vec4(samplePos, 1.0);
- offset = projection_matrix * offset;
- offset.xyz /= offset.w;
- offset.xyz = offset.xyz * 0.5 + 0.5;
- float sampleDepth = texture(gPosition, offset.xy).z;
- float rangeCheck = smoothstep(0.0, 1.0, radius / abs(fragPos.z - sampleDepth));
- occlusion += (sampleDepth >= samplePos.z + bias ? 1.0 : 0.0) * rangeCheck;
- }
- occlusion = 1.0 - (occlusion / kernelSize);
- out_color = occlusion;
- }
- SSAO blur fragment shader
- #version 150
- out float out_color;
- in vec2 frag_uv;
- uniform sampler2D ssao_input;
- void main()
- {
- vec2 texelSize = 1.0 / vec2(textureSize(ssao_input, 0));
- float result = 0.0;
- for (int x = -2; x < 2; ++x)
- {
- for (int y = -2; y < 2; ++y)
- {
- vec2 offset = vec2(float(x), float(y)) * texelSize;
- result += texture(ssao_input, frag_uv + offset).r;
- }
- }
- out_color = result / (4.0 * 4.0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement