<p>Thanks for your help, I fixed it by changing the way i am computing the depth :)</p>

<pre><code>const double z_b = texture(depthBuffer, texcoord).x;
const vec4 clipSpacePosition = vec4(texcoord * 2.0 - 1.0, z_b, 1.0);
vec4 viewSpacePosition = cam.projInverse * clipSpacePosition;
viewSpacePosition /= viewSpacePosition.w;
float depth = length(viewSpacePosition.xyz);
</code></pre>

CC BY-SA 4.0
2020-01-13T09:00:10.583Z
2020-01-13T09:00:10.583Z
antaalt
<p>I'm trying to implement an hybrid renderer based on Vulkan extension VK_NV_ray_tracing. Basically, the rasterizer compute the albedo and depth map of the scene. Then I try to compute the distance from the depth buffer so that I can send a shadow ray from a raygen program to compute direct lighting. I linearize the depth to obtain a correct distance value from the depth buffer. What I am doing is this:</p>

<pre><code>const vec2 texcoord = vec2(gl_LaunchIDNV) / vec2(gl_LaunchSizeNV);
const double z_b = texture(depthBuffer, texcoord).x;
const double depth = (2.0 * near * far) / (far + near - z_b * (far - near));
</code></pre>

<p>I am then computing the ray position and direction</p>

<pre><code>const vec2 pixelCenter = vec2(gl_LaunchIDNV.xy) + vec2(0.5);
const vec2 inUV = pixelCenter / vec2(gl_LaunchSizeNV.xy);
const vec2 d = inUV * 2.0 - 1.0;
const vec4 camFront  = cam.viewInverse * vec4(0, 0, 1, 0);
const vec4 camPos    = cam.viewInverse * vec4(0, 0, 0, 1);
const vec4 camTarget = cam.projInverse * vec4(d.x, d.y, 1, 1);
const vec4 camDir    = cam.viewInverse * vec4(normalize(camTarget.xyz), 0);
</code></pre>

<p>And the final ray position is then set using the depth I just computed.</p>

<pre><code>const vec3 pos = camPos.xyz + camDir.xyz * float(depth);
</code></pre>

<p>The problem here is that the depth seems incorrect because shadows tend to curve at the edges of the screen and do not fit the geometry. 
<a href="https://i.sstatic.net/CgIwK.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/CgIwK.png" alt="bended shadows"></a>
I think this might be because of the depth buffer value that does not represent the distance from the origin of the camera but from the near plane, which would explain the problem, but I am not sure of that.</p>

<p>Any idea?</p>

CC BY-SA 4.0
2020-01-08T21:44:52.780Z
That sounds logical, have you tried taking the pixel position in screenspace and converting that to world space.  You would use that in place of the values in const vec4 camPos    = cam.viewInverse * vec4(d.x, d.y, 0, 1);.  I believe that is the correct value.
ErnieDingo
CC BY-SA 4.0
2020-01-09T09:22:31.483Z
This is called from a raygen program, I don't think I have access to the pixel position in screenspace :(
antaalt
<raytracing><glsl><vulkan><shadow>
Retrieve real distance from depth buffer for shadow ray (vulkan hybrid rendering)
antaalt
# Retrieve real distance from depth buffer for shadow ray (vulkan hybrid rendering)

(Asked by: username_0 on 2020-01-07)

I'm trying to implement an hybrid renderer based on Vulkan extension VK\_NV\_ray\_tracing. Basically, the rasterizer compute the albedo and depth map of the scene. Then I try to compute the distance from the depth buffer so that I can send a shadow ray from a raygen program to compute direct lighting. I linearize the depth to obtain a correct distance value from the depth buffer. What I am doing is this:

```
const vec2 texcoord = vec2(gl_LaunchIDNV) / vec2(gl_LaunchSizeNV);
const double z_b = texture(depthBuffer, texcoord).x;
const double depth = (2.0 * near * far) / (far + near - z_b * (far - near));

```

I am then computing the ray position and direction

```
const vec2 pixelCenter = vec2(gl_LaunchIDNV.xy) + vec2(0.5);
const vec2 inUV = pixelCenter / vec2(gl_LaunchSizeNV.xy);
const vec2 d = inUV * 2.0 - 1.0;
const vec4 camFront  = cam.viewInverse * vec4(0, 0, 1, 0);
const vec4 camPos    = cam.viewInverse * vec4(0, 0, 0, 1);
const vec4 camTarget = cam.projInverse * vec4(d.x, d.y, 1, 1);
const vec4 camDir    = cam.viewInverse * vec4(normalize(camTarget.xyz), 0);

```

And the final ray position is then set using the depth I just computed.

```
const vec3 pos = camPos.xyz + camDir.xyz * float(depth);

```

The problem here is that the depth seems incorrect because shadows tend to curve at the edges of the screen and do not fit the geometry.
[![bended shadows](https://i.sstatic.net/CgIwK.png)](https://i.sstatic.net/CgIwK.png)
I think this might be because of the depth buffer value that does not represent the distance from the origin of the camera but from the near plane, which would explain the problem, but I am not sure of that.

Any idea?

**Tags:** raytracing, glsl, vulkan, shadow

> **Comments:**
> **username_1**: That sounds logical, have you tried taking the pixel position in screenspace and converting that to world space.  You would use that in place of the values in const vec4 camPos    = cam.viewInverse * vec4(d.x, d.y, 0, 1);.  I believe that is the correct value.  
> **username_0**: This is called from a raygen program, I don't think I have access to the pixel position in screenspace :(  

---

## 1 answers

### Answer by username_0 on 2020-01-13. Score: 1

Thanks for your help, I fixed it by changing the way i am computing the depth :)

```
const double z_b = texture(depthBuffer, texcoord).x;
const vec4 clipSpacePosition = vec4(texcoord * 2.0 - 1.0, z_b, 1.0);
vec4 viewSpacePosition = cam.projInverse * clipSpacePosition;
viewSpacePosition /= viewSpacePosition.w;
float depth = length(viewSpacePosition.xyz);

```


---

