0
\$\begingroup\$

**Solved!** Special thanks to comments from Maximus Minimus and Jherico. Scroll down for the solution made in the shader.

I am working on a vulkan renderer in rust using the ash crate. I would like to keep a z-up world orientation as all the 3d tools I've used use this orientation and I would like to be consistent in that workflow.

When positioning my view in this orientation I haven't been able to get the skybox in the proper orientation. I've tried exporting a cube in blender with z-up coordinates. That just left me with a strange triangle pattern of a skybox. Changing the face load order won't help as the x-axis is still in the wrong orientation. I haven't found any documentation that would help with a z-up oriented skybox (or at least one that I can understand). If I need different textures, is there a place to get z-up skybox textures, or do I have to rotate these by hand? Looking for advice or a point in the right direction. Images below to help illustrate my desired outcome.

As you can see, the skybox works fine with y-up orientation (model hasn't been rotated for y-up). I want my skybox to look like this using z-up orientation. enter image description here

But on z-up world orientation my skybox also flips 90 degrees on the x axis.~ enter image description here z-up from the side~ enter image description here

**Solved!** Solution as mentioned in the comments is to change the orientation on the vertices. Changing the vertices themselves led me down to disaster. Most convenient place for this, was in the shader. I added a self-explanatory function to my glsl vertex shader. The code should be easy to follow.

#version 450

layout(binding = 0) uniform UniformBufferObject {
    mat4 model;
    mat4 view;
    mat4 proj;
} ubo;

layout(location = 0) in vec3 inPosition; // incoming vertices
layout(location = 0) out vec3 outTextureDirection; // outgoing vertices for cubemap sampler

// returns a 90 degree x-axis rotation matrix
mat4 get_z_correction_matrix()
{
    float s = sin(radians(90.0));
    float c = cos(radians(90.0));
    return mat4(
        1, 0, 0, 0,
        0, c, s, 0,
        0, -s, c, 0,
        0, 0, 0, 1
    );
}

void main() {

    outTextureDirection = inPosition; 

    mat4 ZUP_CORRECTION = get_z_correction_matrix(); // used to correct for my z-up view

    mat4 no_translation_view = ubo.view;
    no_translation_view[3] = vec4(0.0, 0.0, 0.0, 1.0); // so skybox doesn't move with camera;

    gl_Position = ubo.proj * no_translation_view * ZUP_CORRECTION * vec4(inPosition, 1.0);
}
\$\endgroup\$
1
  • \$\begingroup\$ What does your source texture for the skybox look like? \$\endgroup\$
    – DMGregory
    Nov 27, 2021 at 3:43

2 Answers 2

1
\$\begingroup\$

From what I can tell, Ash isn't a rendering engine, just a wrapper around the Vulkan API. Therefore you are presumably using your own engine and shaders to actually render everything.

So, just modify your skybox shader to apply a transform to the skybox vertices to rotate them 90 degrees on the X axis. That will result in Z UP and Y backwards. Alternatively, since the default Vulkan coordinate system is Y up, your model rendering code must be applying some kind of transform to all vertex coordinates to make the Z up into Y up on the fly. Just don't do that to your skybox model vertex data.

\$\endgroup\$
1
  • \$\begingroup\$ Thank you, sir! Default Vulkan coord system is Y-down, but I am multiplying projection by an Identity Matrix with a negative Y value. Yes, I am writing my own renderer from scratch. Tinkering around. Learning. The Z-up is being calculated by the view function of the math library I am using. Anyways, problem solved by multiplying vertices by a rotation matrix then multiplying that by the view. Will share my solution. \$\endgroup\$ Nov 27, 2021 at 9:47
1
\$\begingroup\$

Assuming the skybox faces are loaded in the following order: front, back, up, down, right, left, and the skybox texture is a cubemap rather than 6 individual faces, you can reorient it for z-up by applying the following matrix to it's texture coords (this also positions it correctly relative to the players eye position):

​0​, ​0​, ​1​, ​0​, ​-​1​, ​0​, ​0​, ​0​, ​0​, ​1​, ​0​, ​0​, eyepos.y, ​-​eyepos.z, ​-​eyepos.x, ​1

(You may or may not need to transpose this depending on your preferred convention).

\$\endgroup\$
1
  • \$\begingroup\$ Assumptions correct. Thank you! I ended up using a standard rotation matrix. \$\endgroup\$ Nov 27, 2021 at 9:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .