diff options
author | quou <quou@disroot.org> | 2025-01-09 22:53:40 +1100 |
---|---|---|
committer | quou <quou@disroot.org> | 2025-01-09 22:53:40 +1100 |
commit | 622e634e1cfd55dd875979a1f109a804d3dbe7ee (patch) | |
tree | d71ec2ff776221189a006b5ffc3a0ac78f3c664a | |
parent | b3363b1716fbbb2af1b33b9bdd7a13f72016283d (diff) |
mipmap the environment probe
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | c2.cpp | 134 | ||||
-rw-r--r-- | intermediate/mip_spec.glsl | 44 | ||||
-rw-r--r-- | intermediate/plastic.mat | 2 | ||||
-rw-r--r-- | intermediate/surface.glsl | 4 | ||||
-rw-r--r-- | video.cpp | 5 |
6 files changed, 166 insertions, 29 deletions
@@ -7,7 +7,8 @@ shaders = \ $(data_dir)/ui.csh \ $(data_dir)/surface.csh \ $(data_dir)/surface_depthonly.csh \ - $(data_dir)/sky.csh + $(data_dir)/sky.csh \ + $(data_dir)/mip_spec.csh textures = \ $(data_dir)/22.tex \ $(data_dir)/kita.tex \ @@ -68,6 +69,9 @@ data/surface_depthonly.csh: intermediate/surface_depthonly.glsl | $(data_dir) sc data/sky.csh: intermediate/sky.glsl | $(data_dir) sc ./sc/sc intermediate/sky.glsl $(data_dir)/sky.csh +data/mip_spec.csh: intermediate/mip_spec.glsl | $(data_dir) sc + ./sc/sc intermediate/mip_spec.glsl $(data_dir)/mip_spec.csh + data/22.tex: intermediate/22.bmp | $(data_dir) convtexture ./convtexture intermediate/22.bmp $(data_dir)/22.tex bc1 @@ -80,6 +80,7 @@ static Sampler_Id create_clamped_linear(Device* dev) { Sampler_State s{}; s.min = Filter_Mode::linear; s.mag = Filter_Mode::linear; + s.mip = Filter_Mode::linear; s.address_u = Address_Mode::repeat; s.address_v = Address_Mode::repeat; return dev->create_sampler("repeated linear", s); @@ -281,12 +282,16 @@ struct Sky { }; struct Env_Probe { - Texture_Id cubemap; + static constexpr int mip_count = 9; + Texture_Id cubemap[2]; Texture_Id cubemap_depth; - Texture_Id faces[6]; + Texture_Id faces[2][6][mip_count]; Sampler_Id sampler; int cubemap_res; + int completed; Staged_Buffer config; + Shader* shader; + int src_binding, vert_binding; void init(Device* dev, Asset_Arena* assets, int res) { int i; @@ -294,8 +299,10 @@ struct Env_Probe { cubemap_res = res; s.min = Filter_Mode::linear; s.mag = Filter_Mode::linear; + s.mip = Filter_Mode::linear; s.address_u = Address_Mode::repeat; s.address_v = Address_Mode::repeat; + s.address_w = Address_Mode::repeat; sampler = dev->create_sampler("env probe sampler", s); cubemap_depth = dev->create_texture( "env cubemap depth", @@ -308,8 +315,8 @@ struct Env_Probe { 1, 0 ); - cubemap = dev->create_texture( - "env cubemap", + cubemap[0] = dev->create_texture( + "env cubemap A", texture_format_rgba16f, Texture_Flags::cubemap | Texture_Flags::colour_target | @@ -317,25 +324,59 @@ struct Env_Probe { res, res, 1, - 0, + mip_count, + 1, + Buffer_Id(0) + ); + cubemap[1] = dev->create_texture( + "env cubemap B", + texture_format_rgba16f, + Texture_Flags::cubemap | + Texture_Flags::colour_target | + Texture_Flags::sampleable, + res, + res, + 1, + mip_count, 1, Buffer_Id(0) ); for (i = 0; i < 6; i++) { - faces[i] = dev->alias_texture( - cubemap, - "env cubemap face", - texture_format_rgba16f, - Texture_Flags::colour_target | - Texture_Flags::sampleable, - res, - res, - 1, - 1, - 1, - 0, - i - ); + int j; + int w = res; + int h = res; + for (j = 0; j < mip_count; j++) { + faces[0][i][j] = dev->alias_texture( + cubemap[0], + "env cubemap face A", + texture_format_rgba16f, + Texture_Flags::colour_target | + Texture_Flags::sampleable, + w, + h, + 1, + 1, + 1, + j, + i + ); + faces[1][i][j] = dev->alias_texture( + cubemap[1], + "env cubemap face B", + texture_format_rgba16f, + Texture_Flags::colour_target | + Texture_Flags::sampleable, + w, + h, + 1, + 1, + 1, + j, + i + ); + w /= 2; + h /= 2; + } } config.init( dev, @@ -343,16 +384,26 @@ struct Env_Probe { sizeof(Sky::Cbuffer) * 6, Buffer_Flags::constant_buffer ); + shader = (Shader*)assets->load("mip_spec.csh"); + src_binding = shader->descriptor_binding("src"); + vert_binding = shader->binding_index("verts"); + assert(src_binding >= 0); + assert(vert_binding >= 0); } void destroy(Device* dev) { int i; for (i = 0; i < 6; i++) { - dev->destroy_texture(faces[i]); + int j; + for (j = 0; j < mip_count; j++) { + dev->destroy_texture(faces[0][i][j]); + dev->destroy_texture(faces[1][i][j]); + } } dev->destroy_texture(cubemap_depth); dev->destroy_sampler(sampler); - dev->destroy_texture(cubemap); + dev->destroy_texture(cubemap[0]); + dev->destroy_texture(cubemap[1]); config.destroy(dev); } @@ -399,7 +450,7 @@ struct Env_Probe { update_cbuffer(dev); for (i = 0; i < 6; i++) { pb.begin_rp(); - pb.rp_target(faces[i], Clear_Mode::discard); + pb.rp_target(faces[0][i][0], Clear_Mode::discard); pb.rp_depth_target(cubemap_depth, 1.0f); sky.render_imp( dev, @@ -412,6 +463,43 @@ struct Env_Probe { cubemap_res ); } + completed = 0; + for (i = 0; i < 6; i++) { + int j; + for (j = 0; j < mip_count; j++) { + Texture& t = dev->get_texture(faces[completed ^ 1][i][j]); + pb.begin_rp(); + pb.rp_target(t.id, Clear_Mode::discard); + Render_Pass& pass = pb.build_rp(); + pb.begin(); + pb.viewport(0, 0, t.w, t.h); + pb.scissor(0, 0, t.w, t.h); + pb.texture( + src_binding, + faces[completed][i][0], + sampler + ); + pb.shader(shader->id); + pb.vertex_format(shader->vf); + Pipeline& pip = pb.build(); + + Vertex_Buffer_Binding vbb[] = {{ + .id = sky.vb, + .offset = 0, + .target = vert_binding + }, {}}; + Draw draw{}; + draw.verts = vbb; + draw.vertex_count = 3; + draw.instance_count = 1; + ctx.submit(draw, pip, pass); + } + } + completed = 1; + } + + Texture_Id get_cubemap() { + return cubemap[completed]; } }; @@ -612,7 +700,7 @@ struct C2 : public App { scene.render(dev, &frame_arena, depth_prepass, 0, clamped_linear); ctx.debug_pop(); ctx.debug_push("forward"); - scene.render(dev, &frame_arena, pass2, eprobe.cubemap, clamped_linear); + scene.render(dev, &frame_arena, pass2, eprobe.get_cubemap(), clamped_linear); ctx.debug_pop(); ctx.debug_pop(); diff --git a/intermediate/mip_spec.glsl b/intermediate/mip_spec.glsl new file mode 100644 index 0000000..bddcbb0 --- /dev/null +++ b/intermediate/mip_spec.glsl @@ -0,0 +1,44 @@ +#ifdef DESC +[program] +type: graphics +vertex: main +fragment: main + +[binding] +name: verts +rate: vertex +[attribute] +name: position +type: vec2 +[attribute] +name: uv +type: vec2 + +[interpolator] +name: uv +type: vec2 + +[texture] +name: src +stage: fragment +dimension: 2 + +[target] +name: colour +type: vec4 +#endif + +#ifdef VERTEX_SHADER +void main() { + interpolator.uv = uv; + gl_Position = vec4(position, 1.0, 1.0); +} +#endif + +#ifdef FRAGMENT_SHADER +void main() { + vec2 uv = interpolator.uv; + colour = texture(src, uv); +} +#endif + diff --git a/intermediate/plastic.mat b/intermediate/plastic.mat index 3d59385..bb52092 100644 --- a/intermediate/plastic.mat +++ b/intermediate/plastic.mat @@ -1,6 +1,6 @@ [params] metalness: 0.0 -roughness: 0.1 +roughness: 0.3 ao: 1.0 albedo: ff0000 diff --git a/intermediate/surface.glsl b/intermediate/surface.glsl index 8ec24f0..fab8694 100644 --- a/intermediate/surface.glsl +++ b/intermediate/surface.glsl @@ -165,8 +165,8 @@ void main() { float met = texture(metal, uv).r * material.metalness; vec3 ref = reflect(-view_dir, nrm); - vec3 spec_col = texture(env_cube, ref).rgb; - vec3 amb_col = texture(env_cube, nrm).rgb; + vec3 spec_col = texture(env_cube, ref, material.roughness * 8.0).rgb; + vec3 amb_col = textureLod(env_cube, nrm, 8.0).rgb; vec3 diffuse = diffuse_brdf(uv) * @@ -6,9 +6,9 @@ #define max_buffers 1024 #define max_vertex_formats 64 #define max_rpos 64 -#define max_fbos 64 +#define max_fbos 1024 #define max_pipelines 64 -#define max_descriptor_sets 64 +#define max_descriptor_sets 1024 #define max_shaders 32 #define max_samplers 16 @@ -4154,6 +4154,7 @@ void Sampler_Vk::init(Device_Vk* dev, const Sampler_State& s) { si.addressModeV = get_mode(s.address_v); si.addressModeW = get_mode(s.address_w); si.borderColor = VK_BORDER_COLOR_FLOAT_CUSTOM_EXT; + si.maxLod = VK_LOD_CLAMP_NONE; si.pNext = &bi; bi.sType = VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT; bi.customBorderColor = col; |