rtx: add material mode enum, precursor for proper translucency handling

#173
This commit is contained in:
Ivan 'provod' Avdeev 2021-10-29 11:05:07 -07:00 committed by Ivan Avdeev
parent 29e8cce207
commit 24f11bccc7
5 changed files with 32 additions and 30 deletions

View File

@ -298,7 +298,7 @@ void main() {
const uint miss_index = 0;
const int ray_payload_loc = 0;
const float L = 10000.;
traceRayEXT(tlas, flags, GEOMETRY_BIT_ANY,
traceRayEXT(tlas, flags, GEOMETRY_BIT_OPAQUE,
sbt_offset, sbt_stride, miss_index,
origin, 0., direction, L,
ray_payload_loc);

View File

@ -21,8 +21,9 @@ layout (constant_id = 2) const uint MAX_VISIBLE_POINT_LIGHTS = 31;
layout (constant_id = 3) const uint MAX_VISIBLE_SURFACE_LIGHTS = 255;
#endif
#define GEOMETRY_BIT_ANY 0x01
#define GEOMETRY_BIT_OPAQUE 0x02
#define GEOMETRY_BIT_OPAQUE 0x01
#define GEOMETRY_BIT_ADDITIVE 0x02
#define GEOMETRY_BIT_ANY 0xff
struct Kusok {
uint index_offset;

View File

@ -31,9 +31,11 @@ typedef struct Kusok vk_kusok_data_t;
typedef struct {
matrix3x4 transform_row;
vk_ray_model_t *model;
int render_mode;
qboolean alpha_test;
qboolean translucent;
enum {
MaterialMode_Opaque,
MaterialMode_Opaque_AlphaTest,
MaterialMode_Additive,
} material_mode;
} vk_ray_draw_model_t;
typedef struct {

View File

@ -308,9 +308,8 @@ static void computeConveyorSpeed(const color24 rendercolor, int tex_index, vec2_
}
void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render_model, const matrix3x4 *transform_row, const vec4_t color, color24 entcolor) {
qboolean reflective = false;
qboolean HACK_reflective = false;
qboolean force_emissive = false;
qboolean additive = false;
vk_ray_draw_model_t* draw_model = g_ray_model_state.frame.models + g_ray_model_state.frame.num_models;
ASSERT(vk_core.rtx);
@ -326,46 +325,39 @@ void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render
{
ASSERT(model->as != VK_NULL_HANDLE);
draw_model->alpha_test = false;
draw_model->model = model;
draw_model->render_mode = render_model->render_mode;
memcpy(draw_model->transform_row, *transform_row, sizeof(draw_model->transform_row));
g_ray_model_state.frame.num_models++;
}
switch (render_model->render_mode) {
case kRenderNormal:
draw_model->material_mode = MaterialMode_Opaque;
break;
// C = (1 - alpha) * DST + alpha * SRC (TODO is this right?)
case kRenderTransColor:
case kRenderTransTexture:
reflective = true;
draw_model->alpha_test = true;
HACK_reflective = true;
draw_model->material_mode = MaterialMode_Opaque_AlphaTest; // FIXME add new translucency mode
break;
// Additive blending: C = SRC * alpha + DST
case kRenderGlow:
case kRenderTransAdd:
additive = true;
force_emissive = true;
draw_model->alpha_test = true;
draw_model->material_mode = MaterialMode_Additive;
break;
// Alpha test (TODO additive? mixing?)
case kRenderTransAlpha:
draw_model->alpha_test = true;
draw_model->material_mode = MaterialMode_Opaque_AlphaTest;
break;
default:
gEngine.Host_Error("Unexpected render mode %d\n", render_model->render_mode);
}
draw_model->translucent = false;
if (additive || color[3] < 1.f) {
draw_model->translucent = true;
}
for (int i = 0; i < render_model->num_geometries; ++i) {
const vk_render_geometry_t *geom = render_model->geometries + i;
const vk_emissive_surface_t *esurf = render_model->static_map ? NULL : VK_LightsAddEmissiveSurface( geom, transform_row, false );
@ -374,19 +366,13 @@ void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render
// HACK until there is proper specular
// FIXME also this erases previour roughness unconditionally
if (reflective)
if (HACK_reflective)
kusok->roughness = 0.f;
else
kusok->roughness = 1.f;
Vector4Copy(color, kusok->color);
if (additive) {
// Alpha zero means fully transparent -- no reflections, full refraction
// Together with force_emissive, this results in just adding emissive color
kusok->color[3] = 0.f;
}
if (esurf) {
VectorCopy(esurf->emissive, kusok->emissive);
} else if (force_emissive) {

View File

@ -472,11 +472,24 @@ static void prepareTlas( VkCommandBuffer cmdbuf ) {
ASSERT(model->model->as != VK_NULL_HANDLE);
inst[i] = (VkAccelerationStructureInstanceKHR){
.instanceCustomIndex = model->model->kusochki_offset,
.mask = (model->translucent ? 0 : GEOMETRY_BIT_OPAQUE) | GEOMETRY_BIT_ANY,
.instanceShaderBindingTableRecordOffset = model->alpha_test ? 1 : 0,
.flags = model->render_mode == kRenderNormal ? VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR : VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR, // TODO is render_mode a good indicator of transparency in general case?
.instanceShaderBindingTableRecordOffset = 0,
.accelerationStructureReference = getASAddress(model->model->as), // TODO cache this addr
};
switch (model->material_mode) {
case MaterialMode_Opaque:
inst[i].mask = GEOMETRY_BIT_OPAQUE;
inst[i].flags = VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR;
break;
case MaterialMode_Opaque_AlphaTest:
inst[i].mask = GEOMETRY_BIT_OPAQUE;
inst[i].instanceShaderBindingTableRecordOffset = 1,
inst[i].flags = VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR;
break;
case MaterialMode_Additive:
inst[i].mask = GEOMETRY_BIT_ADDITIVE;
inst[i].flags = VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR;
break;
}
memcpy(&inst[i].transform, model->transform_row, sizeof(VkTransformMatrixKHR));
}
}