<p>I had the same issue bit ago.</p>
<p>Short answer -
you need to include
<code>#define GLM_FORCE_DEPTH_ZERO_TO_ONE</code> before you import glm.</p>
<p>Long Answer -</p>
<p>In the <a href="https://vulkan-tutorial.com/" rel="nofollow noreferrer">tutorial series</a>, we set</p>
<pre><code>viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;
</code></pre>
<p>Unless you include the macro, when you create a <code>glm::ortho(2.0f*-aspectRatio, 2.0f*aspectRatio, -2.0f, 2.0f, -1.0f, time/1.0f)</code>, the constructor defined in glm\ext\matrix_clip_space.inl as -</p>
<pre><code>    template&lt;typename T&gt;
    GLM_FUNC_QUALIFIER mat&lt;4, 4, T, defaultp&gt; ortho(T left, T right, T bottom, T top, T zNear, T zFar)
    {
#       if GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO
            return orthoLH_ZO(left, right, bottom, top, zNear, zFar);
#       elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO
            return orthoLH_NO(left, right, bottom, top, zNear, zFar);
#       elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO
            return orthoRH_ZO(left, right, bottom, top, zNear, zFar);
#       elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO
            return orthoRH_NO(left, right, bottom, top, zNear, zFar);
#       endif
    }
</code></pre>
<p>is called and it will choose the last branch, GLM_CLIP_CONTROL_RH_<strong>NO</strong>. Here, the difference between NO and ZO is:</p>
<ul>
<li>ZO (Zero to One): Depth values are normalized between 0 and 1.</li>
<li>NO (Negative One to One): Depth values are normalized between -1 and 1.</li>
</ul>
<p>Since the minDepth is set to 0.0f, clearly, we need the values to be normalized between 0 and 1, so we need to switch to ZO. To do that, we need to define the <code>GLM_FORCE_DEPTH_ZERO_TO_ONE </code> macro, which, as it suggests, forces GLM to normalize the depth between 0 and 1.</p>
<p>Alternatively, you can also change viewport.minDepth to -1 but if you set up the validation layers correctly, they'll scream at you that you need to enable an extension to do that. I did not delve that deep into it, but you could try.</p>

CC BY-SA 4.0
2024-07-12T17:31:32.203Z
2024-07-12T17:31:32.203Z
Kakuking
<p>I am following along <a href="https://vulkan-tutorial.com/" rel="nofollow noreferrer">https://vulkan-tutorial.com/</a> and just finished the chapter on Uniform Buffers. I tried to change the projection matrix to see the outcome, however, when I change the zFar value in glm::ortho, it clips unexpectedly.</p>
<ul>
<li>When zFar is lesser than the first vertex, nothing shows as expected</li>
<li>When zFar is more than the first vertex, the quad starts showing up, as expected</li>
<li>However, as zFar increases, the quad starts clipping, <strong>from the bottom up!</strong></li>
</ul>
<p>I checked by altering zFar in the call to glm::perspective as well, the behaviour does not occur. Here is the code:</p>
<pre><code>void updateUniformBuffer(uint32_t currentImage){
        static auto startTime = std::chrono::high_resolution_clock::now();

        auto currentTime = std::chrono::high_resolution_clock::now();
        float time = std::chrono::duration&lt;float, std::chrono::seconds::period&gt;(currentTime - startTime).count();

        UniformBufferObject ubo{};
        ubo.model = glm::mat4(1.0f);

        ubo.view = glm::lookAt(glm::vec3(0.0f, 2.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));

        // ubo.proj = glm::perspective(glm::radians(45.0f), swapChainExtent.width / (float) swapChainExtent.height, 0.1f, time/1.0f);

        float aspectRatio = swapChainExtent.width / (float) swapChainExtent.height;
        ubo.proj = glm::ortho(2.0f*-aspectRatio, 2.0f*aspectRatio, -2.0f, 2.0f, -1.0f, time/1.0f);
        ubo.proj[1][1] *= -1;

        memcpy(uniformBuffersMapped[currentImage], &amp;ubo, sizeof(ubo));
    }
</code></pre>
<p>Please help me out here, sorry if a similar question has been answered before, but my search came up empty ;-;</p>

<rendering><vulkan><glm>
Vulkan+glm orthographic projection clipping unexpectedly
Vulkan_Learner
# Vulkan+glm orthographic projection clipping unexpectedly

(Asked by: username_0 on 2024-07-12)

I am following along <https://vulkan-tutorial.com/> and just finished the chapter on Uniform Buffers. I tried to change the projection matrix to see the outcome, however, when I change the zFar value in glm::ortho, it clips unexpectedly.

* When zFar is lesser than the first vertex, nothing shows as expected
* When zFar is more than the first vertex, the quad starts showing up, as expected
* However, as zFar increases, the quad starts clipping, **from the bottom up!**

I checked by altering zFar in the call to glm::perspective as well, the behaviour does not occur. Here is the code:

```
void updateUniformBuffer(uint32_t currentImage){
        static auto startTime = std::chrono::high_resolution_clock::now();

        auto currentTime = std::chrono::high_resolution_clock::now();
        float time = std::chrono::duration<float, std::chrono::seconds::period>(currentTime - startTime).count();

        UniformBufferObject ubo{};
        ubo.model = glm::mat4(1.0f);

        ubo.view = glm::lookAt(glm::vec3(0.0f, 2.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));

        // ubo.proj = glm::perspective(glm::radians(45.0f), swapChainExtent.width / (float) swapChainExtent.height, 0.1f, time/1.0f);

        float aspectRatio = swapChainExtent.width / (float) swapChainExtent.height;
        ubo.proj = glm::ortho(2.0f*-aspectRatio, 2.0f*aspectRatio, -2.0f, 2.0f, -1.0f, time/1.0f);
        ubo.proj[1][1] *= -1;

        memcpy(uniformBuffersMapped[currentImage], &ubo, sizeof(ubo));
    }

```

Please help me out here, sorry if a similar question has been answered before, but my search came up empty ;-;

**Tags:** rendering, vulkan, glm


---

## 1 answers

### Answer by username_1 on 2024-07-12. Score: 1

I had the same issue bit ago.

Short answer -
you need to include
`#define GLM_FORCE_DEPTH_ZERO_TO_ONE` before you import glm.

Long Answer -

In the [tutorial series](https://vulkan-tutorial.com/), we set

```
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;

```

Unless you include the macro, when you create a `glm::ortho(2.0f*-aspectRatio, 2.0f*aspectRatio, -2.0f, 2.0f, -1.0f, time/1.0f)`, the constructor defined in glm\ext\matrix\_clip\_space.inl as -

```
    template<typename T>
    GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> ortho(T left, T right, T bottom, T top, T zNear, T zFar)
    {
#       if GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO
            return orthoLH_ZO(left, right, bottom, top, zNear, zFar);
#       elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO
            return orthoLH_NO(left, right, bottom, top, zNear, zFar);
#       elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO
            return orthoRH_ZO(left, right, bottom, top, zNear, zFar);
#       elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO
            return orthoRH_NO(left, right, bottom, top, zNear, zFar);
#       endif
    }

```

is called and it will choose the last branch, GLM\_CLIP\_CONTROL\_RH\_**NO**. Here, the difference between NO and ZO is:

* ZO (Zero to One): Depth values are normalized between 0 and 1.
* NO (Negative One to One): Depth values are normalized between -1 and 1.

Since the minDepth is set to 0.0f, clearly, we need the values to be normalized between 0 and 1, so we need to switch to ZO. To do that, we need to define the `GLM_FORCE_DEPTH_ZERO_TO_ONE`  macro, which, as it suggests, forces GLM to normalize the depth between 0 and 1.

Alternatively, you can also change viewport.minDepth to -1 but if you set up the validation layers correctly, they'll scream at you that you need to enable an extension to do that. I did not delve that deep into it, but you could try.


---

