summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile10
-rw-r--r--c2.cpp118
-rw-r--r--configure.lua1
-rw-r--r--intermediate/tonemap.glsl85
-rw-r--r--todo.txt1
5 files changed, 203 insertions, 12 deletions
diff --git a/Makefile b/Makefile
index b2fa152..8761134 100644
--- a/Makefile
+++ b/Makefile
@@ -101,12 +101,14 @@ data/surface.csh: intermediate/surface.glsl shadercompiler | data
./shadercompiler intermediate/surface.glsl data/surface.csh
data/surface_depthonly.csh: intermediate/surface_depthonly.glsl shadercompiler | data
./shadercompiler intermediate/surface_depthonly.glsl data/surface_depthonly.csh
+data/tonemap.csh: intermediate/tonemap.glsl shadercompiler | data
+ ./shadercompiler intermediate/tonemap.glsl data/tonemap.csh
data/triangle.csh: intermediate/triangle.glsl shadercompiler | data
./shadercompiler intermediate/triangle.glsl data/triangle.csh
data/ui.csh: intermediate/ui.glsl shadercompiler | data
./shadercompiler intermediate/ui.glsl data/ui.csh
-data/monkey.mdl: convmodel intermediate/monkey.glb data/debug.csh data/mip_spec.csh data/sky.csh data/surface.csh data/surface_depthonly.csh data/triangle.csh data/ui.csh | data
+data/monkey.mdl: convmodel intermediate/monkey.glb data/debug.csh data/mip_spec.csh data/sky.csh data/surface.csh data/surface_depthonly.csh data/tonemap.csh data/triangle.csh data/ui.csh | data
./convmodel data intermediate/monkey.glb data/monkey.mdl
data/22.tex: convtexture intermediate/22.bmp | data
@@ -127,8 +129,8 @@ data/bricks.mat: convmaterial intermediate/bricks.mat | data
data/plastic.mat: convmaterial intermediate/plastic.mat | data
./convmaterial intermediate/plastic.mat data/plastic.mat
-pack: packer data/debug.csh data/mip_spec.csh data/sky.csh data/surface.csh data/surface_depthonly.csh data/triangle.csh data/ui.csh data/monkey.mdl data/22.tex data/kita.tex data/brick_albedo.tex data/brick_ao.tex data/brick_normal.tex data/sky.tex data/bricks.mat data/plastic.mat
- ./packer pack data debug.csh mip_spec.csh sky.csh surface.csh surface_depthonly.csh triangle.csh ui.csh monkey.mdl 22.tex kita.tex brick_albedo.tex brick_ao.tex brick_normal.tex sky.tex bricks.mat plastic.mat
+pack: packer data/debug.csh data/mip_spec.csh data/sky.csh data/surface.csh data/surface_depthonly.csh data/tonemap.csh data/triangle.csh data/ui.csh data/monkey.mdl data/22.tex data/kita.tex data/brick_albedo.tex data/brick_ao.tex data/brick_normal.tex data/sky.tex data/bricks.mat data/plastic.mat
+ ./packer pack data debug.csh mip_spec.csh sky.csh surface.csh surface_depthonly.csh tonemap.csh triangle.csh ui.csh monkey.mdl 22.tex kita.tex brick_albedo.tex brick_ao.tex brick_normal.tex sky.tex bricks.mat plastic.mat
data:
mkdir -p data
@@ -136,7 +138,7 @@ data:
-include qstd/memory.d qstd/plat.d qstd/str.d qstd/pack.d cfg/cfgparse.d sc/sc.d sc/includer.d app.d asset.d c2.d camera.d debugdraw.d editor.d maths.d model.d pipeline.d scene.d ui.d video.d world.d convtexture.d convmodel.d convmaterial.d packer.d
clean:
- rm -f qstd/memory.o qstd/plat.o qstd/str.o qstd/pack.o cfg/cfgparse.o sc/sc.o sc/includer.o app.o asset.o c2.o camera.o debugdraw.o editor.o maths.o model.o pipeline.o scene.o ui.o video.o world.o convtexture.o convmodel.o convmaterial.o packer.o qstd/memory.d qstd/plat.d qstd/str.d qstd/pack.d cfg/cfgparse.d sc/sc.d sc/includer.d app.d asset.d c2.d camera.d debugdraw.d editor.d maths.d model.d pipeline.d scene.d ui.d video.d world.d convtexture.d convmodel.d convmaterial.d packer.d data/debug.csh data/mip_spec.csh data/sky.csh data/surface.csh data/surface_depthonly.csh data/triangle.csh data/ui.csh data/monkey.mdl data/22.tex data/kita.tex data/brick_albedo.tex data/brick_ao.tex data/brick_normal.tex data/sky.tex data/bricks.mat data/plastic.mat
+ rm -f qstd/memory.o qstd/plat.o qstd/str.o qstd/pack.o cfg/cfgparse.o sc/sc.o sc/includer.o app.o asset.o c2.o camera.o debugdraw.o editor.o maths.o model.o pipeline.o scene.o ui.o video.o world.o convtexture.o convmodel.o convmaterial.o packer.o qstd/memory.d qstd/plat.d qstd/str.d qstd/pack.d cfg/cfgparse.d sc/sc.d sc/includer.d app.d asset.d c2.d camera.d debugdraw.d editor.d maths.d model.d pipeline.d scene.d ui.d video.d world.d convtexture.d convmodel.d convmaterial.d packer.d data/debug.csh data/mip_spec.csh data/sky.csh data/surface.csh data/surface_depthonly.csh data/tonemap.csh data/triangle.csh data/ui.csh data/monkey.mdl data/22.tex data/kita.tex data/brick_albedo.tex data/brick_ao.tex data/brick_normal.tex data/sky.tex data/bricks.mat data/plastic.mat
rm -f shadercompiler
rmdir data
rm -f c2
diff --git a/c2.cpp b/c2.cpp
index 28e63b5..e8e6c82 100644
--- a/c2.cpp
+++ b/c2.cpp
@@ -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 {
diff --git a/configure.lua b/configure.lua
index ac95b4d..3d4a748 100644
--- a/configure.lua
+++ b/configure.lua
@@ -45,6 +45,7 @@ config = {
"sky",
"surface",
"surface_depthonly",
+ "tonemap",
"triangle",
"ui",
},
diff --git a/intermediate/tonemap.glsl b/intermediate/tonemap.glsl
new file mode 100644
index 0000000..5c41a6e
--- /dev/null
+++ b/intermediate/tonemap.glsl
@@ -0,0 +1,85 @@
+#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
+
+[struct]
+name: Config
+[variable]
+name: exposure
+type: float
+
+[cbuffer]
+name: config
+type: Config
+stage: fragment
+
+[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
+
+vec3 to_srgb(vec3 lin) {
+ bvec3 cutoff = lessThan(lin, 0.0031308.xxx);
+ vec3 higher = 1.055.xxx * pow(lin, vec3(1.0 / 2.4)) - 0.055.xxx;
+ vec3 lower = lin.rgb * 12.92.xxx;
+ return mix(higher, lower, cutoff);
+}
+
+vec3 aces(vec3 x) {
+ float a = 2.51;
+ float b = 0.03;
+ float c = 2.43;
+ float d = 0.59;
+ float e = 0.14;
+ return clamp(
+ (x * (a * x + b)) / (x * (c * x + d) + e),
+ 0.0,
+ 1.0f
+ );
+}
+
+vec3 hejl(vec3 x, float whitepoint) {
+ vec4 vh = vec4(x, whitepoint);
+ vec4 va = (1.425 * vh) + 0.05;
+ vec4 vf = ((vh * va + 0.004f) / ((vh * (va + 0.55f) + 0.0491f))) - 0.0821f;
+ return vf.rgb / vf.www;
+}
+
+void main() {
+ vec2 uv = interpolator.uv;
+ vec3 lin = texture(src, uv).rgb * config.exposure;
+ lin = hejl(lin, 1.0);
+ colour = vec4(to_srgb(lin), 1.0);
+}
+#endif
+
diff --git a/todo.txt b/todo.txt
index 984a251..5212343 100644
--- a/todo.txt
+++ b/todo.txt
@@ -18,6 +18,7 @@ todo list
- [x] material system
- [x] render a sky box
- [x] PBR + IBL
+ - [x] Tonemapping
- [ ] shadows
- [ ] MSAA
- [ ] GI