From 551f92c64e7ca02dfbd8ab57c76e8672d84be1de Mon Sep 17 00:00:00 2001 From: sergeypdev Date: Sat, 27 Jul 2024 21:05:50 +0400 Subject: [PATCH] Bring back textures, add sorting by mesh --- assets/shaders/mesh.glsl | 34 +++++++--------- src/AssetManager.zig | 9 +++-- src/Render.zig | 87 +++++++++++++++++++++------------------- src/formats.zig | 4 +- tools/asset_compiler.zig | 2 +- 5 files changed, 69 insertions(+), 67 deletions(-) diff --git a/assets/shaders/mesh.glsl b/assets/shaders/mesh.glsl index 80b2d42..a636f97 100644 --- a/assets/shaders/mesh.glsl +++ b/assets/shaders/mesh.glsl @@ -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; @@ -290,24 +290,20 @@ vec3 microfacetModel(EvalMaterial mat, int light_idx, vec3 P, vec3 N) { texcoord.xyw = shadow_pos.xyz; // sampler2DArrayShadow strange texcoord mapping 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; + float sum = 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 = sum / 16.0; } - shadow_mult = clamp(shadow_mult, 0, 1); + shadow_mult = clamp(shadow_mult, 0.2, 1.0); - vec3 specBrdf = geomSmith(mat, NDotL) * geomSmith(mat, NDotV) * 0.25 * ggxDistribution(mat, NDotH) * schlickFresnel(mat, LDotH); - - vec3 vecTerm = PI * specBrdf + diffuseBrdf; - float scalarTerm = NDotL * shadow_mult; - - return scalarTerm * lightI + mat.emission; + vec3 specBrdf = 0.25 * ggxDistribution(mat, NDotH) * schlickFresnel(mat, LDotH) * geomSmith(mat, NDotL) * geomSmith(mat, NDotV); + + return (diffuseBrdf + PI * specBrdf) * lightI * NDotL * shadow_mult + mat.emission; } void main() { diff --git a/src/AssetManager.zig b/src/AssetManager.zig index 9c8f0da..4b6dbc1 100644 --- a/src/AssetManager.zig +++ b/src/AssetManager.zig @@ -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(); diff --git a/src/Render.zig b/src/Render.zig index f2713d5..5f73d19 100644 --- a/src/Render.zig +++ b/src/Render.zig @@ -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_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(); - }, - }, - }; + 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,36 +812,42 @@ 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); - gl.useProgram(self.assetman.resolveShaderProgram(a.ShaderPrograms.shaders.z_prepass).program); - gl.bindVertexArray(self.shadow_vao); + // 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); - checkGLError(); - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.assetman.vertex_heap.indices.buffer); - checkGLError(); + 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)); + } - gl.useProgram(self.assetman.resolveShaderProgram(a.ShaderPrograms.shaders.mesh).program); - gl.bindVertexArray(self.mesh_vao); - gl.depthFunc(gl.LEQUAL); + // Main pass + { + gl.useProgram(self.assetman.resolveShaderProgram(a.ShaderPrograms.shaders.mesh).program); + gl.bindVertexArray(self.mesh_vao); + 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); - gl.GL_ARB_bindless_texture.uniformHandleui64ARB(Uniform.ShadowMapCube.value(), self.cube_shadow_texture_handle); + gl.uniform1ui(Uniform.LightsCount.value(), lights_buf.count.*); + gl.GL_ARB_bindless_texture.uniformHandleui64ARB(Uniform.ShadowMap2D.value(), self.shadow_texture_handle); + gl.GL_ARB_bindless_texture.uniformHandleui64ARB(Uniform.ShadowMapCube.value(), self.cube_shadow_texture_handle); - self.assetman.vertex_heap.normals.bind(Render.Attrib.Normal.value()); - checkGLError(); - self.assetman.vertex_heap.tangents.bind(Render.Attrib.Tangent.value()); - checkGLError(); - self.assetman.vertex_heap.uvs.bind(Render.Attrib.UV.value()); - checkGLError(); - self.assetman.vertex_heap.vertices.bind(Render.Attrib.Position.value()); - checkGLError(); - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.assetman.vertex_heap.indices.buffer); - checkGLError(); + self.assetman.vertex_heap.normals.bind(Render.Attrib.Normal.value()); + checkGLError(); + self.assetman.vertex_heap.tangents.bind(Render.Attrib.Tangent.value()); + checkGLError(); + self.assetman.vertex_heap.uvs.bind(Render.Attrib.UV.value()); + checkGLError(); + 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), 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 { diff --git a/src/formats.zig b/src/formats.zig index 37b17b3..52ad392 100644 --- a/src/formats.zig +++ b/src/formats.zig @@ -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(), diff --git a/tools/asset_compiler.zig b/tools/asset_compiler.zig index b030708..98c8af3 100644 --- a/tools/asset_compiler.zig +++ b/tools/asset_compiler.zig @@ -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()});