summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorquou <quou@disroot.org>2025-01-09 22:53:40 +1100
committerquou <quou@disroot.org>2025-01-09 22:53:40 +1100
commit622e634e1cfd55dd875979a1f109a804d3dbe7ee (patch)
treed71ec2ff776221189a006b5ffc3a0ac78f3c664a
parentb3363b1716fbbb2af1b33b9bdd7a13f72016283d (diff)
mipmap the environment probe
-rw-r--r--Makefile6
-rw-r--r--c2.cpp134
-rw-r--r--intermediate/mip_spec.glsl44
-rw-r--r--intermediate/plastic.mat2
-rw-r--r--intermediate/surface.glsl4
-rw-r--r--video.cpp5
6 files changed, 166 insertions, 29 deletions
diff --git a/Makefile b/Makefile
index 3c7e3c5..358443e 100644
--- a/Makefile
+++ b/Makefile
@@ -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
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();
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) *
diff --git a/video.cpp b/video.cpp
index a0bbc2c..29afc6e 100644
--- a/video.cpp
+++ b/video.cpp
@@ -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;