summaryrefslogtreecommitdiff
path: root/c2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'c2.cpp')
-rw-r--r--c2.cpp134
1 files changed, 111 insertions, 23 deletions
diff --git a/c2.cpp b/c2.cpp
index c9ab715..2d4ad14 100644
--- a/c2.cpp
+++ b/c2.cpp
@@ -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();