Begin new Asset Pipeline

This commit is contained in:
2025-11-21 13:02:32 +01:00
parent bbafc55f6f
commit 63a8eee18c
34 changed files with 1190 additions and 586 deletions

138
src/assets/Materials.zig Normal file
View File

@@ -0,0 +1,138 @@
const Materials = @This();
const std = @import("std");
const vk = @import("vulkan");
const Atoms = @import("Atoms.zig");
const Engine = @import("../engine/Engine.zig");
const Textures = @import("Textures.zig");
allocator: std.mem.Allocator,
map: Map,
pub const Id = extern struct {
id: u32,
};
pub const Map = std.AutoHashMapUnmanaged(Atoms.Atom, Id);
pub const Material = extern struct {
base_color: [3]f32,
base_color_texture: Textures.Id,
emissive: [3]f32,
emissive_texture: Textures.Id,
ior: f32,
metallic: f32,
normal_scale: f32,
normal_texture: Textures.Id,
occlusion_roughness_metallic_texture: Textures.Id,
occlusion_texture_strength: f32,
roughness: f32,
};
pub fn init(allocator: std.mem.Allocator) !Materials {
var map: Map = .empty;
errdefer map.deinit(allocator);
return .{
.allocator = allocator,
.map = map,
};
}
pub fn deinit(self: *Materials) void {
self.arena.deinit();
self.* = undefined;
}
fn loadMaterial(self: *Materials, textures: *Textures, engine: *Engine, atoms: *Atoms, key: Atoms.Atom) !Id {
const MaterialJson = struct {
baseColor: [3]f32 = .{ 1, 1, 1 },
baseColorTexture: ?[]const u8 = null,
emissive: [3]f32 = .{ 0, 0, 0 },
emissiveTexture: ?[]const u8 = null,
ior: f32 = 1.45,
metallic: f32 = 1,
normalScale: f32 = 1,
normalTexture: ?[]const u8 = null,
occlusionRoughnessMetallicTexture: ?[]const u8 = null,
occlusionTextureStrength: f32 = 1,
roughness: f32 = 1,
};
const filename = atoms.getString(key).?;
const cwd = std.fs.cwd();
var dir = try cwd.openDir("assets/materials", .{});
defer dir.close();
// NOTE Buffer size approximated based on expected JSON structure.
var buffer: [512]u8 = undefined;
const file = try dir.openFile(filename, .{});
defer file.close();
var file_reader = file.reader(&buffer);
var json_reader: std.json.Reader = .init(self.allocator, &file_reader.interface);
defer json_reader.deinit();
const parsed: std.json.Parsed(MaterialJson) = try std.json.parseFromTokenSource(MaterialJson, self.allocator, &json_reader, .{
.duplicate_field_behavior = .@"error",
.ignore_unknown_fields = false,
.allocate = .alloc_if_needed,
});
defer parsed.deinit();
const material_json = parsed.value;
const base_color_texture = blk: {
if (material_json.baseColorTexture) |name| {
const atom = try atoms.getOrPutAtom(name);
break :blk try textures.getOrLoadId(engine, .{ .atom = atom, .usage = .base_color });
} else {
break :blk textures.empty_base_color;
}
};
const emissive_texture = blk: {
if (material_json.emissiveTexture) |name| {
const atom = try atoms.getOrPutAtom(name);
break :blk try textures.getOrLoadId(engine, .{ .atom = atom, .usage = .emissive });
} else {
break :blk textures.empty_emissive;
}
};
const normal_texture = blk: {
if (material_json.normalTexture) |name| {
const atom = try atoms.getOrPutAtom(name);
break :blk try textures.getOrLoadId(engine, .{ .atom = atom, .usage = .normal });
} else {
break :blk textures.empty_normal;
}
};
const occlusion_roughness_metallic_texture = blk: {
if (material_json.occlusionRoughnessMetallicTexture) |name| {
const atom = try atoms.getOrPutAtom(name);
break :blk try textures.getOrLoadId(engine, .{ .atom = atom, .usage = .occlusion_roughness_metallic });
} else {
break :blk textures.empty_occlusuion_roughness_metallic;
}
};
const material: Material = .{
.base_color = material_json.baseColor,
.base_color_texture = base_color_texture,
.emissive = material_json.emissive,
.emissive_texture = emissive_texture,
.ior = material_json.ior,
.metallic = material_json.metallic,
.normal_scale = material_json.normalScale,
.normal_texture = normal_texture,
.occlusion_roughness_metallic_texture = occlusion_roughness_metallic_texture,
.occlusion_texture_strength = material_json.occlusionTextureStrength,
.roughness = material_json.roughness,
};
}