Bring back textures, add sorting by mesh
This commit is contained in:
parent
6a0d8348f1
commit
551f92c64e
@ -38,7 +38,7 @@ VERTEX_EXPORT VertexData {
|
|||||||
vec3 wNormal;
|
vec3 wNormal;
|
||||||
} VertexOut;
|
} VertexOut;
|
||||||
|
|
||||||
VERTEX_EXPORT flat int DrawID;
|
VERTEX_EXPORT flat uint DrawID;
|
||||||
|
|
||||||
float random(vec4 seed4) {
|
float random(vec4 seed4) {
|
||||||
float dot_product = dot(seed4, vec4(12.9898,78.233,45.164,94.673));
|
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);
|
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;
|
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.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;
|
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;
|
return result;
|
||||||
@ -275,7 +275,7 @@ vec3 microfacetModel(EvalMaterial mat, int light_idx, vec3 P, vec3 N) {
|
|||||||
} else {
|
} else {
|
||||||
int csm_split_idx = subgroupBroadcastFirst(getCSMSplit(light_idx, P.z));
|
int csm_split_idx = subgroupBroadcastFirst(getCSMSplit(light_idx, P.z));
|
||||||
// Visualize CSM splits
|
// 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
|
// Directional shadow
|
||||||
vec2 shadow_map_texel_size = 1.0 / vec2(textureSize(shadow_maps, 0));
|
vec2 shadow_map_texel_size = 1.0 / vec2(textureSize(shadow_maps, 0));
|
||||||
shadow_offset *= shadow_map_texel_size.x;
|
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.xyw = shadow_pos.xyz; // sampler2DArrayShadow strange texcoord mapping
|
||||||
texcoord.z = shadow_map_idx + csm_split_idx;
|
texcoord.z = shadow_map_idx + csm_split_idx;
|
||||||
|
|
||||||
float sum = 0;
|
float sum = 0;
|
||||||
sum = 1.0; // texture(shadow_maps, vec4(texcoord.xy, texcoord.zw));
|
for (float y = -1.5; y <= 1.5; y += 1) {
|
||||||
// for (float y = -0.5; y <= 0.5; y += 1) {
|
for (float x = -1.5; x <= 1.5; x += 1) {
|
||||||
// for (float x = -0.5; x <= 0.5; x += 1) {
|
sum += texture(shadow_maps, vec4(texcoord.xy + vec2(x, y) * shadow_map_texel_size, texcoord.zw));
|
||||||
// sum += ;
|
}
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
|
shadow_mult = sum / 16.0;
|
||||||
shadow_mult = sum / 1.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 specBrdf = 0.25 * ggxDistribution(mat, NDotH) * schlickFresnel(mat, LDotH) * geomSmith(mat, NDotL) * geomSmith(mat, NDotV);
|
||||||
|
|
||||||
vec3 vecTerm = PI * specBrdf + diffuseBrdf;
|
return (diffuseBrdf + PI * specBrdf) * lightI * NDotL * shadow_mult + mat.emission;
|
||||||
float scalarTerm = NDotL * shadow_mult;
|
|
||||||
|
|
||||||
return scalarTerm * lightI + mat.emission;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
@ -403,7 +403,8 @@ fn loadTextureErr(self: *AssetManager, id: AssetId) !LoadedTexture {
|
|||||||
const data = try self.loadFile(self.frame_arena, path, TEXTURE_MAX_BYTES);
|
const data = try self.loadFile(self.frame_arena, path, TEXTURE_MAX_BYTES);
|
||||||
defer self.frame_arena.free(data.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;
|
var name: gl.GLuint = 0;
|
||||||
gl.createTextures(gl.TEXTURE_2D, 1, &name);
|
gl.createTextures(gl.TEXTURE_2D, 1, &name);
|
||||||
@ -540,7 +541,7 @@ const LoadedShaderProgram = struct {
|
|||||||
program: gl.GLuint,
|
program: gl.GLuint,
|
||||||
};
|
};
|
||||||
|
|
||||||
const LoadedMesh = struct {
|
pub const LoadedMesh = struct {
|
||||||
aabb: AABB,
|
aabb: AABB,
|
||||||
heap_handle: VertexBufferHeap.Alloc,
|
heap_handle: VertexBufferHeap.Alloc,
|
||||||
positions: BufferSlice,
|
positions: BufferSlice,
|
||||||
@ -771,10 +772,10 @@ const VertexBufferHeap = struct {
|
|||||||
// 256 mega vertices :)
|
// 256 mega vertices :)
|
||||||
// memory usage for vertices (- indices) = n * 11 * 4
|
// memory usage for vertices (- indices) = n * 11 * 4
|
||||||
// 4096, 12 will take 704 mb for vertices
|
// 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();
|
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();
|
errdefer index_buddy.deinit();
|
||||||
|
|
||||||
const vertex_buf_size = vertex_buddy.getSize();
|
const vertex_buf_size = vertex_buddy.getSize();
|
||||||
|
@ -452,22 +452,23 @@ pub fn finish(self: *Render) void {
|
|||||||
const rhs_mesh = render.assetman.resolveMesh(rhs.mesh);
|
const rhs_mesh = render.assetman.resolveMesh(rhs.mesh);
|
||||||
const lhs_material: Material = if (lhs.material_override) |mat| mat else lhs_mesh.material;
|
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;
|
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
|
const lhs_blend_num = @intFromEnum(lhs_material.blend_mode);
|
||||||
return lhs_view_pos.z() < rhs_view_pos.z();
|
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);
|
}.lessThan);
|
||||||
}
|
}
|
||||||
@ -782,7 +783,6 @@ pub fn finish(self: *Render) void {
|
|||||||
.first_index = mesh.indices.offset / 4,
|
.first_index = mesh.indices.offset / 4,
|
||||||
.base_vertex = mesh.indices.base_vertex,
|
.base_vertex = mesh.indices.base_vertex,
|
||||||
.base_instance = 0,
|
.base_instance = 0,
|
||||||
.transform = cmd.transform,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
rendered_count += 1;
|
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.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.bindBufferBase(gl.SHADER_STORAGE_BUFFER, SSBO.DrawCommandData.value(), draw_cmd_data_buf);
|
||||||
|
|
||||||
gl.useProgram(self.assetman.resolveShaderProgram(a.ShaderPrograms.shaders.z_prepass).program);
|
// Z Prepass
|
||||||
gl.bindVertexArray(self.shadow_vao);
|
{
|
||||||
|
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();
|
checkGLError();
|
||||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.assetman.vertex_heap.indices.buffer);
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.assetman.vertex_heap.indices.buffer);
|
||||||
checkGLError();
|
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);
|
// Main pass
|
||||||
gl.bindVertexArray(self.mesh_vao);
|
{
|
||||||
gl.depthFunc(gl.LEQUAL);
|
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.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.ShadowMap2D.value(), self.shadow_texture_handle);
|
||||||
gl.GL_ARB_bindless_texture.uniformHandleui64ARB(Uniform.ShadowMapCube.value(), self.cube_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());
|
self.assetman.vertex_heap.normals.bind(Render.Attrib.Normal.value());
|
||||||
checkGLError();
|
checkGLError();
|
||||||
self.assetman.vertex_heap.tangents.bind(Render.Attrib.Tangent.value());
|
self.assetman.vertex_heap.tangents.bind(Render.Attrib.Tangent.value());
|
||||||
checkGLError();
|
checkGLError();
|
||||||
self.assetman.vertex_heap.uvs.bind(Render.Attrib.UV.value());
|
self.assetman.vertex_heap.uvs.bind(Render.Attrib.UV.value());
|
||||||
checkGLError();
|
checkGLError();
|
||||||
self.assetman.vertex_heap.vertices.bind(Render.Attrib.Position.value());
|
self.assetman.vertex_heap.vertices.bind(Render.Attrib.Position.value());
|
||||||
checkGLError();
|
checkGLError();
|
||||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.assetman.vertex_heap.indices.buffer);
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.assetman.vertex_heap.indices.buffer);
|
||||||
checkGLError();
|
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.disable(gl.BLEND);
|
||||||
gl.depthFunc(gl.LESS);
|
gl.depthFunc(gl.LESS);
|
||||||
@ -1436,7 +1442,6 @@ const DrawIndirectCmd = extern struct {
|
|||||||
first_index: gl.GLuint,
|
first_index: gl.GLuint,
|
||||||
base_vertex: gl.GLint,
|
base_vertex: gl.GLint,
|
||||||
base_instance: gl.GLuint,
|
base_instance: gl.GLuint,
|
||||||
transform: Mat4,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
fn uboAlignedSizeOf(self: *const Render, comptime T: type) usize {
|
fn uboAlignedSizeOf(self: *const Render, comptime T: type) usize {
|
||||||
|
@ -368,8 +368,8 @@ test "write and read scene" {
|
|||||||
|
|
||||||
pub const Material = extern struct {
|
pub const Material = extern struct {
|
||||||
pub const BlendMode = enum(u8) {
|
pub const BlendMode = enum(u8) {
|
||||||
Opaque,
|
Opaque = 0,
|
||||||
AlphaBlend,
|
AlphaBlend = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
albedo: Vec4 = Vec4.one(),
|
albedo: Vec4 = Vec4.one(),
|
||||||
|
@ -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(
|
const maybe_scene: ?*const c.aiScene = @ptrCast(c.aiImportFile(
|
||||||
input_z.ptr,
|
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) {
|
if (maybe_scene == null) {
|
||||||
std.log.err("assimp import error: {s}\n", .{c.aiGetErrorString()});
|
std.log.err("assimp import error: {s}\n", .{c.aiGetErrorString()});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user