From ab9ed1ccadbd2c1b971bfbfb5ee651aa03a4a63e Mon Sep 17 00:00:00 2001 From: quou Date: Sat, 22 Feb 2025 18:16:05 +1100 Subject: shader globals --- c2.cpp | 2 +- intermediate/forward.h | 44 ++++++++++++++++++++++++++++++++++++++++++++ intermediate/surface.glsl | 36 +++++++----------------------------- model.cpp | 29 ++++++++++------------------- model.hpp | 16 +++++----------- renderer.cpp | 36 ++++++++++++++++++++++++++++++++++-- renderer.hpp | 4 ++++ scene.cpp | 4 +--- scene.hpp | 3 --- 9 files changed, 106 insertions(+), 68 deletions(-) create mode 100644 intermediate/forward.h diff --git a/c2.cpp b/c2.cpp index 761d9de..ac9e7d4 100644 --- a/c2.cpp +++ b/c2.cpp @@ -896,7 +896,7 @@ struct C2 : public App { orbit_cam.update_orbit(*this); pcam.update(); lighting.update(dev, ctx, *world, renderer, scene); - update_scene(scene, dev, lighting, pcam, *world); + update_scene(scene, dev, *world); lr.add_box(scene.bound); ctx.debug_push("scene"); renderer.render( diff --git a/intermediate/forward.h b/intermediate/forward.h new file mode 100644 index 0000000..7c4c9d3 --- /dev/null +++ b/intermediate/forward.h @@ -0,0 +1,44 @@ +#ifndef forward_h +#define forward_h +#ifdef DESC + +[struct] +name: Light +[variable] +name: dir +type: vec3 +[variable] +name: brightness +type: float +[variable] +name: colour +type: vec3 +[variable] +name: caster_id +type: int + +[struct] +name: Caster +[variable] +name: projection +type: mat4 + +[struct] +name: Globals +[variable] +name: camera_pos +type: vec3 +[variable] +name: light_count +type: int +[variable] +name: frame +type: int + +[cbuffer] +name: globals +type: Globals +stage: fragment + +#endif +#endif diff --git a/intermediate/surface.glsl b/intermediate/surface.glsl index 10944ae..71a4307 100644 --- a/intermediate/surface.glsl +++ b/intermediate/surface.glsl @@ -3,6 +3,11 @@ type: graphics vertex: main fragment: main +#endif + +#include "forward.h" + +#ifdef DESC [binding] name: mesh @@ -56,33 +61,6 @@ type: float [variable] name: ao type: float -[variable] -name: light_count -type: int -[variable] -name: camera_pos -type: vec3 - -[struct] -name: Light -[variable] -name: dir -type: vec3 -[variable] -name: brightness -type: float -[variable] -name: colour -type: vec3 -[variable] -name: caster_id -type: int - -[struct] -name: Caster -[variable] -name: projection -type: mat4 [cbuffer] name: c_vp @@ -251,7 +229,7 @@ void main() { nrm = normalize(interpolator.tbn * nrm); vec3 col = texture(albedo, uv).rgb * material.albedo; - vec3 view_dir = normalize(material.camera_pos - p); + vec3 view_dir = normalize(globals.camera_pos - p); float met = texture(metal, uv).r * material.metalness; vec3 ref = reflect(-view_dir, nrm); vec3 ref_col = texture(env_cube, ref, material.roughness * 8.0).rgb; @@ -264,7 +242,7 @@ void main() { vec3 base_diffuse = diffuse_brdf(uv) * (1.0 - met); vec3 light = 0.0.xxx; - for (i = 0; i < material.light_count; i++) { + for (i = 0; i < globals.light_count; i++) { Light l = lights[i]; vec3 light_dir = l.dir; float cos_theta_i = max(dot(nrm, light_dir), 0.0); diff --git a/model.cpp b/model.cpp index 765da15..f24c0eb 100644 --- a/model.cpp +++ b/model.cpp @@ -24,10 +24,7 @@ struct Mat_Cbuffer { float metalness; float roughness; float ao; - int light_count; - char pad2[4]; - float camera_pos[3]; - char pad[20]; + char pad[40]; }; void Material::use( @@ -137,6 +134,7 @@ Asset* Model_Loader::load( mesh.mat_binding = shader->descriptor_binding("material"); mesh.light_binding = shader->descriptor_binding("lights"); mesh.casters_binding = shader->descriptor_binding("casters"); + mesh.globals_binding = shader->descriptor_binding("globals"); mesh.shadowmaps_binding = shader->descriptor_binding("shadowmaps"); mesh.env_cube_binding = shader->descriptor_binding("env_cube"); mesh.mesh_binding = shader->binding_index("mesh"); @@ -147,6 +145,7 @@ Asset* Model_Loader::load( assert(mesh.mat_binding >= 0); assert(mesh.light_binding >= 0); assert(mesh.casters_binding >= 0); + assert(mesh.globals_binding >= 0); assert(mesh.shadowmaps_binding >= 0); assert(mesh.mesh_binding >= 0); assert(mesh.env_cube_binding >= 0); @@ -311,11 +310,7 @@ void Model_Instance::update() { } } -void Model_Instance::update_cbuffers( - Device* dev, - const Lighting& lighting, - const Camera& cam -) { +void Model_Instance::update_cbuffers(Device* dev) { int i, c = m->mesh_count; Mesh* meshes = m->get_meshes(); Model_Cbuffer* mcbs = (Model_Cbuffer*)dev->map_buffer( @@ -338,10 +333,6 @@ void Model_Instance::update_cbuffers( mat.metalness = sm.metalness; mat.roughness = sm.roughness; mat.ao = sm.ao; - mat.light_count = lighting.light_count; - mat.camera_pos[0] = cam.position.x; - mat.camera_pos[1] = cam.position.y; - mat.camera_pos[2] = cam.position.z; } dev->unmap_buffer(mcb); dev->unmap_buffer(mat); @@ -421,6 +412,10 @@ void Model_Instance::render( res.sampler ); } + pb.cbuffer( + mesh.globals_binding, + res.globals + ); pb.cull(Cull_Mode::back); pb.vertex_format(shader.vf); if (res.overrider) @@ -470,18 +465,14 @@ void Model_Scene::uninstantiate( count = last; } -void Model_Scene::update( - const Camera& cam, - const Lighting& lighting, - Device* dev -) { +void Model_Scene::update(Device* dev) { int i; Model_Instance* instance = instances; bound.min = v3f( INFINITY); bound.max = v3f(-INFINITY); for (i = 0; i < count; i++, instance++) { instance->update(); - instance->update_cbuffers(dev, lighting, cam); + instance->update_cbuffers(dev); bound.encompass(instance->bound); } } diff --git a/model.hpp b/model.hpp index e7b07e6..7417e51 100644 --- a/model.hpp +++ b/model.hpp @@ -40,7 +40,8 @@ struct Mesh { mat_binding, light_binding, shadowmaps_binding, - casters_binding; + casters_binding, + globals_binding; int env_cube_binding; bool world_dirty; m4f world, local; @@ -98,6 +99,7 @@ struct Model_Resources { Texture_Id env_cubemap; Sampler_Id sampler; Buffer_Id vp; + Buffer_Id globals; void (*overrider)(Pipeline_Builder&); }; @@ -112,11 +114,7 @@ struct Model_Instance { void init(Device* dev, Heap* h, Model* model); void destroy(Device* dev, Heap* h); void update(); - void update_cbuffers( - Device* dev, - const Lighting& lighting, - const Camera& cam - ); + void update_cbuffers(Device* dev); void render( Device* dev, Arena* a, @@ -138,11 +136,7 @@ struct Model_Scene { void destroy(Device* dev); void init(Arena* arena, int max_instances, Sampler_Id s); - void update( - const Camera& cam, - const Lighting& lighting, - Device* dev - ); + void update(Device* dev); }; #endif diff --git a/renderer.cpp b/renderer.cpp index cc7cc6d..d8c4895 100644 --- a/renderer.cpp +++ b/renderer.cpp @@ -9,6 +9,12 @@ struct VP_Cbuffer { m4f view_projection; }; +struct Global_Cbuffer { + v3f camera_pos; + int light_count; + int frame; +}; + void init_drawlist( Drawlist* l, Device* d, @@ -40,12 +46,20 @@ void Renderer::init(Arena* arena, Device* d) { id(i, 512); camera_count = 1; cameras.init(); + globals.init( + d, + "Renderer globals", + sizeof(Global_Cbuffer), + Buffer_Flags::constant_buffer + ); + frame = 0; } void Renderer::destroy(Device* d) { int i; for (i = 0; i < drawlist_count; i++) drawlists[i].vp.destroy(d); + globals.destroy(d); } void Renderer::set_camera(Camera_Id cam, int drawlist) { @@ -70,22 +84,39 @@ void Drawlist::render( res.sampler = r.clamped_linear; res.env_cubemap = r.env_cubemap; res.vp = vp.gpuonly; + res.globals = r.globals.gpuonly; res.overrider = overrider; for (i = 0; i < c; i++) { models[i]->render(dev, a, pass, l, res); } } +void Renderer::update_globals( + const Lighting* l, + Device* d, + Context& ctx +) { + void* ptr = globals.map(d); + Global_Cbuffer* cb = (Global_Cbuffer*)ptr; + v3f& cp = get_camera(drawlists[FORWARD].camera).position; + cb->camera_pos = cp; + cb->frame = frame; + cb->light_count = l->light_count; + globals.unmap(d); + globals.update(ctx); +} + void Renderer::render( Device* dev, - Arena* a, - Texture_Id hdr_target, + Arena* a, Texture_Id hdr_target, const Lighting* l ) { int i, j; Pipeline_Builder pb(a, dev); Context& ctx = dev->get_ctx(); + update_globals(l, dev, ctx); + Render_Pass& depth_prepass = pb .begin_rp() .rp_depth_target(dev->get_depth_target(), 1.0f) @@ -126,6 +157,7 @@ void Renderer::render( ctx.debug_push("forward"); drawlists[FORWARD].render(*this, dev, a, l, forward_pass, 0); ctx.debug_pop(); + frame++; } void Renderer::add_model(int drawlist, Model_Instance* m) { diff --git a/renderer.hpp b/renderer.hpp index ae638e0..c49c804 100644 --- a/renderer.hpp +++ b/renderer.hpp @@ -36,7 +36,9 @@ struct Renderer { static constexpr int max_cameras = 16; Hash_Map cameras; Drawlist drawlists[drawlist_count]; + Staged_Buffer globals; int camera_count; + int frame; Sampler_Id clamped_linear; Texture_Id env_cubemap; @@ -60,6 +62,8 @@ struct Renderer { const Camera& get_camera(Camera_Id cam) const; void destroy_camera(Camera_Id cam); void setcam(int did, Camera_Id cam); + + void update_globals(const Lighting* l, Device* d, Context& ctx); }; #endif diff --git a/scene.cpp b/scene.cpp index d162eda..53d06dd 100644 --- a/scene.cpp +++ b/scene.cpp @@ -5,8 +5,6 @@ void update_scene( Model_Scene& ms, Device* dev, - const Lighting& lighting, - const Camera& cam, World& w ) { for (auto v : w.view()) { @@ -14,7 +12,7 @@ void update_scene( auto& m = v.get(); m.i->transform = t.mat; } - ms.update(cam, lighting, dev); + ms.update(dev); } std::pair scene_pick( diff --git a/scene.hpp b/scene.hpp index 6706899..8056e54 100644 --- a/scene.hpp +++ b/scene.hpp @@ -9,7 +9,6 @@ struct Arena; struct Camera; -struct Lighting; struct Model_Instance; struct Model_Scene; struct World; @@ -25,8 +24,6 @@ struct C_Model { void update_scene( Model_Scene& ms, Device* dev, - const Lighting& lighting, - const Camera& cam, World& w ); std::pair scene_pick( -- cgit v1.2.3-54-g00ecf