diff options
author | quou <quou@disroot.org> | 2025-01-18 17:35:27 +1100 |
---|---|---|
committer | quou <quou@disroot.org> | 2025-01-18 17:35:27 +1100 |
commit | 7b6bda1188cf80ffc85b16e099d7811c92dbd7ac (patch) | |
tree | 4e27a5a59c7a3d20de9dd15167b2c706aca4a090 /c2.cpp | |
parent | b2392cf01e6fd0c15bc52941177fbe4b8a5d1a69 (diff) |
tonemap
Diffstat (limited to 'c2.cpp')
-rw-r--r-- | c2.cpp | 118 |
1 files changed, 110 insertions, 8 deletions
@@ -254,10 +254,10 @@ struct Sky { Fullscreen_Quad& quad, Render_Pass& pass, Sampler_Id sampler, - const Camera& cam + const Camera& cam, + Texture_Id target ) { - Texture_Id backbuffer_id = d->get_backbuffer(); - Texture& backbuffer = d->get_texture(backbuffer_id); + Texture& backbuffer = d->get_texture(target); Cbuffer* cb = (Cbuffer*)config.map(d); cb->iview = cam.get_view().inverse(); cb->iprojection = cam.get_proj().inverse(); @@ -554,6 +554,68 @@ struct Env_Probe { } }; +struct Tonemap { + Staged_Buffer config; + Shader* shader; + int config_binding, vert_binding, src_binding; + + struct Cbuffer { + float exposure; + }; + + void init(Device* d, Asset_Arena* assets) { + shader = (Shader*)assets->load("tonemap.csh"); + assert(shader != 0); + vert_binding = shader->binding_index("verts"); + assert(vert_binding >= 0); + src_binding = shader->descriptor_binding("src"); + assert(src_binding >= 0); + config_binding = shader->descriptor_binding("config"); + assert(config_binding >= 0); + config.init( + d, + "Tonemap Cbuffer", + sizeof(Cbuffer), + Buffer_Flags::constant_buffer + ); + } + + void destroy(Device* d) { + config.destroy(d); + } + + void update(Device* d, float exposure) { + Context& ctx = d->get_ctx(); + Cbuffer* b = (Cbuffer*)config.map(d); + b->exposure = exposure; + config.unmap(d); + config.update(ctx); + } + + void render( + Device* d, + Arena* a, + Fullscreen_Quad& quad, + Render_Pass& pass, + Texture_Id src, + Sampler_Id sampler + ) { + Context& ctx = d->get_ctx(); + Pipeline_Builder pb(a, d); + pb.begin(); + pb.shader(shader->id); + pb.vertex_format(shader->vf); + pb.texture( + src_binding, + src, + sampler + ); + pb.cbuffer(config_binding, config.gpuonly); + Pipeline& pip = pb.build(); + quad.render(ctx, pip, pass, vert_binding); + } +}; + struct Config_Buffer { float offset[2]; }; @@ -579,8 +641,10 @@ struct C2 : public App { Fullscreen_Quad quad; Sky sky; Env_Probe eprobe; + Tonemap tonemap; Buffer_Id vbo, cbuf; Sampler_Id clamped_linear; + Texture_Id hdr_target; Line_Renderer lr; World* world; UI* ui; @@ -618,6 +682,7 @@ struct C2 : public App { assets.init(&asset_arena, "pack", 128); dev = Device::create(&video_arena, this); default_texture = make_default_texture(dev); + make_hdr_target(); model_loader.init(dev, &assets); mat_loader.init(&assets, default_texture); register_asset_loader("MODL", &model_loader); @@ -650,6 +715,7 @@ struct C2 : public App { scene.init(&scene_arena, 32, clamped_linear); sky.init(dev, &assets); eprobe.init(dev, &assets, 256); + tonemap.init(dev, &assets); camera.init(); { monkey = world->create_entity(); @@ -694,7 +760,7 @@ struct C2 : public App { Pipeline_Builder pb(&frame_arena, dev); pb.begin_rp(); - pb.rp_target(dev->get_backbuffer(), { r, 0x00, 0xff, 0xff }); + pb.rp_target(hdr_target, { r, 0x00, 0xff, 0xff }); Render_Pass& pass = pb.build_rp(); pb.begin(); @@ -737,20 +803,24 @@ struct C2 : public App { Render_Pass& depth_prepass = pb.build_rp(); pb.begin_rp(); - pb.rp_target(dev->get_backbuffer(), Clear_Mode::restore); + pb.rp_target(hdr_target, Clear_Mode::restore); pb.rp_depth_target(dev->get_depth_target(), Clear_Mode::restore); Render_Pass& pass2 = pb.build_rp(); pb.begin_rp(); - pb.rp_target(dev->get_backbuffer(), Clear_Mode::restore); + pb.rp_target(hdr_target, Clear_Mode::restore); pb.rp_depth_target(dev->get_depth_target(), Clear_Mode::restore); Render_Pass& sky_pass = pb.build_rp(); + pb.begin_rp(); + pb.rp_target(dev->get_backbuffer(), Clear_Mode::discard); + Render_Pass& tonemap_pass = pb.build_rp(); + ctx.debug_push("environment cube"); eprobe.render(dev, &frame_arena, quad, sky); ctx.debug_pop(); - Texture& bb = dev->get_texture(dev->get_backbuffer()); + Texture& bb = dev->get_texture(hdr_target); world->get<Transform>(monkey).mat = m4f::translate( m4f::identity(), v3f(0.0f, 0.0f, 0.0f) @@ -787,7 +857,21 @@ struct C2 : public App { quad, sky_pass, clamped_linear, - camera + camera, + hdr_target + ); + ctx.debug_pop(); + + tonemap.update(dev, 0.2f); + + ctx.debug_push("TONEMAP"); + tonemap.render( + dev, + &frame_arena, + quad, + tonemap_pass, + hdr_target, + clamped_linear ); ctx.debug_pop(); @@ -830,10 +914,12 @@ struct C2 : public App { sky.destroy(dev); lr.destroy(dev); eprobe.destroy(dev); + tonemap.destroy(dev); ui->destroy(); deinit_editor(); assets.destroy(); dev->destroy_texture(default_texture); + dev->destroy_texture(hdr_target); dev->destroy_sampler(clamped_linear); dev->destroy_buffer(vbo); dev->destroy_buffer(cbuf); @@ -843,6 +929,22 @@ struct C2 : public App { void on_resize() override { ui->layout(w, h); dev->on_resize(); + dev->destroy_texture(hdr_target); + make_hdr_target(); + } + + void make_hdr_target() { + hdr_target = dev->create_texture( + "HDR target", + texture_format_rgba16f, + Texture_Flags::sampleable | Texture_Flags::colour_target, + w, + h, + 1, + 1, + 1, + Buffer_Id(0) + ); } void on_text_input(const char* buf) override { |