From 6c46c024aca49d4b35c0d10c7fa910e37d2703f9 Mon Sep 17 00:00:00 2001 From: Ivan Avdeev Date: Thu, 27 Apr 2023 11:22:05 -0700 Subject: [PATCH] rt: add very basic support for emissive textures They only affect what's visible on screen and bounces. They don't participate in lighting directly as light sources. Adding them as light sources is a bit trickier (and more expensive too). Arbitrary model with arbitrary emissive textures support would be very difficult, especially wrt sampling strategies. --- ref/vk/shaders/ray_interop.h | 8 ++++++-- ref/vk/shaders/ray_primary_hit.glsl | 7 ++++++- ref/vk/vk_materials.c | 6 ++++++ ref/vk/vk_materials.h | 2 ++ ref/vk/vk_ray_model.c | 2 ++ 5 files changed, 22 insertions(+), 3 deletions(-) diff --git a/ref/vk/shaders/ray_interop.h b/ref/vk/shaders/ray_interop.h index ad16f3d955..a33f1999cb 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 9f7d157e8f..50302bbdc5 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 4e9cf2830b..8f7cb2634f 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 3eec91c736..17b9fa278c 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 c97e917407..161b43b3bd 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;