diff options
Diffstat (limited to 'c2.cpp')
-rw-r--r-- | c2.cpp | 114 |
1 files changed, 72 insertions, 42 deletions
@@ -285,13 +285,36 @@ struct Env_Probe { static constexpr int mip_count = 9; Texture_Id cubemap[2]; Texture_Id cubemap_depth; - Texture_Id faces[2][6][mip_count]; + Texture_Id faces_render[6]; + Texture_Id faces[6][mip_count]; Sampler_Id sampler; int cubemap_res; - int completed; Staged_Buffer config; + Staged_Buffer face_cb[6][mip_count]; Shader* shader; - int src_binding, vert_binding; + int src_binding, vert_binding, face_binding; + + struct Face_Cbuffer { + float dir[3]; + float roughness; + float up[3]; + }; + v3f face_dirs[6] = { + v3f( 1.0f, 0.0f, 0.0f), + v3f(-1.0f, 0.0f, 0.0f), + v3f( 0.0f, 1.0f, 0.0f), + v3f( 0.0f, -1.0f, 0.0f), + v3f( 0.0f, 0.0f, -1.0f), + v3f( 0.0f, 0.0f, 1.0f) + }; + v3f face_ups[6] = { + v3f(0.0f, 1.0f, 0.0f), + v3f(0.0f, 1.0f, 0.0f), + v3f(0.0f, 0.0f, 1.0f), + v3f(0.0f, 0.0f, -1.0f), + v3f(0.0f, 1.0f, 0.0f), + v3f(0.0f, 1.0f, 0.0f) + }; void init(Device* dev, Asset_Arena* assets, int res) { int i; @@ -345,22 +368,28 @@ struct Env_Probe { int j; int w = res; int h = res; + faces_render[i] = dev->alias_texture( + cubemap[0], + "env cubemap face A", + texture_format_rgba16f, + Texture_Flags::colour_target | + Texture_Flags::sampleable, + w, + h, + 1, + 1, + 1, + 0, + i + ); 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 + face_cb[i][j].init( + dev, + "env probe mip face cbuffer", + sizeof(Face_Cbuffer), + Buffer_Flags::constant_buffer ); - faces[1][i][j] = dev->alias_texture( + faces[i][j] = dev->alias_texture( cubemap[1], "env cubemap face B", texture_format_rgba16f, @@ -386,6 +415,7 @@ struct Env_Probe { ); shader = (Shader*)assets->load("mip_spec.csh"); src_binding = shader->descriptor_binding("src"); + face_binding = shader->descriptor_binding("c_face"); vert_binding = shader->binding_index("verts"); assert(src_binding >= 0); assert(vert_binding >= 0); @@ -396,9 +426,10 @@ struct Env_Probe { for (i = 0; i < 6; 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(faces[i][j]); + face_cb[i][j].destroy(dev); } + dev->destroy_texture(faces_render[i]); } dev->destroy_texture(cubemap_depth); dev->destroy_sampler(sampler); @@ -417,25 +448,9 @@ struct Env_Probe { 0.1f, 1000.0f ).inverse(); - v3f dirs[] = { - v3f( 1.0f, 0.0f, 0.0f), - v3f(-1.0f, 0.0f, 0.0f), - v3f( 0.0f, 1.0f, 0.0f), - v3f( 0.0f, -1.0f, 0.0f), - v3f( 0.0f, 0.0f, -1.0f), - v3f( 0.0f, 0.0f, 1.0f) - }; - v3f ups[] = { - v3f(0.0f, 1.0f, 0.0f), - v3f(0.0f, 1.0f, 0.0f), - v3f(0.0f, 0.0f, 1.0f), - v3f(0.0f, 0.0f, -1.0f), - v3f(0.0f, 1.0f, 0.0f), - v3f(0.0f, 1.0f, 0.0f) - }; for (i = 0; i < 6; i++) { Sky::Cbuffer& buf = bufs[i]; - m4f view = m4f::lookat(v3f(0.0f), dirs[i], ups[i]); + m4f view = m4f::lookat(v3f(0.0f), face_dirs[i], face_ups[i]); buf.iview = view.inverse(); buf.iprojection = iproj; } @@ -449,8 +464,21 @@ struct Env_Probe { Context& ctx = dev->get_ctx(); update_cbuffer(dev); for (i = 0; i < 6; i++) { + int j; + for (j = 0; j < mip_count; j++) { + Face_Cbuffer* cb = (Face_Cbuffer*)face_cb[i][j].map(dev); + cb->dir[0] = face_dirs[i].x; + cb->dir[1] = face_dirs[i].y; + cb->dir[2] = face_dirs[i].z; + cb->roughness = (float)j / (float)(mip_count - 1); + cb->up[0] = face_ups[i].x; + cb->up[1] = face_ups[i].y; + cb->up[2] = face_ups[i].z; + face_cb[i][j].unmap(dev); + face_cb[i][j].update(ctx); + } pb.begin_rp(); - pb.rp_target(faces[0][i][0], Clear_Mode::discard); + pb.rp_target(faces_render[i], Clear_Mode::discard); pb.rp_depth_target(cubemap_depth, 1.0f); sky.render_imp( dev, @@ -463,20 +491,23 @@ 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]); + Texture& t = dev->get_texture(faces[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.cbuffer( + face_binding, + face_cb[i][j].gpuonly + ); pb.texture( src_binding, - faces[completed][i][0], + cubemap[0], sampler ); pb.shader(shader->id); @@ -495,11 +526,10 @@ struct Env_Probe { ctx.submit(draw, pip, pass); } } - completed = 1; } Texture_Id get_cubemap() { - return cubemap[completed]; + return cubemap[1]; } }; |