Bring back textures, add sorting by mesh

This commit is contained in:
sergeypdev 2024-07-27 21:05:50 +04:00
parent 6a0d8348f1
commit 551f92c64e
5 changed files with 69 additions and 67 deletions

View File

@ -38,7 +38,7 @@ VERTEX_EXPORT VertexData {
vec3 wNormal;
} VertexOut;
VERTEX_EXPORT flat int DrawID;
VERTEX_EXPORT flat uint DrawID;
float random(vec4 seed4) {
float dot_product = dot(seed4, vec4(12.9898,78.233,45.164,94.673));
@ -154,7 +154,7 @@ EvalMaterial evalMaterial() {
result.albedo = textureSize(materials[materialIdx].albedo_map, 0) == ivec2(0) ? vec4(pow(materials[materialIdx].albedo.rgb, vec3(2.2)), materials[materialIdx].albedo.a) : texture(materials[materialIdx].albedo_map, VertexOut.uv * materials[materialIdx].albedo_map_uv_scale);
float fMetallic = textureSize(materials[materialIdx].metallic_map, 0) == ivec2(0) ? materials[materialIdx].metallic : texture(materials[materialIdx].metallic_map, VertexOut.uv * materials[materialIdx].metallic_map_uv_scale).b;
result.metallic = fMetallic > 0.1;
result.roughness = max(0.01, textureSize(materials[materialIdx].roughness_map, 0) == ivec2(0) ? materials[materialIdx].roughness : texture(materials[materialIdx].roughness_map, VertexOut.uv * materials[materialIdx].roughness_map_uv_scale).g);
result.roughness = max(1.0, textureSize(materials[materialIdx].roughness_map, 0) == ivec2(0) ? materials[materialIdx].roughness : texture(materials[materialIdx].roughness_map, VertexOut.uv * materials[materialIdx].roughness_map_uv_scale).g);
result.emission = textureSize(materials[materialIdx].emission_map, 0) == ivec2(0) ? materials[materialIdx].emission : texture(materials[materialIdx].emission_map, VertexOut.uv * materials[materialIdx].emission_map_uv_scale).rgb;
return result;
@ -275,7 +275,7 @@ vec3 microfacetModel(EvalMaterial mat, int light_idx, vec3 P, vec3 N) {
} else {
int csm_split_idx = subgroupBroadcastFirst(getCSMSplit(light_idx, P.z));
// Visualize CSM splits
//mat.albedo = vec4(mix(mat.albedo.rgb, csm_split_colors[csm_split_idx], 0.8), mat.albedo.a);
// mat.albedo = vec4(mix(mat.albedo.rgb, csm_split_colors[csm_split_idx], 0.8), mat.albedo.a);
// Directional shadow
vec2 shadow_map_texel_size = 1.0 / vec2(textureSize(shadow_maps, 0));
shadow_offset *= shadow_map_texel_size.x;
@ -291,23 +291,19 @@ vec3 microfacetModel(EvalMaterial mat, int light_idx, vec3 P, vec3 N) {
texcoord.z = shadow_map_idx + csm_split_idx;
float sum = 0;
sum = 1.0; // texture(shadow_maps, vec4(texcoord.xy, texcoord.zw));
// for (float y = -0.5; y <= 0.5; y += 1) {
// for (float x = -0.5; x <= 0.5; x += 1) {
// sum += ;
// }
// }
shadow_mult = sum / 1.0;
for (float y = -1.5; y <= 1.5; y += 1) {
for (float x = -1.5; x <= 1.5; x += 1) {
sum += texture(shadow_maps, vec4(texcoord.xy + vec2(x, y) * shadow_map_texel_size, texcoord.zw));
}
}
shadow_mult = clamp(shadow_mult, 0, 1);
vec3 specBrdf = geomSmith(mat, NDotL) * geomSmith(mat, NDotV) * 0.25 * ggxDistribution(mat, NDotH) * schlickFresnel(mat, LDotH);
shadow_mult = sum / 16.0;
}
shadow_mult = clamp(shadow_mult, 0.2, 1.0);
vec3 vecTerm = PI * specBrdf + diffuseBrdf;
float scalarTerm = NDotL * shadow_mult;
vec3 specBrdf = 0.25 * ggxDistribution(mat, NDotH) * schlickFresnel(mat, LDotH) * geomSmith(mat, NDotL) * geomSmith(mat, NDotV);
return scalarTerm * lightI + mat.emission;
return (diffuseBrdf + PI * specBrdf) * lightI * NDotL * shadow_mult + mat.emission;
}
void main() {

View File

@ -403,7 +403,8 @@ fn loadTextureErr(self: *AssetManager, id: AssetId) !LoadedTexture {
const data = try self.loadFile(self.frame_arena, path, TEXTURE_MAX_BYTES);
defer self.frame_arena.free(data.bytes);
const texture = try formats.Texture.fromBuffer(self.frame_arena, data.bytes);
var texture = try formats.Texture.fromBuffer(self.allocator, data.bytes);
defer texture.free(self.allocator);
var name: gl.GLuint = 0;
gl.createTextures(gl.TEXTURE_2D, 1, &name);
@ -540,7 +541,7 @@ const LoadedShaderProgram = struct {
program: gl.GLuint,
};
const LoadedMesh = struct {
pub const LoadedMesh = struct {
aabb: AABB,
heap_handle: VertexBufferHeap.Alloc,
positions: BufferSlice,
@ -771,10 +772,10 @@ const VertexBufferHeap = struct {
// 256 mega vertices :)
// memory usage for vertices (- indices) = n * 11 * 4
// 4096, 12 will take 704 mb for vertices
var vertex_buddy = try BuddyAllocator.init(allocator, 4096, 12);
var vertex_buddy = try BuddyAllocator.init(allocator, 4096, 13);
errdefer vertex_buddy.deinit();
var index_buddy = try BuddyAllocator.init(allocator, 4096, 12);
var index_buddy = try BuddyAllocator.init(allocator, 4096, 13);
errdefer index_buddy.deinit();
const vertex_buf_size = vertex_buddy.getSize();

View File

@ -452,22 +452,23 @@ pub fn finish(self: *Render) void {
const rhs_mesh = render.assetman.resolveMesh(rhs.mesh);
const lhs_material: Material = if (lhs.material_override) |mat| mat else lhs_mesh.material;
const rhs_material: Material = if (rhs.material_override) |mat| mat else rhs_mesh.material;
return switch (lhs_material.blend_mode) {
.Opaque => switch (rhs_material.blend_mode) {
.AlphaBlend => true,
.Opaque => false,
},
.AlphaBlend => switch (rhs_material.blend_mode) {
.Opaque => false,
.AlphaBlend => {
const lhs_blend_num = @intFromEnum(lhs_material.blend_mode);
const rhs_blend_num = @intFromEnum(rhs_material.blend_mode);
if (lhs_material.blend_mode == .Opaque and rhs_material.blend_mode == .Opaque) {
return lhs.mesh.id < rhs.mesh.id;
}
if (lhs_material.blend_mode == .AlphaBlend and rhs_material.blend_mode == .AlphaBlend) {
const lhs_view_pos = render.camera.view_mat.mulByVec4(lhs.transform.extractTranslation().toVec4(1));
const rhs_view_pos = render.camera.view_mat.mulByVec4(rhs.transform.extractTranslation().toVec4(1));
// Back to front sorting. View pos has negative Z
return lhs_view_pos.z() < rhs_view_pos.z();
},
},
};
}
return lhs_blend_num < rhs_blend_num;
}
}.lessThan);
}
@ -782,7 +783,6 @@ pub fn finish(self: *Render) void {
.first_index = mesh.indices.offset / 4,
.base_vertex = mesh.indices.base_vertex,
.base_instance = 0,
.transform = cmd.transform,
};
rendered_count += 1;
@ -812,19 +812,24 @@ pub fn finish(self: *Render) void {
gl.namedBufferStorage(draw_cmd_data_buf, @intCast(@sizeOf(DrawCommandData) * rendered_count), draw_cmd_data.ptr, 0);
gl.bindBufferBase(gl.SHADER_STORAGE_BUFFER, SSBO.DrawCommandData.value(), draw_cmd_data_buf);
// Z Prepass
{
gl.useProgram(self.assetman.resolveShaderProgram(a.ShaderPrograms.shaders.z_prepass).program);
gl.bindVertexArray(self.shadow_vao);
self.assetman.vertex_heap.vertices.bind(Render.Attrib.Position.value(), 0);
self.assetman.vertex_heap.vertices.bind(Render.Attrib.Position.value());
checkGLError();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.assetman.vertex_heap.indices.buffer);
checkGLError();
// gl.multiDrawElementsIndirect(gl.TRIANGLES, gl.UNSIGNED_INT, null, @intCast(rendered_count), @sizeOf(DrawIndirectCmd));
gl.multiDrawElementsIndirect(gl.TRIANGLES, gl.UNSIGNED_INT, null, @intCast(rendered_count), @sizeOf(DrawIndirectCmd));
}
// Main pass
{
gl.useProgram(self.assetman.resolveShaderProgram(a.ShaderPrograms.shaders.mesh).program);
gl.bindVertexArray(self.mesh_vao);
gl.depthFunc(gl.LEQUAL);
gl.depthFunc(gl.EQUAL);
gl.uniform1ui(Uniform.LightsCount.value(), lights_buf.count.*);
gl.GL_ARB_bindless_texture.uniformHandleui64ARB(Uniform.ShadowMap2D.value(), self.shadow_texture_handle);
@ -841,7 +846,8 @@ pub fn finish(self: *Render) void {
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.assetman.vertex_heap.indices.buffer);
checkGLError();
gl.multiDrawElementsIndirect(gl.TRIANGLES, gl.UNSIGNED_INT, null, @intCast(rendered_count), @sizeOf(DrawIndirectCmd));
gl.multiDrawElementsIndirect(gl.TRIANGLES, gl.UNSIGNED_INT, null, @intCast(rendered_count), 0);
}
gl.disable(gl.BLEND);
gl.depthFunc(gl.LESS);
@ -1436,7 +1442,6 @@ const DrawIndirectCmd = extern struct {
first_index: gl.GLuint,
base_vertex: gl.GLint,
base_instance: gl.GLuint,
transform: Mat4,
};
fn uboAlignedSizeOf(self: *const Render, comptime T: type) usize {

View File

@ -368,8 +368,8 @@ test "write and read scene" {
pub const Material = extern struct {
pub const BlendMode = enum(u8) {
Opaque,
AlphaBlend,
Opaque = 0,
AlphaBlend = 1,
};
albedo: Vec4 = Vec4.one(),

View File

@ -157,7 +157,7 @@ fn processScene(allocator: std.mem.Allocator, input: []const u8, output_dir: std
const maybe_scene: ?*const c.aiScene = @ptrCast(c.aiImportFile(
input_z.ptr,
@as(c_uint, @intCast(c.aiProcess_CalcTangentSpace | c.aiProcess_Triangulate | c.aiProcess_JoinIdenticalVertices | c.aiProcess_SortByPType | c.aiProcess_GenNormals)) | c.aiProcess_GenBoundingBoxes,
@as(c_uint, @intCast(c.aiProcess_CalcTangentSpace | c.aiProcess_Triangulate | c.aiProcess_JoinIdenticalVertices | c.aiProcess_SortByPType | c.aiProcess_GenNormals | c.aiProcess_ImproveCacheLocality)) | c.aiProcess_GenBoundingBoxes,
));
if (maybe_scene == null) {
std.log.err("assimp import error: {s}\n", .{c.aiGetErrorString()});