rt: commoditize setting material mode
Known issues: - Breaks sprite glow for some reason.
This commit is contained in:
parent
5b370509fe
commit
1ebc1d207c
|
@ -140,8 +140,7 @@ bool shadowedSky(vec3 pos, vec3 dir) {
|
|||
const uint kusok_index = instance_kusochki_offset + geometry_index;
|
||||
const Kusok kusok = getKusok(kusok_index);
|
||||
|
||||
// TODO this flag can be encoded into custom index, so that we'd need no extra indirection
|
||||
if ((kusok.material.flags & KUSOK_MATERIAL_FLAG_SKYBOX) == 0)
|
||||
if (kusok.material.mode != MATERIAL_MODE_SKYBOX)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ LIST_SPECIALIZATION_CONSTANTS(DECLARE_SPECIALIZATION_CONSTANT)
|
|||
|
||||
#define GEOMETRY_BIT_OPAQUE 0x01
|
||||
#define GEOMETRY_BIT_ALPHA_TEST 0x02
|
||||
#define GEOMETRY_BIT_ADDITIVE 0x04
|
||||
#define GEOMETRY_BIT_BLEND 0x04
|
||||
#define GEOMETRY_BIT_REFRACTIVE 0x08
|
||||
|
||||
#define SHADER_OFFSET_MISS_REGULAR 0
|
||||
|
@ -63,11 +63,16 @@ LIST_SPECIALIZATION_CONSTANTS(DECLARE_SPECIALIZATION_CONSTANT)
|
|||
#define SHADER_OFFSET_HIT_REGULAR_BASE 0
|
||||
#define SHADER_OFFSET_HIT_SHADOW_BASE 3
|
||||
|
||||
#define KUSOK_MATERIAL_FLAG_SKYBOX (1<<0)
|
||||
#define KUSOK_MATERIAL_FLAG_FIXME_GLOW (1<<1)
|
||||
#define MATERIAL_MODE_OPAQUE 0
|
||||
#define MATERIAL_MODE_OPAQUE_ALPHA_TEST 1
|
||||
#define MATERIAL_MODE_TRANSLUCENT 2
|
||||
#define MATERIAL_MODE_BLEND_ADD 3
|
||||
#define MATERIAL_MODE_BLEND_MIX 4
|
||||
#define MATERIAL_MODE_BLEND_GLOW 5
|
||||
#define MATERIAL_MODE_SKYBOX 6
|
||||
|
||||
struct Material {
|
||||
uint flags;
|
||||
uint mode;
|
||||
|
||||
uint tex_base_color;
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ void main() {
|
|||
|
||||
const Kusok kusok = getKusok(geom.kusok_index);
|
||||
|
||||
if ((kusok.material.flags & KUSOK_MATERIAL_FLAG_SKYBOX) != 0) {
|
||||
if (kusok.material.mode == MATERIAL_MODE_SKYBOX) {
|
||||
payload.emissive.rgb = SRGBtoLINEAR(texture(skybox, gl_WorldRayDirectionEXT).rgb);
|
||||
return;
|
||||
} else {
|
||||
|
|
|
@ -30,7 +30,7 @@ void primaryRayHit(rayQueryEXT rq, inout RayPayloadPrimary payload) {
|
|||
const Kusok kusok = getKusok(geom.kusok_index);
|
||||
const Material material = kusok.material;
|
||||
|
||||
if ((kusok.material.flags & KUSOK_MATERIAL_FLAG_SKYBOX) != 0) {
|
||||
if (kusok.material.mode == MATERIAL_MODE_SKYBOX) {
|
||||
payload.emissive.rgb = SRGBtoLINEAR(texture(skybox, rayDirection).rgb);
|
||||
return;
|
||||
} else {
|
||||
|
|
|
@ -12,5 +12,5 @@ void main() {
|
|||
const Kusok kusok = getKusok(kusok_index);
|
||||
const uint tex_base_color = kusok.material.tex_base_color;
|
||||
|
||||
payload_shadow.hit_type = ((kusok.material.flags & KUSOK_MATERIAL_FLAG_SKYBOX) == 0) ? SHADOW_HIT : SHADOW_SKY ;
|
||||
payload_shadow.hit_type = (kusok.material.mode != MATERIAL_MODE_SKYBOX) ? SHADOW_HIT : SHADOW_SKY ;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ vec3 traceAdditive(vec3 pos, vec3 dir, float L) {
|
|||
//| gl_RayFlagsSkipClosestHitShaderEXT
|
||||
| gl_RayFlagsNoOpaqueEXT // force all to be non-opaque
|
||||
;
|
||||
rayQueryInitializeEXT(rq, tlas, flags, GEOMETRY_BIT_ADDITIVE, pos, 0., dir, L + additive_soft_overshoot);
|
||||
rayQueryInitializeEXT(rq, tlas, flags, GEOMETRY_BIT_BLEND, pos, 0., dir, L + additive_soft_overshoot);
|
||||
while (rayQueryProceedEXT(rq)) {
|
||||
const MiniGeometry geom = readCandidateMiniGeometry(rq);
|
||||
const Kusok kusok = getKusok(geom.kusok_index);
|
||||
|
@ -23,7 +23,7 @@ vec3 traceAdditive(vec3 pos, vec3 dir, float L) {
|
|||
|
||||
if (overshoot < 0.)
|
||||
ret += color;
|
||||
else if ((kusok.material.flags & KUSOK_MATERIAL_FLAG_FIXME_GLOW) != 0)
|
||||
else if (kusok.material.mode == MATERIAL_MODE_BLEND_GLOW)
|
||||
ret += color * smoothstep(additive_soft_overshoot, 0., overshoot);
|
||||
}
|
||||
return ret;
|
||||
|
|
|
@ -189,26 +189,32 @@ void RT_VkAccelPrepareTlas(vk_combuf_t *combuf) {
|
|||
.accelerationStructureReference = getASAddress(model->model->as), // TODO cache this addr
|
||||
};
|
||||
switch (model->material_mode) {
|
||||
case MaterialMode_Opaque:
|
||||
case MATERIAL_MODE_OPAQUE:
|
||||
case MATERIAL_MODE_SKYBOX:
|
||||
inst[i].mask = GEOMETRY_BIT_OPAQUE;
|
||||
inst[i].instanceShaderBindingTableRecordOffset = SHADER_OFFSET_HIT_REGULAR,
|
||||
inst[i].flags = VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR;
|
||||
break;
|
||||
case MaterialMode_Opaque_AlphaTest:
|
||||
case MATERIAL_MODE_OPAQUE_ALPHA_TEST:
|
||||
inst[i].mask = GEOMETRY_BIT_ALPHA_TEST;
|
||||
inst[i].instanceShaderBindingTableRecordOffset = SHADER_OFFSET_HIT_ALPHA_TEST,
|
||||
inst[i].flags = VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR;
|
||||
break;
|
||||
case MaterialMode_Refractive:
|
||||
case MATERIAL_MODE_TRANSLUCENT:
|
||||
inst[i].mask = GEOMETRY_BIT_REFRACTIVE;
|
||||
inst[i].instanceShaderBindingTableRecordOffset = SHADER_OFFSET_HIT_REGULAR,
|
||||
inst[i].flags = VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR;
|
||||
break;
|
||||
case MaterialMode_Additive:
|
||||
inst[i].mask = GEOMETRY_BIT_ADDITIVE;
|
||||
case MATERIAL_MODE_BLEND_ADD:
|
||||
case MATERIAL_MODE_BLEND_MIX:
|
||||
case MATERIAL_MODE_BLEND_GLOW:
|
||||
inst[i].mask = GEOMETRY_BIT_BLEND;
|
||||
inst[i].instanceShaderBindingTableRecordOffset = SHADER_OFFSET_HIT_ADDITIVE,
|
||||
inst[i].flags = VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR;
|
||||
break;
|
||||
default:
|
||||
gEngine.Host_Error("Unexpected material mode %d\n", model->material_mode);
|
||||
break;
|
||||
}
|
||||
memcpy(&inst[i].transform, model->transform_row, sizeof(VkTransformMatrixKHR));
|
||||
}
|
||||
|
|
|
@ -31,13 +31,7 @@ typedef struct Kusok vk_kusok_data_t;
|
|||
typedef struct {
|
||||
matrix3x4 transform_row;
|
||||
vk_ray_model_t *model;
|
||||
enum {
|
||||
MaterialMode_Opaque,
|
||||
MaterialMode_Opaque_AlphaTest,
|
||||
MaterialMode_Refractive,
|
||||
// TODO MaterialMode_Subtractive,
|
||||
MaterialMode_Additive,
|
||||
} material_mode;
|
||||
uint32_t material_mode; // MATERIAL_MODE_ from ray_interop.h
|
||||
} vk_ray_draw_model_t;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -155,7 +155,7 @@ void XVK_RayModel_Validate( void ) {
|
|||
}
|
||||
}
|
||||
|
||||
static void applyMaterialToKusok(vk_kusok_data_t* kusok, const vk_render_geometry_t *geom, const vec4_t color, qboolean HACK_reflective) {
|
||||
static void applyMaterialToKusok(vk_kusok_data_t* kusok, const vk_render_geometry_t *geom, const vec4_t model_color, uint32_t mode) {
|
||||
const xvk_material_t *const mat = XVK_GetMaterialForTextureIndex( geom->texture );
|
||||
ASSERT(mat);
|
||||
|
||||
|
@ -166,7 +166,7 @@ static void applyMaterialToKusok(vk_kusok_data_t* kusok, const vk_render_geometr
|
|||
kusok->triangles = geom->element_count / 3;
|
||||
|
||||
kusok->material = (struct Material){
|
||||
.flags = 0,
|
||||
.mode = mode,
|
||||
|
||||
.tex_base_color = mat->tex_base_color,
|
||||
.tex_roughness = mat->tex_roughness,
|
||||
|
@ -178,26 +178,20 @@ static void applyMaterialToKusok(vk_kusok_data_t* kusok, const vk_render_geometr
|
|||
.normal_scale = mat->normal_scale,
|
||||
};
|
||||
|
||||
// HACK until there is a proper mechanism for patching materials, see https://github.com/w23/xash3d-fwgs/issues/213
|
||||
// FIXME also this erases previous roughness unconditionally
|
||||
if (HACK_reflective) {
|
||||
kusok->material.tex_roughness = tglob.blackTexture;
|
||||
} else if (!mat->set && geom->material == kXVkMaterialChrome) {
|
||||
const qboolean HACK_chrome = geom->material == kXVkMaterialChrome;
|
||||
if (!mat->set && HACK_chrome)
|
||||
kusok->material.tex_roughness = tglob.grayTexture;
|
||||
}
|
||||
|
||||
if (geom->material == kXVkMaterialSky)
|
||||
kusok->material.flags |= KUSOK_MATERIAL_FLAG_SKYBOX;
|
||||
|
||||
if (geom->material == kXVkMaterialEmissiveGlow)
|
||||
kusok->material.flags |= KUSOK_MATERIAL_FLAG_FIXME_GLOW;
|
||||
kusok->material.mode = MATERIAL_MODE_SKYBOX;
|
||||
|
||||
// FIXME modulates model_color with material->base_color which has different frequency
|
||||
{
|
||||
vec4_t gcolor;
|
||||
gcolor[0] = color[0] * mat->base_color[0];
|
||||
gcolor[1] = color[1] * mat->base_color[1];
|
||||
gcolor[2] = color[2] * mat->base_color[2];
|
||||
gcolor[3] = color[3] * mat->base_color[3];
|
||||
gcolor[0] = model_color[0] * mat->base_color[0];
|
||||
gcolor[1] = model_color[1] * mat->base_color[1];
|
||||
gcolor[2] = model_color[2] * mat->base_color[2];
|
||||
gcolor[3] = model_color[3] * mat->base_color[3];
|
||||
Vector4Copy(gcolor, kusok->model.color);
|
||||
}
|
||||
|
||||
|
@ -271,7 +265,7 @@ vk_ray_model_t* VK_RayModelCreate( vk_ray_model_init_t args ) {
|
|||
.firstVertex = mg->vertex_offset,
|
||||
};
|
||||
|
||||
applyMaterialToKusok(kusochki + i, mg, args.model->color, false);
|
||||
applyMaterialToKusok(kusochki + i, mg, args.model->color, MATERIAL_MODE_OPAQUE);
|
||||
Matrix4x4_LoadIdentity(kusochki[i].model.prev_transform);
|
||||
}
|
||||
|
||||
|
@ -408,37 +402,31 @@ void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render
|
|||
memcpy(draw_model->transform_row, *transform_row, sizeof(draw_model->transform_row));
|
||||
}
|
||||
|
||||
qboolean HACK_reflective = false;
|
||||
qboolean HACK_additive_emissive = false;
|
||||
|
||||
uint32_t material_mode = MATERIAL_MODE_OPAQUE;
|
||||
switch (render_model->render_type) {
|
||||
case kVkRenderTypeSolid:
|
||||
draw_model->material_mode = MaterialMode_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
|
||||
// FIXME proper trasnlucency
|
||||
//HACK_reflective = true;
|
||||
//draw_model->material_mode = MaterialMode_Refractive;
|
||||
HACK_additive_emissive = true;
|
||||
draw_model->material_mode = MaterialMode_Additive;
|
||||
material_mode = MATERIAL_MODE_BLEND_MIX;
|
||||
break;
|
||||
case kVkRenderType_A_1: // blend: scr*a + dst, no depth test or write; sprite:kRenderGlow only
|
||||
material_mode = MATERIAL_MODE_BLEND_GLOW;
|
||||
break;
|
||||
|
||||
case kVkRenderType_A_1: // blend: scr*a + dst, no depth test or write
|
||||
case kVkRenderType_A_1_R: // blend: scr*a + dst, depth test
|
||||
case kVkRenderType_1_1_R: // blend: scr + dst, depth test
|
||||
HACK_additive_emissive = true;
|
||||
draw_model->material_mode = MaterialMode_Additive;
|
||||
material_mode = MATERIAL_MODE_BLEND_ADD;
|
||||
break;
|
||||
|
||||
case kVkRenderType_AT: // no blend, depth RW, alpha test
|
||||
draw_model->material_mode = MaterialMode_Opaque_AlphaTest;
|
||||
material_mode = MATERIAL_MODE_OPAQUE_ALPHA_TEST;
|
||||
break;
|
||||
|
||||
default:
|
||||
gEngine.Host_Error("Unexpected render type %d\n", render_model->render_type);
|
||||
}
|
||||
|
||||
draw_model->material_mode = material_mode;
|
||||
|
||||
// TODO optimize:
|
||||
// - collect list of geoms for which we could update anything (animated textues, uvs, etc)
|
||||
// - update only those through staging
|
||||
|
@ -464,11 +452,11 @@ void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render
|
|||
vk_render_geometry_t *geom = render_model->geometries + i;
|
||||
|
||||
// FIXME an impedance mismatch: render_type is per-model, while materials and emissive color are per-geom
|
||||
if (HACK_additive_emissive) {
|
||||
VectorCopy(render_model->color, geom->emissive);
|
||||
}
|
||||
/* if (HACK_additive_emissive) { */
|
||||
/* VectorCopy(render_model->color, geom->emissive); */
|
||||
/* } */
|
||||
|
||||
applyMaterialToKusok(kusochki + i, geom, render_model->color, HACK_reflective);
|
||||
applyMaterialToKusok(kusochki + i, geom, render_model->color, material_mode);
|
||||
|
||||
Matrix4x4_ToArrayFloatGL(render_model->prev_transform, (float*)(kusochki + i)->model.prev_transform);
|
||||
}
|
||||
|
|
|
@ -25,15 +25,10 @@ typedef enum {
|
|||
kXVkMaterialRegular = 0,
|
||||
|
||||
// Set for SURF_DRAWSKY surfaces in vk_brush.c.
|
||||
// Used: for setting KUSOK_MATERIAL_FLAG_SKYBOX for skybox texture sampling and environment shadows.
|
||||
// Used: for setting MATERIAL_MODE_SKYBOX for skybox texture sampling and environment shadows.
|
||||
// Remove: pass it as a special texture/material index (e.g. -2).
|
||||
kXVkMaterialSky,
|
||||
|
||||
// Set by glow sprites only.
|
||||
// Used: glow means no depth test. Allows for slight ray overshoot (KUSOK_MATERIAL_FLAG_FIXME_GLOW). Special exclusive case for sprites. Desired effect: "bloom" from bright light sources.
|
||||
// Remove: in favor of "real" pbr hdr, tonemapping and bloop.
|
||||
kXVkMaterialEmissiveGlow,
|
||||
|
||||
// Set for chrome studio submodels.
|
||||
// Used: ray tracing sets gray roughness texture to get smooth surface look.
|
||||
// Remove: Have an explicit material for chrome surfaces.
|
||||
|
|
|
@ -730,7 +730,7 @@ static void R_DrawSpriteQuad( const char *debug_name, mspriteframe_t *frame, vec
|
|||
{
|
||||
const vk_render_geometry_t geometry = {
|
||||
.texture = texture,
|
||||
.material = render_mode == kRenderGlow ? kXVkMaterialEmissiveGlow : kXVkMaterialRegular,
|
||||
.material = kXVkMaterialRegular,
|
||||
|
||||
.max_vertex = 4,
|
||||
.vertex_offset = buffer.vertices.unit_offset,
|
||||
|
|
Loading…
Reference in New Issue