title: SSAO sampling from depth map causing pixel flicker issue
body: <p>I was trying to implement the Crytek SSAO technique based on a shader shown in the Appendix of the following paper:</p>
  <p>Shader from paper:
  <a href="https://i.stack.imgur.com/py4tr.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/py4tr.png" alt="enter image description here" /></a></p>
  <p>However, when implementing and running the shader, it kept giving me this graining look and I cannot seem to identify what might have caused this particular issue.</p>
  <p>My implementation of the shader:</p>
  <pre><code>#version 450
  
  layout(binding = 3) uniform sampler2D texNoise;
  layout(binding = 6) uniform sampler2D depthMap;
  
  layout(location = 0) in vec3 fragColor;
  layout(location = 1) in vec2 uvCoords;
  
  
  layout(binding = 5) uniform UniformBufferObject {
      mat4 model;
      mat4 view;
      mat4 proj;
      float time;
  }camera;
  
  
  layout(binding = 4) uniform KernelSample {
      vec3 samples[64];
      mat4 projection;
      vec4 camera_eye;
      vec4 camera_direction;
      float z_far;
  }kernelsamples;
  
  int kernelSize = 64;
  
  layout(location = 0) out vec4 outColor;
  
  vec4 ambient_occlusion;
  
  float ec_depth(in vec2 tc)
  {
      float buffer_z = texture(depthMap, tc).x;
      return camera.proj[3][2] / (-2.0 * buffer_z + 1.0 - camera.proj[2][2]);
  }
  
  const vec2 window = vec2(2560.0, 1440.0);
  
  void main()
  
  {
  
      vec2 tc_depths = gl_FragCoord.xy / uvCoords;
  
      float ec_depth_negated = -ec_depth(tc_depths);
      vec3 wc_positions = kernelsamples.camera_eye.xyz + kernelsample.camera_direction * ec_depth_negated / kernelsamples.z_far;
  
      ambient_occlusion.a = 0.0f;
      const float radius = 10.0f;
      const int samples = 64;
  
      float projection_scale_xy = 1.0 / ec_depth_negated;
      float projection_scale_z = 100.0 / kernelsamples.z_far * projection_scale_xy;
  
      float scene_depth = texture(depthMap, tc_depths).x;
  
      vec2 inverted_random_texture_size = 1.0 / vec2(textureSize(texNoise, 0));
      vec2 tc_random_texture = gl_FragCoord.xy * inverted_random_texture_size;
  
      vec3 random_direction = texture(texNoise, tc_random_texture).xyz;
      random_direction = normalize(random_direction * 2.0 - 1.0);
  
      for(int i = 0; i &lt; samples; i++)
      {
          vec3 sample_random_direction = texture(texNoise, vec2(float(i) * 
          inverted_random_texture_size.x, float(i / textureSize(texNoise, 0).x) *
          inverted_random_texture_size.y)).xyz;
          sample_random_direction = sample_random_direction * 2.0 - 1.0;
          sample_random_direction = reflect(sample_random_direction, random_direction);
  
          vec3 tc_sample_pos = vec3(tc_depths.xy, scene_depth) 
                   + vec3(sample_random_direction.xy * projection_scale_xy,
                       sample_random_direction.z * scene_depth * projection_scale_z) * radius;
  
          float sample_depth = texture(depthMap, tc_sample_pos.xy).x;
  
          ambient_occlusion.a += float(sample_depth &gt; tc_sample_pos.z);
      }
  
      ambient_occlusion.a /= float(kernelSize);
  
      outColor = ambient_occlusion;
  
  }
  </code></pre>
  <p><strong>C++</strong></p>
  <pre><code>// Projection
   ubo.proj = glm::perspective(glm::radians(45.0f), swapChainExtent.width / 
  (float)swapChainExtent.height, 0.1f, 1000.0f);
  ubo.proj[1][1] *= -1;
  
  KernelSample ks{}; 
  .....
  ks.cameraEye = glm::vec4(cameraPosition, 0.0f);
  ks.cameraDirection = glm::vec4(cameraPosition + cameraCenter, 1.0f);
  </code></pre>
  <p><strong>RenderPass</strong></p>
  <pre><code>VkAttachmentDescription colorAttachment{};
  colorAttachment.format = VK_FORMAT_R16_SFLOAT;
  colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
  colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
  colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
  colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
  colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
  colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
  colorAttachment.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
  
  VkAttachmentDescription depthAttachment = {};
  depthAttachment.format = format;
  depthAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
  depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
  depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
  depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
  depthAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
  depthAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
  depthAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
  
  VkAttachmentReference depthAttachmentRef{};
  depthAttachmentRef.attachment = 1;
  depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
  
  VkAttachmentReference colorAttatchmentRef{};
  colorAttatchmentRef.attachment = 0;
  colorAttatchmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
  
  VkSubpassDescription subpass{};
  subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
  subpass.colorAttachmentCount = 1;
  subpass.pColorAttachments = &amp;colorAttatchmentRef;
  subpass.pDepthStencilAttachment = &amp;depthAttachmentRef;
  
  VkSubpassDependency dependency{};
  dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
  dependency.dstSubpass = 0;
  dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
  dependency.srcAccessMask = 0;
  dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
  dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
  
  std::array&lt;VkAttachmentDescription, 2&gt; attachments = { colorAttachment, depthAttachment };
  
  VkRenderPassCreateInfo renderPassInfo{};
  renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
  renderPassInfo.attachmentCount = static_cast&lt;uint32_t&gt;(attachments.size());
  renderPassInfo.pAttachments = attachments.data();
  renderPassInfo.subpassCount = 1;
  renderPassInfo.pSubpasses = &amp;subpass;
  renderPassInfo.dependencyCount = 1;
  renderPassInfo.pDependencies = &amp;dependency;
  </code></pre>
  <p><strong>Result</strong>
  <a href="https://i.stack.imgur.com/elFzT.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/elFzT.png" alt="enter image description here" /></a></p>
  <p><strong>SSAO shader output</strong>
  <a href="https://i.stack.imgur.com/RXfNY.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/RXfNY.png" alt="enter image description here" /></a></p>