FreshRSS

Zobrazení pro čtení

Jsou dostupné nové články, klikněte pro obnovení stránky.

Orbit Camera In vulkan

I've been having trouble trying to make a solidworks style Orbit Camera, nothing I do seems to work even though apparently it should (I've tried multiple methods and this seems to be the most promising).

I have a camera struct defined as such

Camera :: struct {
    pos:vec3 = .{0,0,1}; // 1
    target:vec3 = .{0,0,0};

    up:vec3 = .{0,0,1};
    right:vec3 = .{1,0,0};
    // zoom:float = 1;

    Tmat:mat4 = IDENTITY; // Translation
    Rmat:mat4 = IDENTITY; // Rotation
    Pmat:mat4 = IDENTITY; // Pivot matrix
    
    view:mat4 = IDENTITY;
    viewMat:mat4 = IDENTITY; // really inverse view mat

    lastposx:float;
    lastposy:float;
}

my rotate camera function is defined as such

rotate_cam :: (r:fwdpp_r,cam:*Camera,x:float,y:float) {
    using cam;
    rotation_origin := target;

    dx := TAU / r.pipeline.Extent.width;
    dy := PI / r.pipeline.Extent.height;
    r_x := (lastposx - x) * dx;
    r_y := (lastposy - y) * dy;
    lastposx = x;
    lastposy = y;
    rotx:Quaternion = .{r_x,0,0,1};
    roty:Quaternion = .{0,0,r_y,1};

    camDir := normalize(pos - target);

    right = xx normalize(cross(up,camDir));
    up = xx normalize(cross(camDir,right));

    rq := rotx * roty;

    Rmat = rotate(Rmat,rq);


    updateViewMatrix(cam);
}

with rotate being

rotate :: (q: Quaternion) -> Matrix4 {
    m: Matrix4;



    xs := q.x * 2;
    ys := q.y * 2;
    zs := q.z * 2;

    wx := q.w * xs;
    wy := q.w * ys;
    wz := q.w * zs;

    _xx := q.x * xs;
    xy := q.x * ys;
    xz := q.x * zs;

    yy := q.y * ys;
    yz := q.y * zs;
    zz := q.z * zs;

    m._11 = 1.0 - (yy + zz);
    m._12 = xy - wz;
    m._13 = xz + wy;

    m._21 = xy + wz;
    m._22 = 1.0 - (_xx + zz);
    m._23 = yz - wx;

    m._31 = xz - wy;
    m._32 = yz + wx;
    m._33 = 1.0 - (_xx + yy);
    
    m._44 = 1;

    return m;
}

update_view matrix being

updateViewMatrix :: (cam:*Camera) {
    using cam;
    Pmat = translate(IDENTITY,target);
    viewMat = multiply(TO_VULKAN_COORDS_MATRIX,inverse(Pmat) * Rmat * Pmat * Tmat);
    view = inverse(viewMat);
}
TO_VULKAN_COORDS_MATRIX :: Matrix4.{
    0, -1,  0,  0,
    0,  0, -1,  0,
    1,  0,  0,  0,
    0,  0,  0,  1,
};

This produces this result

How do you handle shaders/graphics while remaining cross-platform?

I'm building a C++ based game engine, and I have my ECS complete as well as some basic components for stuff like graphics & audio. However, I'm currently using a custom interface on top of SFML with GLSL based shaders and OpenGL based graphics. I'd like to switch to a graphics solution where I can switch between OpenGL, Vulkan, DirectX3D, and Metal without rewriting large portioins of my code. The graphics API itself isn't a problem, since I can easily build an interface on top of it and reimplement it for each desired platform. My issue, however, is with the shaders.

I'm currently writing my test shaders in GLSL targeting OpenGL. I know I can use the SPIR-V translator to generate HLSL/MSL/Vulkan-Style GLSL from my OpenGL source code, but I'm not sure how that will work when I start having to set uniforms, handle shader buffers, and the like.

The big solution I've heard of is generating shaders at runtime, which is what Godot does. However, my engine is very performance-oriented, so I'd like to precompile all my shaders if possible. I've also seen that Unity uses HLSL2GLSL translator and SPIR-V cross is very common. However, I'm worried about how these will interact with setting uniforms and whatnot, and I'm very concerned about their impact on performance.

❌