diff --git a/assets/shaders/gradient.comp.spv b/assets/shaders/gradient.comp.spv index 6fdb516..241bd2c 100644 Binary files a/assets/shaders/gradient.comp.spv and b/assets/shaders/gradient.comp.spv differ diff --git a/assets/shaders/pbr.frag.spv b/assets/shaders/pbr.frag.spv index f91b9e3..799cd64 100644 Binary files a/assets/shaders/pbr.frag.spv and b/assets/shaders/pbr.frag.spv differ diff --git a/assets/shaders/pbr.vert.spv b/assets/shaders/pbr.vert.spv index 1a9aa13..fec4902 100644 Binary files a/assets/shaders/pbr.vert.spv and b/assets/shaders/pbr.vert.spv differ diff --git a/src/VulkanRenderer b/src/VulkanRenderer index c42238a..748c8ec 160000 --- a/src/VulkanRenderer +++ b/src/VulkanRenderer @@ -1 +1 @@ -Subproject commit c42238a456f5048c7d1b2d5ebd71ecf13bb10ece +Subproject commit 748c8ec00e098ba2a55ba1a6b831ed6f5b63f85a diff --git a/src/dlib b/src/dlib index 493c17c..292bb10 160000 --- a/src/dlib +++ b/src/dlib @@ -1 +1 @@ -Subproject commit 493c17cba26952861ae4c5402f1676013b8317c6 +Subproject commit 292bb10214869da59a8fcaeda9bfce813ac28ad7 diff --git a/src/gears/game2.d b/src/gears/game2.d index 7a80349..5bed4ec 100644 --- a/src/gears/game2.d +++ b/src/gears/game2.d @@ -21,6 +21,9 @@ struct RenderState Arena[2] frame_arenas; Arena perm_arena; + u64 frame; + u64 frame_idx; + PushConst pc; ShaderGlobals globals; @@ -36,8 +39,9 @@ struct RenderState Buffer[] model_states; u64 itex, imat, istate; - ImageView placeholder_tex; - Buffer globals_buffer; + Descriptor default_tex; + Descriptor default_mat; + Descriptor[2] globals_buffer; } struct ShaderGlobals @@ -49,12 +53,29 @@ struct ShaderGlobals f32 alpha = 0.0; } -struct ModelRenderInfo +struct Model { - PushConst pc; - PipelineID pid; + Buffer vtx_buf; + Buffer idx_buf; + Descriptor[] tex; + Descriptor[] mats; + PipelineID[] mat_pipelines; + DescSet[] resource_sets; + Mesh[] meshes; +} - alias pc this; +struct RenderObject +{ + Model* model; + Descriptor[2] state_descs; + ModelState[2] state; + DescSet[2] state_sets; + bool[2] pending_update; +} + +struct Entity +{ + Model* model; } struct ModelState @@ -64,45 +85,59 @@ struct ModelState enum PBRMod : u32 { - AlbedoValue = 0x0001, - AmbientValue = 0x0002, - SpecularValue = 0x0004, - AlphaValue = 0x0008, - AlbedoTexture = 0x0010, - AmbientTexture = 0x0020, - SpecularTexture = 0x0040, - AlphaTexture = 0x0080, + None = 0x000, + AlbedoTexture = 0x001, + NormalTexture = 0x002, + MetalRoughTexture = 0x004, + OcclusionTexture = 0x008, + EmissionTexture = 0x010, } -enum PipelineID : u32 +enum PipelineID { None, - PBRVVVV, - PBRTVVV, - PBRVTVV, - PBRVVTV, - PBRVVVT, - PBRTTVV, - PBRTVTV, - PBRTVVT, - PBRVTTV, - PBRVTVT, - PBRVVTT, - PBRVTTT, - PBRTVTT, - PBRTTVT, - PBRTTTV, - PBRTTTT, + PBRVVVVV, + PBRTVVVV, + PBRVTVVV, + PBRTTVVV, + PBRVVTVV, + PBRTVTVV, + PBRVTTVV, + PBRTTTVV, + PBRVVVTV, + PBRTVVTV, + PBRVTVTV, + PBRTTVTV, + PBRVVTTV, + PBRTVTTV, + PBRVTTTV, + PBRTTTTV, + PBRVVVVT, + PBRTVVVT, + PBRVTVVT, + PBRTTVVT, + PBRVVTVT, + PBRTVTVT, + PBRVTTVT, + PBRTTTVT, + PBRVVVTT, + PBRTVVTT, + PBRVTVTT, + PBRTTVTT, + PBRVVTTT, + PBRTVTTT, + PBRVTTTT, + PBRTTTTT, Max, } alias PID = PipelineID; const PID[] PBR_PIPELINES = [ - PID.PBRVVVV, PID.PBRTVVV, PID.PBRVTVV, PID.PBRVVTV, - PID.PBRVVVT, PID.PBRTTVV, PID.PBRTVTV, PID.PBRTVVT, - PID.PBRVTTV, PID.PBRVTVT, PID.PBRVVTT, PID.PBRTTTV, - PID.PBRTTVT, PID.PBRTVTT, PID.PBRVTTT, PID.PBRTTTT, + PID.PBRVVVVV, PID.PBRTVVVV, PID.PBRVTVVV, PID.PBRTTVVV, PID.PBRVVTVV, PID.PBRTVTVV, PID.PBRVTTVV, PID.PBRTTTVV, + PID.PBRVVVTV, PID.PBRTVVTV, PID.PBRVTVTV, PID.PBRTTVTV, PID.PBRVVTTV, PID.PBRTVTTV, PID.PBRVTTTV, PID.PBRTTTTV, + PID.PBRVVVVT, PID.PBRTVVVT, PID.PBRVTVVT, PID.PBRTTVVT, PID.PBRVVTVT, PID.PBRTVTVT, PID.PBRVTTVT, PID.PBRTTTVT, + PID.PBRVVVTT, PID.PBRTVVTT, PID.PBRVTVTT, PID.PBRTTVTT, PID.PBRVVTTT, PID.PBRTVTTT, PID.PBRVTTTT, PID.PBRTTTTT, ]; struct PushConst @@ -130,12 +165,22 @@ struct PushConst } } -ModelData g_box; +Model g_model; +RenderObject g_object; void RunCycle(GameState* g) { + BeginFrame(&g.rds.rd); + BeginRendering(&g.rds.rd); + Render(&g.rds, &g_object); + + FinishRendering(&g.rds.rd); + SubmitAndPresent(&g.rds.rd); + + g.rds.frame += 1; + g.rds.frame_idx = g.rds.frame % 2; } GameState @@ -175,7 +220,7 @@ Init(RenderState* rds, PlatformWindow* window) { binding: 1, descriptorType: DT.Image, descriptorCount: 1, stageFlags: SS.All }, { binding: 2, descriptorType: DT.Image, descriptorCount: 1, stageFlags: SS.All }, { binding: 3, descriptorType: DT.Image, descriptorCount: 1, stageFlags: SS.All }, - { binding: 4, descriptorType: DT.Uniform, descriptorCount: 1, stageFlags: SS.All }, + { binding: 4, descriptorType: DT.Image, descriptorCount: 1, stageFlags: SS.All }, { binding: 5, descriptorType: DT.Uniform, descriptorCount: 1, stageFlags: SS.All }, ]; @@ -209,7 +254,7 @@ Init(RenderState* rds, PlatformWindow* window) rds.desc_set_globals[i] = AllocDescSet(&rds.rd, rds.desc_layout_globals); } - u32[4] spec_data; + u32[5] spec_data; Specialization spec = { data: spec_data.ptr, @@ -219,6 +264,7 @@ Init(RenderState* rds, PlatformWindow* window) { constantID: 1, size: u32.sizeof, offset: u32.sizeof*1 }, { constantID: 2, size: u32.sizeof, offset: u32.sizeof*2 }, { constantID: 3, size: u32.sizeof, offset: u32.sizeof*3 }, + { constantID: 4, size: u32.sizeof, offset: u32.sizeof*4 }, ], }; @@ -237,59 +283,198 @@ Init(RenderState* rds, PlatformWindow* window) { u32 mod = PIDToPBR(pid); spec_data[0] = mod & PBRMod.AlbedoTexture; - spec_data[1] = mod & PBRMod.AmbientTexture; - spec_data[2] = mod & PBRMod.SpecularTexture; - spec_data[3] = mod & PBRMod.AlphaTexture; + spec_data[1] = mod & PBRMod.NormalTexture; + spec_data[2] = mod & PBRMod.MetalRoughTexture; + spec_data[3] = mod & PBRMod.OcclusionTexture; + spec_data[4] = mod & PBRMod.EmissionTexture; bool result = CreateGraphicsPipeline(&rds.rd, &rds.pipelines[pid], &pbr_info); assert(result); } - const u64 tex_size = 32*32*4; - u8[tex_size] placeholder_tex; - - u8[4] magenta = [255, 0, 255, 255]; - u8[4] black = [0, 0, 0, 255]; - u64 half = tex_size/2; - for(u64 i = 0; i < tex_size; i += 32) - { - bool swap = i <= half; - for(u64 j = 0; j < 16; j += 4) - { - placeholder_tex[i+j .. i+j+4] = !swap ? magenta[0 .. $] : black[0 .. $]; - placeholder_tex[i+j+16 .. i+j+16+4] = !swap ? black[0 .. $] : magenta[0 .. $]; - } - } - - CreateImageView(&rds.rd, &rds.placeholder_tex, 32, 32, 4, placeholder_tex); - - CreateBuffer(&rds.rd, &rds.globals_buffer, BT.Uniform, ShaderGlobals.sizeof, false); + CreateBuffer(&rds.rd, &rds.globals_buffer[0], BT.Uniform, ShaderGlobals.sizeof, false, DT.Uniform); + CreateBuffer(&rds.rd, &rds.globals_buffer[1], BT.Uniform, ShaderGlobals.sizeof, false, DT.Uniform); ModelData md = LoadGLTF(&rds.frame_arenas[0], "assets/models/DamagedHelmet.glb"); + + rds.default_tex = Upload(rds, &DEFAULT_IMAGE); + + CreateBuffer(&rds.rd, &rds.default_mat, BT.Uniform, Material.sizeof, false, DT.Uniform); + + bool result = Transfer(&rds.rd, &rds.default_mat.buf, &DEFAULT_MATERIAL); + assert(result); + + g_model = Upload(rds, &md); + g_object = CreateRenderObject(rds, &g_model); +} + +void +Render(RenderState* rds, RenderObject* obj) +{ + DescSet[3] sets; + sets[0] = rds.desc_set_globals[rds.frame_idx]; + sets[2] = obj.state_sets[rds.frame_idx]; + + BindBuffers(&rds.rd, &obj.model.idx_buf, &obj.model.vtx_buf); + foreach(i; 0 .. obj.model.meshes.length) + { + Mesh* mesh = obj.model.meshes.ptr + i; + + sets[1] = obj.model.resource_sets[i]; + + Bind(&rds.rd, rds.pipelines[obj.model.mat_pipelines[mesh.mat_id]], sets, false); + DrawIndexed(&rds.rd, mesh.length, 1, mesh.offset); + } +} + +Descriptor +Upload(RenderState* rds, ImageData* image) +{ + Descriptor desc; + CreateImageView(&rds.rd, &desc, image.w, image.h, image.ch, image.data, DT.Image); + return desc; +} + +Model +Upload(RenderState* rds, ModelData* md) +{ + Model model = { + meshes: md.meshes, + }; + + CreateBuffer(&rds.rd, &model.vtx_buf, BT.Vertex, Vertex.sizeof*md.vtx_buf.length, false); + CreateBuffer(&rds.rd, &model.idx_buf, BT.Index, u32.sizeof*md.idx_buf.length, false); + + bool result = true; + result &= Transfer(&rds.rd, &model.vtx_buf, md.vtx_buf); + result &= Transfer(&rds.rd, &model.idx_buf, md.idx_buf); + + assert(result, "Failed to transfer vtx/idx buffer"); + + model.tex = Alloc!(Descriptor)(md.tex.length); + model.mats = Alloc!(Descriptor)(md.mats.length); + model.mat_pipelines = Alloc!(PipelineID)(md.mats.length); + model.resource_sets = Alloc!(DescSet)(md.mats.length); + + model.tex[0] = rds.default_tex; + model.mats[0] = rds.default_mat; + model.mat_pipelines[0] = PID.PBRVVVVV; + + foreach(i; 1 .. md.tex.length) + { + CreateImageView(&rds.rd, &model.tex[i], md.tex[i].w, md.tex[i].h, md.tex[i].ch, md.tex[i].data, DT.Image); + } + + foreach(i; 1 .. md.mats.length) + { + MaterialMap[] maps = md.mats[i].maps; + + bool albedo = maps[MMI.Albedo].tex_id > 0, + normal = maps[MMI.Normal].tex_id > 0, + metal_rough = maps[MMI.Metallic].tex_id > 0, + occlusion = maps[MMI.Occlusion].tex_id > 0, + emission = maps[MMI.Emission].tex_id > 0; + + model.resource_sets[i] = AllocDescSet(&rds.rd, rds.desc_layout_resources); + model.mat_pipelines[i] = GetPBRID(albedo, normal, metal_rough, occlusion, emission); + + CreateBuffer(&rds.rd, &model.mats[i], BT.Uniform, Material.sizeof, false, DT.Uniform); + + result = Transfer(&rds.rd, &model.mats[i].buf, &md.mats[i]); + assert(result); + + Descriptor[6] descs = [ + model.tex[maps[MMI.Albedo].tex_id], + model.tex[maps[MMI.Normal].tex_id], + model.tex[maps[MMI.Metallic].tex_id], + model.tex[maps[MMI.Occlusion].tex_id], + model.tex[maps[MMI.Emission].tex_id], + model.mats[i], + ]; + + foreach(j; 0 .. descs.length) + { + descs[j].binding = cast(u32)j; + } + + Write(&rds.rd, model.resource_sets[i], descs); + } + + return model; +} + +RenderObject +CreateRenderObject(RenderState* rds, Model* model) +{ + RenderObject rdobj = { + model: model, + state: [DefaultModelState(), DefaultModelState()], + }; + + foreach(i; 0 .. 2) + { + CreateBuffer(&rds.rd, &rdobj.state_descs[i], BT.Uniform, ModelState.sizeof, false, DT.Uniform); + bool result = Transfer(&rds.rd, &rdobj.state_descs[i].buf, &rdobj.state[i]); + + rdobj.state_sets[i] = AllocDescSet(&rds.rd, rds.desc_layout_state); + Write(&rds.rd, rdobj.state_sets[i], &rdobj.state_descs[i]); + } + + return rdobj; +} + +ModelState +DefaultModelState() +{ + return ModelState( + matrix: Mat4Identity(), + ); +} + +PipelineID +GetPBRID(bool albedo, bool normal, bool metal_rough, bool occlusion, bool emission) +{ + return PBRToPID(GetPBRMod(albedo, normal, metal_rough, occlusion, emission)); } PipelineID PBRToPID(u32 mod) { - switch(mod) + switch(mod) with(PID) { - case GetPBRMod(false, false, false, false): return PID.PBRVVVV; - case GetPBRMod(true , false, false, false): return PID.PBRTVVV; - case GetPBRMod(false, true , false, false): return PID.PBRVTVV; - case GetPBRMod(false, false, true , false): return PID.PBRVVTV; - case GetPBRMod(false, false, false, true ): return PID.PBRVVVT; - case GetPBRMod(true , true , false, false): return PID.PBRTTVV; - case GetPBRMod(true , false, true , false): return PID.PBRTVTV; - case GetPBRMod(true , false, false, true ): return PID.PBRTVVT; - case GetPBRMod(false, true , true , false): return PID.PBRVTTV; - case GetPBRMod(false, true , false, true ): return PID.PBRVTVT; - case GetPBRMod(false, false, true , true ): return PID.PBRVVTT; - case GetPBRMod(false, true , true , true ): return PID.PBRVTTT; - case GetPBRMod(true , false, true , true ): return PID.PBRTVTT; - case GetPBRMod(true , true , false, true ): return PID.PBRTTVT; - case GetPBRMod(true , true , true , false): return PID.PBRTTTV; - case GetPBRMod(true , true , true , true ): return PID.PBRTTTT; - default: return PID.None; + case GetPBRMod(false, false, false, false, false): return PBRVVVVV; + case GetPBRMod(true , false, false, false, false): return PBRTVVVV; + case GetPBRMod(false, true , false, false, false): return PBRVTVVV; + case GetPBRMod(true , true , false, false, false): return PBRTTVVV; + case GetPBRMod(false, false, true , false, false): return PBRVVTVV; + case GetPBRMod(true , false, true , false, false): return PBRTVTVV; + case GetPBRMod(false, true , true , false, false): return PBRVTTVV; + case GetPBRMod(true , true , true , false, false): return PBRTTTVV; + case GetPBRMod(false, false, false, true , false): return PBRVVVTV; + case GetPBRMod(true , false, false, true , false): return PBRTVVTV; + case GetPBRMod(false, true , false, true , false): return PBRVTVTV; + case GetPBRMod(true , true , false, true , false): return PBRTTVTV; + case GetPBRMod(false, false, true , true , false): return PBRVVTTV; + case GetPBRMod(true , false, true , true , false): return PBRTVTTV; + case GetPBRMod(false, true , true , true , false): return PBRVTTTV; + case GetPBRMod(true , true , true , true , false): return PBRTTTTV; + case GetPBRMod(false, false, false, false, true ): return PBRVVVVT; + case GetPBRMod(true , false, false, false, true ): return PBRTVVVT; + case GetPBRMod(false, true , false, false, true ): return PBRVTVVT; + case GetPBRMod(true , true , false, false, true ): return PBRTTVVT; + case GetPBRMod(false, false, true , false, true ): return PBRVVTVT; + case GetPBRMod(true , false, true , false, true ): return PBRTVTVT; + case GetPBRMod(false, true , true , false, true ): return PBRVTTVT; + case GetPBRMod(true , true , true , false, true ): return PBRTTTVT; + case GetPBRMod(false, false, false, true , true ): return PBRVVVTT; + case GetPBRMod(true , false, false, true , true ): return PBRTVVTT; + case GetPBRMod(false, true , false, true , true ): return PBRVTVTT; + case GetPBRMod(true , true , false, true , true ): return PBRTTVTT; + case GetPBRMod(false, false, true , true , true ): return PBRVVTTT; + case GetPBRMod(true , false, true , true , true ): return PBRTVTTT; + case GetPBRMod(false, true , true , true , true ): return PBRVTTTT; + case GetPBRMod(true , true , true , true , true ): return PBRTTTTT; + default: return None; } } @@ -298,36 +483,53 @@ PIDToPBR(PipelineID pid) { switch(pid) with(PID) { - case PBRVVVV: return GetPBRMod(false, false, false, false); - case PBRTVVV: return GetPBRMod(true , false, false, false); - case PBRVTVV: return GetPBRMod(false, true , false, false); - case PBRVVTV: return GetPBRMod(false, false, true , false); - case PBRVVVT: return GetPBRMod(false, false, false, true ); - case PBRTTVV: return GetPBRMod(true , true , false, false); - case PBRTVTV: return GetPBRMod(true , false, true , false); - case PBRTVVT: return GetPBRMod(true , false, false, true ); - case PBRVTTV: return GetPBRMod(false, true , true , false); - case PBRVTVT: return GetPBRMod(false, true , false, true ); - case PBRVVTT: return GetPBRMod(false, false, true , true ); - case PBRTTTV: return GetPBRMod(true , true , true , false); - case PBRTTVT: return GetPBRMod(true , true , false, true ); - case PBRTVTT: return GetPBRMod(true , false, true , true ); - case PBRVTTT: return GetPBRMod(false, true , true , true ); - case PBRTTTT: return GetPBRMod(true , true , true , true ); - default: return 0; + case PBRVVVVV: return GetPBRMod(false, false, false, false, false); + case PBRTVVVV: return GetPBRMod(true , false, false, false, false); + case PBRVTVVV: return GetPBRMod(false, true , false, false, false); + case PBRTTVVV: return GetPBRMod(true , true , false, false, false); + case PBRVVTVV: return GetPBRMod(false, false, true , false, false); + case PBRTVTVV: return GetPBRMod(true , false, true , false, false); + case PBRVTTVV: return GetPBRMod(false, true , true , false, false); + case PBRTTTVV: return GetPBRMod(true , true , true , false, false); + case PBRVVVTV: return GetPBRMod(false, false, false, true , false); + case PBRTVVTV: return GetPBRMod(true , false, false, true , false); + case PBRVTVTV: return GetPBRMod(false, true , false, true , false); + case PBRTTVTV: return GetPBRMod(true , true , false, true , false); + case PBRVVTTV: return GetPBRMod(false, false, true , true , false); + case PBRTVTTV: return GetPBRMod(true , false, true , true , false); + case PBRVTTTV: return GetPBRMod(false, true , true , true , false); + case PBRTTTTV: return GetPBRMod(true , true , true , true , false); + case PBRVVVVT: return GetPBRMod(false, false, false, false, true ); + case PBRTVVVT: return GetPBRMod(true , false, false, false, true ); + case PBRVTVVT: return GetPBRMod(false, true , false, false, true ); + case PBRTTVVT: return GetPBRMod(true , true , false, false, true ); + case PBRVVTVT: return GetPBRMod(false, false, true , false, true ); + case PBRTVTVT: return GetPBRMod(true , false, true , false, true ); + case PBRVTTVT: return GetPBRMod(false, true , true , false, true ); + case PBRTTTVT: return GetPBRMod(true , true , true , false, true ); + case PBRVVVTT: return GetPBRMod(false, false, false, true , true ); + case PBRTVVTT: return GetPBRMod(true , false, false, true , true ); + case PBRVTVTT: return GetPBRMod(false, true , false, true , true ); + case PBRTTVTT: return GetPBRMod(true , true , false, true , true ); + case PBRVVTTT: return GetPBRMod(false, false, true , true , true ); + case PBRTVTTT: return GetPBRMod(true , false, true , true , true ); + case PBRVTTTT: return GetPBRMod(false, true , true , true , true ); + case PBRTTTTT: return GetPBRMod(true , true , true , true , true ); + default: return 0; } } static u32 -GetPBRMod(bool albedo = false, bool ambient = false, bool specular = false, bool alpha = false) +GetPBRMod(bool albedo = false, bool normal = false, bool metal_rough = false, bool occlusion = false, bool emission = false) { with(PBRMod) { return - (albedo ? AlbedoTexture : AlbedoValue) | - (ambient ? AmbientTexture : AmbientValue) | - (specular ? SpecularTexture : SpecularValue) | - (alpha ? AlphaTexture : AlphaValue); + (albedo ? AlbedoTexture : None) | + (normal ? NormalTexture : None) | + (metal_rough ? MetalRoughTexture : None) | + (occlusion ? OcclusionTexture : None) | + (emission ? EmissionTexture : None); } } diff --git a/src/shaders/structures.layout b/src/shaders/structures.layout index fafab1a..5b9a729 100644 --- a/src/shaders/structures.layout +++ b/src/shaders/structures.layout @@ -1,17 +1,38 @@ -// DEFINES +// TYPES -#define OIT_LAYERS 16 +#define u32 uint +#define i32 int +#define b32 bool +#define f32 float +#define f64 double -#define IMG_MAX 100 -#define BUF_MAX 25 -#define UNI_MAX 50 +// CONSTANTS + +const u32 OIT_LAYERS = 16; +const u32 IMG_MAX = 100; +const u32 BUF_MAX = 25; +const u32 UNI_MAX = 50; + +const u32 MAT_ALBEDO = 0; +const u32 MAT_NORMAL = 1; +const u32 MAT_METALLIC = 2; +const u32 MAT_ROUGHNESS = 3; +const u32 MAT_OCCLUSION = 4; +const u32 MAT_EMISSION = 5; +const u32 MAT_HEIGHT = 6; +const u32 MAT_CUBEMAP = 7; +const u32 MAT_IRRADIANCE = 8; +const u32 MAT_PREFILTER = 9; +const u32 MAT_BRDF = 10; +const u32 MAT_MAX = 11; // SPEC CONSTANTS -layout (constant_id = 0) const bool ALBEDO_TEX = false; -layout (constant_id = 1) const bool AMBIENT_TEX = false; -layout (constant_id = 2) const bool SPECULAR_TEX = false; -layout (constant_id = 3) const bool ALPHA_TEX = false; +layout (constant_id = 0) const bool ALBEDO_TEX = false; +layout (constant_id = 1) const bool NORMAL_TEX = false; +layout (constant_id = 2) const bool METALLIC_ROUGHNESS_TEX = false; +layout (constant_id = 3) const bool OCCLUSION_TEX = false; +layout (constant_id = 4) const bool EMISSION_TEX = false; // SET 0 @@ -34,16 +55,15 @@ layout (set = 1, binding = 2, r32ui) uniform coherent uimage2D ImageAux; // SET 2 layout (set = 2, binding = 0) uniform texture2D AlbedoTex; -layout (set = 2, binding = 1) uniform texture2D AmbientTex; -layout (set = 2, binding = 2) uniform texture2D SpecularTex; -layout (set = 2, binding = 3) uniform texture2D AlphaTex; -layout (set = 2, binding = 4) uniform MaterialData { - vec4 ambient; - vec4 diffuse; - vec4 specular; - float shininess; - float alpha; -} Material; +layout (set = 2, binding = 1) uniform texture2D NormalTex; +layout (set = 2, binding = 2) uniform texture2D MRTex; // Metallic Roughness +layout (set = 2, binding = 3) uniform texture2D OcclusionTex; +layout (set = 2, binding = 4) uniform texture2D EmissionTex; +layout (set = 2, binding = 5) uniform MaterialData { + vec4 col; + u32 padding; + f32 value; +} Material[MAT_MAX]; layout (set = 3, binding = 0) uniform ModelState { mat4 model_matrix; @@ -52,19 +72,20 @@ layout (set = 3, binding = 0) uniform ModelState { // PUSH CONSTANTS layout (push_constant) uniform PushConstants { - uint t0; - uint t1; - uint t2; - uint t3; - uint m0; - uint s0; + u32 t0; + u32 t1; + u32 t2; + u32 t3; + u32 m0; + u32 s0; } PC; // ALIAS MACROS -#define ModelMatrix State.model_matrix -#define ModelAmbient Material.ambient -#define ModelDiffuse Material.diffuse -#define ModelSpecular Material.specular -#define ModelShininess Material.shininess -#define ModelAlpha Material.alpha +#define ModelMatrix State.model_matrix +#define Albedo Material[MAT_ALBEDO].col; +#define Metallic(uv) texture(sampler2D(MRTex, SamplerNearest), uv).b +#define Roughness(uv) texture(sampler2D(MRTex, SamplerNearest), uv).g +#define MetallicFactor Material[MAT_METALLIC].value +#define RoughnessFactor Material[MAT_ROUGHNESS].value +#define EmissiveFactor Material[MAT_EMISSION].value