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.
This commit is contained in:
Ivan 'provod' Avdeev 2023-02-14 12:35:23 -08:00 committed by Ivan Avdeev
parent eaf8b3c55a
commit 4dd793569c
3 changed files with 29 additions and 17 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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);
}