diff --git a/ref/vk/shaders/ray_interop.h b/ref/vk/shaders/ray_interop.h index ad16f3d9..a33f1999 100644 --- a/ref/vk/shaders/ray_interop.h +++ b/ref/vk/shaders/ray_interop.h @@ -80,18 +80,22 @@ struct Material { uint tex_base_color; - // TODO can be combined into a single texture + // TODO these three can be combined into a single texture uint tex_roughness; uint tex_metalness; uint tex_normalmap; + uint tex_emissive; + // TODO: - // uint tex_emissive; // uint tex_detail; float roughness; float metalness; float normal_scale; + float emissive_scale; + + PAD(2) }; struct ModelMetadata { diff --git a/ref/vk/shaders/ray_primary_hit.glsl b/ref/vk/shaders/ray_primary_hit.glsl index 9f7d157e..50302bbd 100644 --- a/ref/vk/shaders/ray_primary_hit.glsl +++ b/ref/vk/shaders/ray_primary_hit.glsl @@ -62,7 +62,12 @@ void primaryRayHit(rayQueryEXT rq, inout RayPayloadPrimary payload) { //payload.emissive.rgb = kusok.emissive * SRGBtoLINEAR(payload.base_color_a.rgb); //payload.emissive.rgb = clamp((kusok.emissive * (1.0/3.0) / 20), 0, 1.0) * SRGBtoLINEAR(payload.base_color_a.rgb); //payload.emissive.rgb = (sqrt(sqrt(kusok.emissive)) * (1.0/3.0)) * SRGBtoLINEAR(payload.base_color_a.rgb); - payload.emissive.rgb = (sqrt(kusok.emissive) / 8) * SRGBtoLINEAR(payload.base_color_a.rgb); + if (material.tex_emissive == 0) { + payload.emissive.rgb = (sqrt(kusok.emissive) / 8) * SRGBtoLINEAR(payload.base_color_a.rgb); + } else { + const vec3 emissive = sampleTexture(material.tex_emissive, geom.uv, geom.uv_lods).rgb; + payload.emissive.rgb = kusok.material.emissive_scale * emissive; + } #else // Fake texture color if (any(greaterThan(kusok.emissive, vec3(0.)))) diff --git a/ref/vk/vk_materials.c b/ref/vk/vk_materials.c index 4e9cf283..8f7cb263 100644 --- a/ref/vk/vk_materials.c +++ b/ref/vk/vk_materials.c @@ -13,10 +13,12 @@ static xvk_material_t k_default_material = { .tex_metalness = 0, .tex_roughness = 0, .tex_normalmap = 0, + .tex_emissive = 0, .metalness = 0.f, .roughness = 1.f, .normal_scale = 1.f, + .emissive_scale = 1.f, .base_color = { 1.f, 1.f, 1.f, 1.f }, .set = false, @@ -153,6 +155,8 @@ static void loadMaterialsFromFile( const char *filename, int depth ) { tex_id_dest = ¤t_material.tex_metalness; } else if (Q_stricmp(key, "roughness_map") == 0) { tex_id_dest = ¤t_material.tex_roughness; + } else if (Q_stricmp(key, "emissive_map") == 0) { + tex_id_dest = ¤t_material.tex_emissive; } else if (Q_stricmp(key, "roughness") == 0) { sscanf(value, "%f", ¤t_material.roughness); } else if (Q_stricmp(key, "metalness") == 0) { @@ -160,6 +164,8 @@ static void loadMaterialsFromFile( const char *filename, int depth ) { metalness_set = true; } else if (Q_stricmp(key, "normal_scale") == 0) { sscanf(value, "%f", ¤t_material.normal_scale); + } else if (Q_stricmp(key, "emissive") == 0) { + sscanf(value, "%f", ¤t_material.emissive_scale); } else if (Q_stricmp(key, "base_color") == 0) { sscanf(value, "%f %f %f %f", ¤t_material.base_color[0], ¤t_material.base_color[1], ¤t_material.base_color[2], ¤t_material.base_color[3]); } else { diff --git a/ref/vk/vk_materials.h b/ref/vk/vk_materials.h index 3eec91c7..17b9fa27 100644 --- a/ref/vk/vk_materials.h +++ b/ref/vk/vk_materials.h @@ -7,11 +7,13 @@ typedef struct { int tex_roughness; int tex_metalness; int tex_normalmap; + int tex_emissive; vec4_t base_color; float roughness; float metalness; float normal_scale; + float emissive_scale; qboolean set; } xvk_material_t; diff --git a/ref/vk/vk_ray_model.c b/ref/vk/vk_ray_model.c index c97e9174..161b43b3 100644 --- a/ref/vk/vk_ray_model.c +++ b/ref/vk/vk_ray_model.c @@ -172,10 +172,12 @@ static void applyMaterialToKusok(vk_kusok_data_t* kusok, const vk_render_geometr .tex_roughness = mat->tex_roughness, .tex_metalness = mat->tex_metalness, .tex_normalmap = mat->tex_normalmap, + .tex_emissive = mat->tex_emissive, .roughness = mat->roughness, .metalness = mat->metalness, .normal_scale = mat->normal_scale, + .emissive_scale = mat->emissive_scale, }; const qboolean HACK_chrome = geom->material == kXVkMaterialChrome;