vk: rt: pass material mode directly from draw command

Different render sources (model types, render types, etc) might require
different material modes. E.g. brush should be translucent (refractive+mirror)
for blend mix modes. However, smoke particles should not be
mirror/refractive for the same blend mix render type.
This commit is contained in:
Ivan Avdeev 2023-09-26 13:14:28 -04:00
parent f63dcd14ce
commit b07c5c3740
7 changed files with 59 additions and 7 deletions

View File

@ -534,6 +534,33 @@ static qboolean brushCreateWaterModel(const model_t *mod, vk_brush_model_t *bmod
return true;
}
material_mode_e brushMaterialModeForRenderType(vk_render_type_e render_type) {
switch (render_type) {
case kVkRenderTypeSolid:
return kMaterialMode_Opaque;
break;
case kVkRenderType_A_1mA_RW: // blend: scr*a + dst*(1-a), depth: RW
case kVkRenderType_A_1mA_R: // blend: scr*a + dst*(1-a), depth test
return kMaterialMode_Translucent;
break;
case kVkRenderType_A_1: // blend: scr*a + dst, no depth test or write; sprite:kRenderGlow only
return kMaterialMode_BlendGlow;
break;
case kVkRenderType_A_1_R: // blend: scr*a + dst, depth test
case kVkRenderType_1_1_R: // blend: scr + dst, depth test
return kMaterialMode_BlendAdd;
break;
case kVkRenderType_AT: // no blend, depth RW, alpha test
return kMaterialMode_AlphaTest;
break;
default:
gEngine.Host_Error("Unexpected render type %d\n", render_type);
}
return kMaterialMode_Opaque;
}
static void brushDrawWater(vk_brush_model_t *bmodel, const cl_entity_t *ent, int render_type, const vec4_t color, const matrix4x4 transform) {
APROF_SCOPE_DECLARE_BEGIN(brush_draw_water, __FUNCTION__);
ASSERT(bmodel->water.surfaces_count > 0);
@ -543,8 +570,10 @@ static void brushDrawWater(vk_brush_model_t *bmodel, const cl_entity_t *ent, int
ERR("Failed to update brush model \"%s\" water", bmodel->render_model.debug_name);
}
const material_mode_e material_mode = brushMaterialModeForRenderType(render_type);
R_RenderModelDraw(&bmodel->water.render_model, (r_model_draw_t){
.render_type = render_type,
.material_mode = material_mode,
.color = (const vec4_t*)color,
.transform = (const matrix4x4*)transform,
.prev_transform = &bmodel->prev_transform,
@ -751,8 +780,10 @@ void VK_BrushModelDraw( const cl_entity_t *ent, int render_mode, float blend, co
APROF_SCOPE_END(brush_update_textures);
}
const material_mode_e material_mode = brushMaterialModeForRenderType(render_type);
R_RenderModelDraw(&bmodel->render_model, (r_model_draw_t){
.render_type = render_type,
.material_mode = material_mode,
.color = &color,
.transform = &transform,
.prev_transform = &bmodel->prev_transform,

View File

@ -99,7 +99,7 @@ static qboolean uploadKusochkiSubset(const vk_ray_model_t *const model, const vk
// TODO this material mapping is context dependent. I.e. different entity types might need different ray tracing behaviours for
// same render_mode/type and even texture.
static uint32_t materialModeFromRenderType(vk_render_type_e render_type) {
uint32_t R_VkMaterialModeFromRenderType(vk_render_type_e render_type) {
switch (render_type) {
case kVkRenderTypeSolid:
return MATERIAL_MODE_OPAQUE;
@ -328,7 +328,7 @@ void RT_FrameAddModel( struct rt_model_s *model, rt_frame_add_model_t args ) {
draw_instance->blas_addr = model->blas_addr;
draw_instance->kusochki_offset = kusochki_offset;
draw_instance->material_mode = materialModeFromRenderType(args.render_type);
draw_instance->material_mode = args.material_mode;
Vector4Copy(*args.color, draw_instance->color);
Matrix3x4_Copy(draw_instance->transform_row, args.transform);
Matrix4x4_Copy(draw_instance->prev_transform_row, args.prev_transform);
@ -430,7 +430,8 @@ tail:
}
void RT_FrameAddOnce( rt_frame_add_once_t args ) {
const int material_mode = materialModeFromRenderType(args.render_type);
// TODO pass material_mode explicitly
const int material_mode = R_VkMaterialModeFromRenderType(args.render_type);
rt_dynamic_t *const dyn = g_dyn.groups + material_mode;
for (int i = 0; i < args.geometries_count; ++i) {

View File

@ -781,7 +781,7 @@ void R_RenderModelDraw(const vk_render_model_t *model, r_model_draw_t args) {
if (g_render_state.current_frame_is_ray_traced) {
ASSERT(model->rt_model);
RT_FrameAddModel(model->rt_model, (rt_frame_add_model_t){
.render_type = args.render_type,
.material_mode = args.material_mode,
.transform = (const matrix3x4*)args.transform,
.prev_transform = (const matrix3x4*)args.prev_transform,
.color = args.color,

View File

@ -77,6 +77,20 @@ typedef enum {
kVkRenderType_COUNT
} vk_render_type_e;
typedef enum {
// MUST be congruent to MATERIAL_MODE_* definitions in shaders/ray_interop.h
kMaterialMode_Opaque = 0,
kMaterialMode_AlphaTest = 1,
kMaterialMode_Translucent = 2,
kMaterialMode_BlendAdd = 3,
kMaterialMode_BlendMix = 4,
kMaterialMode_BlendGlow = 5,
kMaterialMode_COUNT = 6,
} material_mode_e;
uint32_t R_VkMaterialModeFromRenderType(vk_render_type_e render_type);
struct rt_light_add_polygon_s;
struct rt_model_s;
@ -120,7 +134,8 @@ qboolean R_RenderModelUpdate( const vk_render_model_t *model );
qboolean R_RenderModelUpdateMaterials( const vk_render_model_t *model, const int *geom_indices, int geom_indices_count);
typedef struct {
vk_render_type_e render_type;
vk_render_type_e render_type; // TODO rename legacy
material_mode_e material_mode;
// These are "consumed": copied into internal storage and can be pointers to stack vars
const vec4_t *color;

View File

@ -56,7 +56,7 @@ qboolean RT_ModelUpdate(struct rt_model_s *model, const struct vk_render_geometr
qboolean RT_ModelUpdateMaterials(struct rt_model_s *model, const struct vk_render_geometry_s *geometries, int geometries_count, const int *geom_indices, int geom_indices_count);
typedef struct {
int render_type; // TODO material_mode
int material_mode;
const matrix3x4 *transform, *prev_transform;
const vec4_t *color;

View File

@ -804,9 +804,11 @@ static void R_DrawSpriteQuad( const char *debug_name, const mspriteframe_t *fram
const vk_render_type_e render_type = spriteRenderModeToRenderType(render_mode);
const r_vk_material_t material_override = R_VkMaterialGetForTexture(texture);
const material_mode_e material_mode = R_VkMaterialModeFromRenderType(render_type);
R_RenderModelDraw(&g_sprite.quad.model, (r_model_draw_t){
.render_type = render_type,
.material_mode = material_mode,
.color = (const vec4_t*)color,
.transform = &transform,
.prev_transform = &transform,

View File

@ -2304,8 +2304,11 @@ static void R_StudioDrawPoints( void ) {
Vector4Set(color, g_studio.blend, g_studio.blend, g_studio.blend, 1.f);
// TODO r_model_draw_t.transform should be matrix3x4
const vk_render_type_e render_type = studioRenderModeToRenderType(RI.currententity->curstate.rendermode);
const material_mode_e material_mode = R_VkMaterialModeFromRenderType(render_type);
R_RenderModelDraw(&render_submodel->model, (r_model_draw_t){
.render_type = studioRenderModeToRenderType(RI.currententity->curstate.rendermode),
.render_type = render_type,
.material_mode = material_mode,
.color = &color,
.transform = &g_studio_current.entmodel->transform,
.prev_transform = &g_studio_current.entmodel->prev_transform,