Screen Space Reflection Implemented in Vulkan
Introduction
An important part of real-time rendering is computing indirect lighting. There are many ways to implement indirect lighting, and screen space reflection is one of them. I will try to implement screen space reflection and add it to my renderer.
Principle

The principle is simple ray marching in view space.
For any point ( p ) on screen:
- According to the camera direction ( L ) and the normal ( N ) of the current point ( p ), compute the reflection direction ( RDir = reflect(L,N) ).
- Starting from point ( p ), march along the reflected direction: ( rayPos = p + step * RDir ), where
stepis the marching length. - For each step, compare ( rayPos ) with the screen-space ( z ) value corresponding to ( rayPos.xy ). If the difference is smaller than a threshold ( eps ), an intersection occurs, and that point’s color is used as the reflection value for ( p ). Otherwise, return to step 2 and continue the loop.
The principle is very simple, but the direct result is not ideal. It needs attenuation based on ray-marching distance, roughness at the sample point, and other factors. Since this is also an iterative marching algorithm, the time cost is large, so acceleration techniques such as binary search and Hi-Z need to be considered.
Implementation
- The most primitive SSR result I first implemented is shown below. The step size is 0.2.

- Adjusting the step size can improve the result. When the step size is changed to 0.02, the result looks better, but the performance cost becomes high.

- Adding attenuation based on marching distance improves the result further. The attenuation formula I used is ( weight = e^{-distance * attenuation} ), where ( distance ) is the ray-marching length and ( attenuation ) is the attenuation coefficient.

- I tried using binary search to find the intersection point, but the improvement did not seem obvious.
- I tried determining attenuation based on metallic and roughness values, applying another attenuation by the coefficient ( metal * rough ). I changed to another scene here. The floor is non-metallic with roughness 0.5, and most of the model is metallic. From the image, some color bleeding can be seen.
| ssr_3 | ssr_4 |
|---|---|
| Rendering result | SSR texture |