Added camera uniforms for projection and view matrix

This commit is contained in:
Lorenzo Torres 2025-08-04 17:23:00 +02:00
parent 59e3997056
commit dcb2ee0584
7 changed files with 92 additions and 28 deletions

View file

@ -2,11 +2,16 @@
layout(location = 0) in vec3 vertPos; layout(location = 0) in vec3 vertPos;
layout (binding = 0) uniform Uniform { layout (binding = 0) uniform ProjUniform {
mat4 proj; mat4 proj;
} ubo; } proj;
layout (binding = 1) uniform ViewUniform {
mat4 view;
} view;
void main() { void main() {
vec4 out_vec = ubo.proj * vec4(vertPos, 1.0); vec4 out_vec = proj.proj * view.view * vec4(vertPos, 1.0);
gl_Position = vec4(out_vec.x, out_vec.y, 0.5, out_vec.w); //vec4 out_vec = proj.proj * vec4(vertPos, 1.0);
gl_Position = vec4(out_vec.x, out_vec.y, out_vec.z, out_vec.w);
} }

View file

@ -3,6 +3,7 @@ const Allocator = std.mem.Allocator;
const components = @import("components.zig"); const components = @import("components.zig");
const sparse = @import("sparse.zig"); const sparse = @import("sparse.zig");
const Renderer = @import("renderer"); const Renderer = @import("renderer");
const Camera = @import("renderer").Camera;
const Input = @import("sideros").Input; const Input = @import("sideros").Input;
const ecs = @import("ecs.zig"); const ecs = @import("ecs.zig");
@ -11,6 +12,7 @@ pub const SystemGroup = []const System;
pub const SyncGroup = []const System; pub const SyncGroup = []const System;
pub const Resources = struct { pub const Resources = struct {
camera: Camera,
renderer: Renderer, renderer: Renderer,
input: Input, input: Input,
delta_time: f64 = 0.0, delta_time: f64 = 0.0,

View file

@ -45,6 +45,10 @@ pub fn main() !void {
//defer w.destroy(); //defer w.destroy();
const resources = ecs.Resources{ const resources = ecs.Resources{
.camera = .{
.position = .{0.0, 0.0, 100},
.target = .{0.0, 0.0, 0.0},
},
.renderer = undefined, .renderer = undefined,
.input = .{ .key_pressed = .{false} ** @intFromEnum(Input.KeyCode.menu) }, .input = .{ .key_pressed = .{false} ** @intFromEnum(Input.KeyCode.menu) },
}; };

View file

@ -8,15 +8,15 @@ pub const Matrix = struct {
rows: [4]@Vector(4, f32), rows: [4]@Vector(4, f32),
pub fn lookAt(eye: @Vector(3, f32), target: @Vector(3, f32), arbitrary_up: @Vector(3, f32)) Matrix { pub fn lookAt(eye: @Vector(3, f32), target: @Vector(3, f32), arbitrary_up: @Vector(3, f32)) Matrix {
const forward = normalize(eye - target); const forward = normalize(target - eye);
const right = normalize(cross(arbitrary_up, forward)); const right = normalize(cross(forward, arbitrary_up));
const up = cross(forward, right); const up = cross(right, forward);
const view = [_]@Vector(4, f32){ const view = [_]@Vector(4, f32){
@Vector(4, f32){ right[0], right[1], right[2], 0.0 }, @Vector(4, f32){ right[0], up[0], -forward[0], 0.0 },
@Vector(4, f32){ up[0], up[1], up[2], 0.0 }, @Vector(4, f32){ right[1], up[1], -forward[1], 0.0 },
@Vector(4, f32){ forward[0], forward[1], forward[2], 0.0 }, @Vector(4, f32){ right[2], up[2], -forward[2], 0.0 },
@Vector(4, f32){ 0.0, 0.0, 1.0, eye[2] }, @Vector(4, f32){ -dot(eye, right), -dot(eye, up), -dot(eye, forward), 1.0 },
}; };
return Matrix{ return Matrix{
@ -25,11 +25,17 @@ pub const Matrix = struct {
} }
pub fn perspective(fov: f32, aspect: f32, near: f32, far: f32) Matrix { pub fn perspective(fov: f32, aspect: f32, near: f32, far: f32) Matrix {
const focal_length = 1.0 / tan(fov / 2.0);
const x = focal_length / aspect;
const y = -focal_length;
const a = near / (far - near);
const b = far * a;
const projection = [_]@Vector(4, f32){ const projection = [_]@Vector(4, f32){
@Vector(4, f32){ 1.0 / (aspect * tan(fov / 2.0)), 0.0, 0.0, 0.0 }, @Vector(4, f32){ x, 0.0, 0.0, 0.0 },
@Vector(4, f32){ 0.0, 1.0 / tan(fov / 2.0), 0.0, 0.0 }, @Vector(4, f32){ 0.0, y, 0.0, 0.0 },
@Vector(4, f32){ 0.0, 0.0, -((far + near) / (far - near)), -((2 * far * near) / (far - near)) }, @Vector(4, f32){ 0.0, 0.0, a, b },
@Vector(4, f32){ 0.0, 0.0, -1.0, 1.0 }, @Vector(4, f32){ 0.0, 0.0, 1.0, 0.0 },
}; };
return Matrix{ return Matrix{

View file

@ -12,21 +12,18 @@ pub const Uniform = struct {
model: math.Matrix, model: math.Matrix,
}; };
uniform: Uniform,
position: @Vector(3, f32), position: @Vector(3, f32),
target: @Vector(3, f32), target: @Vector(3, f32) = .{0.0, 0.0, 0.0},
direction: @Vector(3, f32), front: @Vector(3, f32) = .{0.0, 0.0, 1.0 },
right: @Vector(3, f32), up: @Vector(3, f32) = .{0.0, 1.0, 0.0 },
front: @Vector(3, f32),
up: @Vector(3, f32),
speed: f32 = 2.5, speed: f32 = 2.5,
pub fn getProjection(width: usize, height: usize) math.Matrix { pub fn getProjection(width: usize, height: usize) math.Matrix {
return math.Matrix.perspective(math.rad(45.0), (@as(f32, @floatFromInt(width)) / @as(f32, @floatFromInt(height))), 0.1, 10.0); return math.Matrix.perspective(math.rad(45.0), (@as(f32, @floatFromInt(width)) / @as(f32, @floatFromInt(height))), 0.1, 100.0);
} }
pub fn getView(self: Camera) math.Matrix { pub fn getView(self: Camera) math.Matrix {
math.lookAt(self.position, self.position + self.front, self.up); return math.Matrix.lookAt(self.position, self.target, self.up);
} }
pub fn moveCamera(pool: *ecs.Pool) void { pub fn moveCamera(pool: *ecs.Pool) void {

View file

@ -1,8 +1,10 @@
const c = @import("sideros").c; const c = @import("sideros").c;
const math = @import("sideros").math;
const ecs = @import("ecs"); const ecs = @import("ecs");
const std = @import("std"); const std = @import("std");
const vk = @import("vulkan.zig"); const vk = @import("vulkan.zig");
pub const Mesh = @import("Mesh.zig"); pub const Mesh = @import("Mesh.zig");
pub const Camera = @import("Camera.zig");
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
const Renderer = @This(); const Renderer = @This();
@ -76,6 +78,10 @@ pub fn deinit(self: Renderer) void {
// TODO: render is maybe a bad name? something like present() or submit() is better? // TODO: render is maybe a bad name? something like present() or submit() is better?
pub fn render(pool: *ecs.Pool) anyerror!void { pub fn render(pool: *ecs.Pool) anyerror!void {
var renderer = pool.resources.renderer; var renderer = pool.resources.renderer;
var camera = pool.resources.camera;
const view_memory = renderer.graphics_pipeline.view_memory;
@memcpy(view_memory[0..@sizeOf(math.Matrix)], std.mem.asBytes(&camera.getView()));
try renderer.device.waitFence(renderer.current_frame); try renderer.device.waitFence(renderer.current_frame);
const image = try renderer.swapchain.nextImage(renderer.device, renderer.current_frame); const image = try renderer.swapchain.nextImage(renderer.device, renderer.current_frame);

View file

@ -304,6 +304,8 @@ pub fn GraphicsPipeline(comptime n: usize) type {
descriptor_set: c.VkDescriptorSet, descriptor_set: c.VkDescriptorSet,
descriptor_set_layout: c.VkDescriptorSetLayout, descriptor_set_layout: c.VkDescriptorSetLayout,
projection_buffer: Buffer, projection_buffer: Buffer,
view_buffer: Buffer,
view_memory: [*c]u8,
const Self = @This(); const Self = @This();
@ -373,7 +375,8 @@ pub fn GraphicsPipeline(comptime n: usize) type {
.rasterizerDiscardEnable = c.VK_FALSE, .rasterizerDiscardEnable = c.VK_FALSE,
.polygonMode = c.VK_POLYGON_MODE_FILL, .polygonMode = c.VK_POLYGON_MODE_FILL,
.lineWidth = 1.0, .lineWidth = 1.0,
.cullMode = c.VK_CULL_MODE_BACK_BIT, //.cullMode = c.VK_CULL_MODE_BACK_BIT,
.cullMode = c.VK_CULL_MODE_NONE,
.frontFace = c.VK_FRONT_FACE_COUNTER_CLOCKWISE, .frontFace = c.VK_FRONT_FACE_COUNTER_CLOCKWISE,
.depthBiasEnable = c.VK_FALSE, .depthBiasEnable = c.VK_FALSE,
}; };
@ -404,20 +407,27 @@ pub fn GraphicsPipeline(comptime n: usize) type {
.blendConstants = .{ 0.0, 0.0, 0.0, 0.0 }, .blendConstants = .{ 0.0, 0.0, 0.0, 0.0 },
}; };
const set_binding = c.VkDescriptorSetLayoutBinding{ const projection_binding = c.VkDescriptorSetLayoutBinding{
.binding = 0, .binding = 0,
.descriptorType = c.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .descriptorType = c.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.descriptorCount = 1, .descriptorCount = 1,
.stageFlags = c.VK_SHADER_STAGE_VERTEX_BIT, .stageFlags = c.VK_SHADER_STAGE_VERTEX_BIT,
}; };
const bindings = [_]c.VkDescriptorSetLayoutBinding{set_binding}; const view_binding = c.VkDescriptorSetLayoutBinding{
.binding = 1,
.descriptorType = c.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.descriptorCount = 1,
.stageFlags = c.VK_SHADER_STAGE_VERTEX_BIT,
};
const bindings = [_]c.VkDescriptorSetLayoutBinding{projection_binding, view_binding};
var descriptor_set_layout: c.VkDescriptorSetLayout = undefined; var descriptor_set_layout: c.VkDescriptorSetLayout = undefined;
const descriptor_set_layout_info = c.VkDescriptorSetLayoutCreateInfo{ const descriptor_set_layout_info = c.VkDescriptorSetLayoutCreateInfo{
.sType = c.VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, .sType = c.VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.bindingCount = 1, .bindingCount = 2,
.pBindings = bindings[0..].ptr, .pBindings = bindings[0..].ptr,
}; };
@ -462,7 +472,7 @@ pub fn GraphicsPipeline(comptime n: usize) type {
var size = c.VkDescriptorPoolSize{ var size = c.VkDescriptorPoolSize{
.type = c.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .type = c.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.descriptorCount = 1, .descriptorCount = 2,
}; };
const descriptor_pool_info = c.VkDescriptorPoolCreateInfo{ const descriptor_pool_info = c.VkDescriptorPoolCreateInfo{
@ -520,6 +530,38 @@ pub fn GraphicsPipeline(comptime n: usize) type {
c.vkUpdateDescriptorSets(device.handle, 1, &write_descriptor_set, 0, null); c.vkUpdateDescriptorSets(device.handle, 1, &write_descriptor_set, 0, null);
const view_buffer = try device.createBuffer(BufferUsage{ .uniform_buffer = true, .transfer_dst = true }, BufferFlags{ .device_local = true }, @sizeOf(math.Matrix));
var view_data: [*c]u8 = undefined;
try mapError(c.vkMapMemory(
device.handle,
view_buffer.memory,
0,
view_buffer.size,
0,
@ptrCast(&view_data),
));
const view_descriptor_buffer_info = c.VkDescriptorBufferInfo{
.buffer = view_buffer.handle,
.offset = 0,
.range = view_buffer.size,
};
const write_view_descriptor_set = c.VkWriteDescriptorSet{
.sType = c.VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = descriptor_set,
.dstBinding = 1,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = c.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.pBufferInfo = &view_descriptor_buffer_info,
};
c.vkUpdateDescriptorSets(device.handle, 1, &write_view_descriptor_set, 0, null);
return Self{ return Self{
.layout = layout, .layout = layout,
.handle = pipeline, .handle = pipeline,
@ -527,6 +569,8 @@ pub fn GraphicsPipeline(comptime n: usize) type {
.descriptor_set = descriptor_set, .descriptor_set = descriptor_set,
.descriptor_set_layout = descriptor_set_layout, .descriptor_set_layout = descriptor_set_layout,
.projection_buffer = projection_buffer, .projection_buffer = projection_buffer,
.view_buffer = view_buffer,
.view_memory = view_data,
}; };
} }