From 4dd793569c014b6e22b0124d81d40e2d6a8126e0 Mon Sep 17 00:00:00 2001 From: Ivan 'provod' Avdeev Date: Tue, 14 Feb 2023 12:35:23 -0800 Subject: [PATCH] rt: add alpha-quality alpha blending Do translucency in bounce stage. It's not great, but lets us see thing through. Also fix reading OOB uninitialized memory for color/alpha. --- ref_vk/shaders/bounce.comp | 40 +++++++++++++++++++++------------ ref_vk/shaders/ray_primary.comp | 2 +- ref_vk/vk_ray_model.c | 4 ++-- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/ref_vk/shaders/bounce.comp b/ref_vk/shaders/bounce.comp index a3f9c2e8..550c0216 100644 --- a/ref_vk/shaders/bounce.comp +++ b/ref_vk/shaders/bounce.comp @@ -12,7 +12,8 @@ layout(set=0, binding=1) uniform accelerationStructureEXT tlas; #define RAY_LIGHT_DIRECT_INPUTS(X) \ X(10, position_t, rgba32f) \ X(11, normals_gs, rgba16f) \ - X(12, material_rmxx, rgba8) + X(12, material_rmxx, rgba8) \ + X(13, base_color_a, rgba8) #define X(index, name, format) layout(set=0,binding=index,format) uniform readonly image2D name; RAY_LIGHT_DIRECT_INPUTS(X) #undef X @@ -92,9 +93,10 @@ void computeBounce(ivec2 pix, vec3 direction, out vec3 diffuse, out vec3 specula specular = vec3(0.); const vec4 material_data = imageLoad(material_rmxx, pix); + const vec4 base_a = imageLoad(base_color_a, pix); MaterialProperties material; - material.baseColor = vec3(1.); + material.baseColor = vec3(1.f); material.emissive = vec3(0.f); material.metalness = material_data.g; material.roughness = material_data.r; @@ -103,31 +105,40 @@ void computeBounce(ivec2 pix, vec3 direction, out vec3 diffuse, out vec3 specula readNormals(pix, geometry_normal, shading_normal); const float ray_normal_fudge = .01; - const vec3 pos = imageLoad(position_t, pix).xyz + geometry_normal * ray_normal_fudge; vec3 throughput = vec3(1.); // 1. Make a "random" material-based ray for diffuse lighting vec3 bounce_direction = vec3(0.); - vec3 brdf_weight = vec3(0.); int brdf_type = DIFFUSE_TYPE; - if (material.metalness == 1.0f && material.roughness == 0.0f) { - // Fast path for mirrors + const float alpha = (base_a.a); + if (1. > alpha && rand01() > alpha) { brdf_type = SPECULAR_TYPE; + // TODO: when not sampling randomly: throughput *= (1. - base_a.a); + bounce_direction = normalize(refract(direction, geometry_normal, .95)); + geometry_normal = -geometry_normal; + //throughput /= base_a.rgb; } else { - // Decide whether to sample diffuse or specular BRDF (based on Fresnel term) - const float brdf_probability = getBrdfProbability(material, -direction, shading_normal); - if (rand01() < brdf_probability) { + if (material.metalness == 1.0f && material.roughness == 0.0f) { + // Fast path for mirrors brdf_type = SPECULAR_TYPE; - throughput /= brdf_probability; + } else { + // Decide whether to sample diffuse or specular BRDF (based on Fresnel term) + const float brdf_probability = getBrdfProbability(material, -direction, shading_normal); + if (rand01() < brdf_probability) { + brdf_type = SPECULAR_TYPE; + throughput /= brdf_probability; + } } + + const vec2 u = vec2(rand01(), rand01()); + vec3 brdf_weight = vec3(0.); + if (!evalIndirectCombinedBRDF(u, shading_normal, geometry_normal, -direction, material, brdf_type, bounce_direction, brdf_weight)) + return; + throughput *= brdf_weight; } - const vec2 u = vec2(rand01(), rand01()); - if (!evalIndirectCombinedBRDF(u, shading_normal, geometry_normal, -direction, material, brdf_type, bounce_direction, brdf_weight)) - return; const float throughput_threshold = 1e-3; - throughput *= brdf_weight; if (dot(throughput, throughput) < throughput_threshold) return; @@ -136,6 +147,7 @@ void computeBounce(ivec2 pix, vec3 direction, out vec3 diffuse, out vec3 specula RayPayloadPrimary payload; payload.base_color_a = vec4(0.); payload.emissive = vec4(0.); + const vec3 pos = imageLoad(position_t, pix).xyz + geometry_normal * ray_normal_fudge; if (!getHit(pos, bounce_direction, payload)) return; diff --git a/ref_vk/shaders/ray_primary.comp b/ref_vk/shaders/ray_primary.comp index 4f45b9a1..fc34f2e3 100644 --- a/ref_vk/shaders/ray_primary.comp +++ b/ref_vk/shaders/ray_primary.comp @@ -54,7 +54,7 @@ void main() { //| gl_RayFlagsSkipClosestHitShaderEXT ; float L = 10000.; // TODO Why 10k? - rayQueryInitializeEXT(rq, tlas, flags, GEOMETRY_BIT_OPAQUE | GEOMETRY_BIT_ALPHA_TEST, origin, 0., direction, L); + rayQueryInitializeEXT(rq, tlas, flags, GEOMETRY_BIT_OPAQUE | GEOMETRY_BIT_ALPHA_TEST | GEOMETRY_BIT_REFRACTIVE, origin, 0., direction, L); while (rayQueryProceedEXT(rq)) { if (0 != (rayQueryGetRayFlagsEXT(rq) & gl_RayFlagsOpaqueEXT)) continue; diff --git a/ref_vk/vk_ray_model.c b/ref_vk/vk_ray_model.c index b0586b11..f55a55a6 100644 --- a/ref_vk/vk_ray_model.c +++ b/ref_vk/vk_ray_model.c @@ -153,7 +153,7 @@ void XVK_RayModel_Validate( void ) { } } -static void applyMaterialToKusok(vk_kusok_data_t* kusok, const vk_render_geometry_t *geom, const vec3_t color, qboolean HACK_reflective) { +static void applyMaterialToKusok(vk_kusok_data_t* kusok, const vk_render_geometry_t *geom, const vec4_t color, qboolean HACK_reflective) { const xvk_material_t *const mat = XVK_GetMaterialForTextureIndex( geom->texture ); ASSERT(mat); @@ -299,7 +299,7 @@ vk_ray_model_t* VK_RayModelCreate( vk_ray_model_init_t args ) { kusochki[i].tex_base_color &= (~KUSOK_MATERIAL_FLAG_SKYBOX); } - const vec3_t color = {1, 1, 1}; + const vec4_t color = {1, 1, 1, 1}; applyMaterialToKusok(kusochki + i, mg, color, false); Matrix4x4_LoadIdentity(kusochki[i].prev_transform); }