Advertisement
Guest User

SSAO

a guest
Oct 10th, 2024
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.39 KB | Source Code | 0 0
  1. Generation of FBOs
  2.  
  3.     m_ssaoFBO = new FBO();
  4.     m_ssaoBlurFBO = new FBO();
  5.  
  6.     m_ssaoFBO->bind();
  7.     glGenTextures(1, &m_ssaoColorBuffer);
  8.     glBindTexture(GL_TEXTURE_2D, m_ssaoColorBuffer);
  9.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, GAME_WIN_W, GAME_WIN_H, 0, GL_RED, GL_FLOAT, nullptr);
  10.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  11.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  12.     m_ssaoFBO->storeTexture2D(GL_COLOR_ATTACHMENT0, m_ssaoColorBuffer, 0);
  13.     m_ssaoFBO->unbind();
  14.  
  15.     m_ssaoBlurFBO->bind();
  16.     glGenTextures(1, &m_ssaoColorBufferBlur);
  17.     glBindTexture(GL_TEXTURE_2D, m_ssaoColorBufferBlur);
  18.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, GAME_WIN_W, GAME_WIN_H, 0, GL_RED, GL_FLOAT, nullptr);
  19.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  20.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  21.     m_ssaoBlurFBO->storeTexture2D(GL_COLOR_ATTACHMENT0, m_ssaoColorBufferBlur, 0);
  22.     m_ssaoBlurFBO->unbind();
  23.  
  24. Noise and kernels
  25.  
  26.     std::uniform_real_distribution<GLfloat> randomFloats(0.0, 1.0);
  27.     std::default_random_engine generator;
  28.  
  29.     for (unsigned int i = 0; i < 64; ++i) {
  30.         glm::vec3 sample(randomFloats(generator) * 2.0 - 1.0, randomFloats(generator) * 2.0 - 1.0,
  31.                          randomFloats(generator));
  32.         sample = glm::normalize(sample);
  33.         sample *= randomFloats(generator);
  34.         float scale = float(i) / 64.0f;
  35.  
  36.         scale = lerp(0.1f, 1.0f, scale * scale);
  37.         sample *= scale;
  38.         m_ssaoKernel.push_back(sample);
  39.     }
  40.  
  41.     for (unsigned int i = 0; i < 16; i++) {
  42.         glm::vec3 noise(randomFloats(generator) * 2.0 - 1.0, randomFloats(generator) * 2.0 - 1.0, 0.0f);
  43.         m_ssaoNoise.push_back(noise);
  44.     }
  45.  
  46.     glGenTextures(1, &m_noiseTexture);
  47.     glBindTexture(GL_TEXTURE_2D, m_noiseTexture);
  48.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 4, 4, 0, GL_RGB, GL_FLOAT, &m_ssaoNoise[0]);
  49.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  50.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  51.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  52.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  53.  
  54. SSAO pass with blur immediately after geometry pass
  55.  
  56.     m_gBuffer->unbind();
  57.  
  58.     m_ssaoFBO->bind();
  59.     glClear(GL_COLOR_BUFFER_BIT);
  60.     m_ssaoShader->use();
  61.  
  62.     for (unsigned int i = 0; i < 64; ++i) {
  63.         m_ssaoShader->uniform3f("samples[" + std::to_string(i) + "]", m_ssaoKernel[i].x, m_ssaoKernel[i].y,
  64.                                 m_ssaoKernel[i].z);
  65.     }
  66.  
  67.     m_ssaoShader->uniformMatrix4fv(glProjectionMatrixUniform, value_ptr(m_projectionMatrix), false);
  68.  
  69.     m_ssaoShader->uniform1i("gPosition", 0);
  70.     m_ssaoShader->uniform1i("gNormal", 1);
  71.     m_ssaoShader->uniform1i("tex_noise", 2);
  72.  
  73.     glActiveTexture(GL_TEXTURE0);
  74.     glBindTexture(GL_TEXTURE_2D, m_gPosition);
  75.  
  76.     glActiveTexture(GL_TEXTURE1);
  77.     glBindTexture(GL_TEXTURE_2D, m_gNormal);
  78.  
  79.     glActiveTexture(GL_TEXTURE2);
  80.     glBindTexture(GL_TEXTURE_2D, m_noiseTexture);
  81.  
  82.     renderQuad();
  83.  
  84.     m_ssaoFBO->unbind();
  85.  
  86.     m_ssaoBlurFBO->bind();
  87.     glClear(GL_COLOR_BUFFER_BIT);
  88.     m_ssaoBlurShader->use();
  89.  
  90.     m_ssaoBlurShader->uniform1i("ssao_input", 0);
  91.     glActiveTexture(GL_TEXTURE0);
  92.     glBindTexture(GL_TEXTURE_2D, m_ssaoColorBuffer);
  93.  
  94.     renderQuad();
  95.  
  96.     m_ssaoBlurFBO->unbind();
  97.  
  98. Here comes the lightning pass
  99.  
  100. SSAO fragment shader
  101.  
  102. #version 150
  103.  
  104. out float out_color;
  105.  
  106. in vec2 frag_uv;
  107.  
  108. uniform sampler2D gPosition;
  109. uniform sampler2D gNormal;
  110. uniform sampler2D tex_noise;
  111.  
  112. uniform vec3 samples[64];
  113. uniform mat4 projection_matrix;
  114.  
  115. int kernelSize = 64;
  116. float radius = 0.5;
  117. float bias = 0.025;
  118.  
  119. const vec2 noiseScale = vec2(800.0 / 4.0, 600.0 / 4.0);
  120.  
  121. void main()
  122. {
  123.     vec3 fragPos = texture(gPosition, frag_uv).xyz;
  124.     vec3 normal = normalize(texture(gNormal, frag_uv).rgb);
  125.     vec3 randomVec = normalize(texture(tex_noise, frag_uv * noiseScale).xyz);
  126.  
  127.     vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal));
  128.     vec3 bitangent = cross(normal, tangent);
  129.     mat3 TBN = mat3(tangent, bitangent, normal);
  130.  
  131.     float occlusion = 0.0;
  132.     for (int i = 0; i < kernelSize; ++i)
  133.     {
  134.         vec3 samplePos = TBN * samples[i];
  135.         samplePos = fragPos + samplePos * radius;
  136.  
  137.         vec4 offset = vec4(samplePos, 1.0);
  138.         offset = projection_matrix * offset;
  139.         offset.xyz /= offset.w;
  140.         offset.xyz = offset.xyz * 0.5 + 0.5;
  141.  
  142.         float sampleDepth = texture(gPosition, offset.xy).z;
  143.  
  144.         float rangeCheck = smoothstep(0.0, 1.0, radius / abs(fragPos.z - sampleDepth));
  145.         occlusion += (sampleDepth >= samplePos.z + bias ? 1.0 : 0.0) * rangeCheck;
  146.     }
  147.  
  148.     occlusion = 1.0 - (occlusion / kernelSize);
  149.     out_color = occlusion;
  150. }
  151.  
  152. SSAO blur fragment shader
  153.  
  154. #version 150
  155.  
  156. out float out_color;
  157.  
  158. in vec2 frag_uv;
  159.  
  160. uniform sampler2D ssao_input;
  161.  
  162. void main()
  163. {
  164.     vec2 texelSize = 1.0 / vec2(textureSize(ssao_input, 0));
  165.     float result = 0.0;
  166.     for (int x = -2; x < 2; ++x)
  167.     {
  168.         for (int y = -2; y < 2; ++y)
  169.         {
  170.             vec2 offset = vec2(float(x), float(y)) * texelSize;
  171.             result += texture(ssao_input, frag_uv + offset).r;
  172.         }
  173.     }
  174.  
  175.     out_color = result / (4.0 * 4.0);
  176. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement