From 5e50bdfcf2388fb17eba24437a55c9901b5fed9e Mon Sep 17 00:00:00 2001 From: Ivan 'provod' Avdeev Date: Wed, 27 Oct 2021 10:21:06 -0700 Subject: [PATCH] rtx: add conveyor scrolling texture, fix #158 --- ref_vk/shaders/ray.rchit | 6 +++++- ref_vk/shaders/ray_interop.h | 5 +++++ ref_vk/vk_brush.c | 8 ++++++-- ref_vk/vk_ray_model.c | 37 +++++++++++++++++++++++++++++++++++- ref_vk/vk_render.c | 6 +++--- ref_vk/vk_render.h | 4 +++- ref_vk/vk_rtx.c | 6 +++--- ref_vk/vk_rtx.h | 2 +- 8 files changed, 62 insertions(+), 12 deletions(-) diff --git a/ref_vk/shaders/ray.rchit b/ref_vk/shaders/ray.rchit index 72f9eb95..97dfcf15 100644 --- a/ref_vk/shaders/ray.rchit +++ b/ref_vk/shaders/ray.rchit @@ -10,6 +10,10 @@ layout (set = 0, binding = 6) uniform sampler2D textures[MAX_TEXTURES]; layout(location = 0) rayPayloadInEXT RayPayload payload; +layout (push_constant) uniform PC_ { + PushConstants push_constants; +}; + hitAttributeEXT vec2 bary; float hash(float f) { return fract(sin(f)*53478.4327); } @@ -76,7 +80,7 @@ void main() { vertices[vi2].pos, vertices[vi3].pos, }; - const vec2 texture_uv = vertices[vi1].gl_tc * (1. - bary.x - bary.y) + vertices[vi2].gl_tc * bary.x + vertices[vi3].gl_tc * bary.y; + const vec2 texture_uv = vertices[vi1].gl_tc * (1. - bary.x - bary.y) + vertices[vi2].gl_tc * bary.x + vertices[vi3].gl_tc * bary.y + push_constants.time * kusochki[kusok_index].uv_speed; const uint tex_index = kusochki[kusok_index].texture; const float ray_cone_width = payload.pixel_cone_spread_angle * payload.t_offset; diff --git a/ref_vk/shaders/ray_interop.h b/ref_vk/shaders/ray_interop.h index 9e35534c..44445b14 100644 --- a/ref_vk/shaders/ray_interop.h +++ b/ref_vk/shaders/ray_interop.h @@ -2,6 +2,7 @@ #ifndef GLSL #define uint uint32_t +#define vec2 vec2_t #define vec3 vec3_t #define vec4 vec4_t #define TOKENPASTE(x, y) x ## y @@ -38,6 +39,9 @@ struct Kusok { //PAD(1) float roughness; + + vec2 uv_speed; // for conveyors + PAD(2) }; struct PointLight { @@ -72,6 +76,7 @@ struct LightCluster { }; struct PushConstants { + float time; uint random_seed; int bounces; float prev_frame_blend_factor; diff --git a/ref_vk/vk_brush.c b/ref_vk/vk_brush.c index e506f5f0..7de2a82a 100644 --- a/ref_vk/vk_brush.c +++ b/ref_vk/vk_brush.c @@ -352,7 +352,7 @@ void VK_BrushModelDraw( const cl_entity_t *ent, int render_mode ) } bmodel->render_model.render_mode = render_mode; - VK_RenderModelDraw(&bmodel->render_model); + VK_RenderModelDraw(ent, &bmodel->render_model); } static qboolean renderableSurface( const msurface_t *surf, int i ) { @@ -375,7 +375,7 @@ static qboolean renderableSurface( const msurface_t *surf, int i ) { // } //if( surf->flags & ( SURF_DRAWSKY | SURF_DRAWTURB | SURF_CONVEYOR | SURF_DRAWTURB_QUADS ) ) { - if( surf->flags & ( SURF_DRAWTURB | SURF_CONVEYOR | SURF_DRAWTURB_QUADS ) ) { + if( surf->flags & ( SURF_DRAWTURB | SURF_DRAWTURB_QUADS ) ) { //if( surf->flags & ( SURF_DRAWSKY | SURF_CONVEYOR ) ) { // FIXME don't print this on second sort-by-texture pass //gEngine.Con_Reportf("Skipping surface %d because of flags %08x\n", i, surf->flags); @@ -489,6 +489,10 @@ static qboolean loadBrushSurfaces( model_sizes_t sizes, const model_t *mod ) { VK_CreateSurfaceLightmap( surf, mod ); } + if (FBitSet( surf->flags, SURF_CONVEYOR )) { + model_geometry->material = kXVkMaterialConveyor; + } + for( int k = 0; k < surf->numedges; k++ ) { const int iedge = mod->surfedges[surf->firstedge + k]; diff --git a/ref_vk/vk_ray_model.c b/ref_vk/vk_ray_model.c index 9bd1ae5f..456682d3 100644 --- a/ref_vk/vk_ray_model.c +++ b/ref_vk/vk_ray_model.c @@ -278,7 +278,36 @@ void VK_RayModelDestroy( struct vk_ray_model_s *model ) { } } -void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render_model, const matrix3x4 *transform_row, const vec4_t color) { +// TODO move this to some common place with traditional renderer +static void computeConveyorSpeed(const color24 rendercolor, int tex_index, vec2_t speed) { + float sy, cy; + float flConveyorSpeed = 0.0f; + float flRate, flAngle; + vk_texture_t *texture = findTexture( tex_index ); + //gl_texture_t *texture; + + // FIXME + /* if( ENGINE_GET_PARM( PARM_QUAKE_COMPATIBLE ) && RI.currententity == gEngfuncs.GetEntityByIndex( 0 ) ) */ + /* { */ + /* // same as doom speed */ + /* flConveyorSpeed = -35.0f; */ + /* } */ + /* else */ + { + flConveyorSpeed = (rendercolor.g<<8|rendercolor.b) / 16.0f; + if( rendercolor.r ) flConveyorSpeed = -flConveyorSpeed; + } + //texture = R_GetTexture( glState.currentTextures[glState.activeTMU] ); + + flRate = fabs( flConveyorSpeed ) / (float)texture->width; + flAngle = ( flConveyorSpeed >= 0 ) ? 180 : 0; + + SinCos( flAngle * ( M_PI_F / 180.0f ), &sy, &cy ); + speed[0] = cy * flRate; + speed[1] = sy * flRate; +} + +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 force_emissive = false; qboolean additive = false; @@ -363,6 +392,12 @@ void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render } else if (force_emissive) { VectorSet(kusok->emissive, 1.f, 1.f, 1.f); } + + if (geom->material == kXVkMaterialConveyor) { + computeConveyorSpeed( entcolor, geom->texture, kusok->uv_speed ); + } else { + kusok->uv_speed[0] = kusok->uv_speed[1] = 0.f; + } } } diff --git a/ref_vk/vk_render.c b/ref_vk/vk_render.c index 32ac4d2c..da741d69 100644 --- a/ref_vk/vk_render.c +++ b/ref_vk/vk_render.c @@ -721,14 +721,14 @@ void VK_RenderModelDestroy( vk_render_model_t* model ) { } } -void VK_RenderModelDraw( vk_render_model_t* model ) { +void VK_RenderModelDraw( const cl_entity_t *ent, vk_render_model_t* model ) { int current_texture = -1; int element_count = 0; int index_offset = -1; int vertex_offset = 0; if (g_render_state.current_frame_is_ray_traced) { - VK_RayFrameAddModel(model->ray_model, model, (const matrix3x4*)g_render_state.model, g_render_state.dirty_uniform_data.color); + VK_RayFrameAddModel(model->ray_model, model, (const matrix3x4*)g_render_state.model, g_render_state.dirty_uniform_data.color, ent ? ent->curstate.rendercolor : (color24){255,255,255}); return; } @@ -820,7 +820,7 @@ void VK_RenderModelDynamicCommit( void ) { if (g_dynamic_model.model.num_geometries > 0) { g_dynamic_model.model.dynamic = true; VK_RenderModelInit( &g_dynamic_model.model ); - VK_RenderModelDraw( &g_dynamic_model.model ); + VK_RenderModelDraw( NULL, &g_dynamic_model.model ); } g_dynamic_model.model.debug_name[0] = '\0'; diff --git a/ref_vk/vk_render.h b/ref_vk/vk_render.h index 7ebf3ad2..8298eee0 100644 --- a/ref_vk/vk_render.h +++ b/ref_vk/vk_render.h @@ -67,11 +67,13 @@ typedef struct vk_vertex_s { // For some things we don't even have that. E.g. water and sky surfaces are weird. // Lets just assigne water and sky materials to those geometries (and probably completely // disregard render_mode, as it should be irrelevant). +// FIXME these should be bits, not enums typedef enum { kXVkMaterialRegular = 0, kXVkMaterialWater, kXVkMaterialSky, kXVkMaterialEmissive, + kXVkMaterialConveyor, } XVkMaterialType; typedef struct vk_render_geometry_s { @@ -120,7 +122,7 @@ typedef struct vk_render_model_s { qboolean VK_RenderModelInit( vk_render_model_t* model ); void VK_RenderModelDestroy( vk_render_model_t* model ); -void VK_RenderModelDraw( vk_render_model_t* model ); +void VK_RenderModelDraw( const cl_entity_t *ent, vk_render_model_t* model ); void VK_RenderFrameBegin( void ); diff --git a/ref_vk/vk_rtx.c b/ref_vk/vk_rtx.c index bd0a7185..a28d7536 100644 --- a/ref_vk/vk_rtx.c +++ b/ref_vk/vk_rtx.c @@ -609,7 +609,7 @@ static qboolean rayTrace( VkCommandBuffer cmdbuf, VkImage frame_dst, float fov_a vkCmdBindPipeline(cmdbuf, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, g_rtx.pipeline); { vk_rtx_push_constants_t push_constants = { - //.t = gpGlobals->realtime, + .time = gpGlobals->time, .random_seed = (uint32_t)gEngine.COM_RandomLong(0, INT32_MAX), .bounces = vk_rtx_bounces->value, .prev_frame_blend_factor = vk_rtx_prev_frame_blend_factor->value, @@ -617,7 +617,7 @@ static qboolean rayTrace( VkCommandBuffer cmdbuf, VkImage frame_dst, float fov_a .debug_light_index_begin = (uint32_t)(vk_rtx_light_begin->value), .debug_light_index_end = (uint32_t)(vk_rtx_light_end->value), }; - vkCmdPushConstants(cmdbuf, g_rtx.descriptors.pipeline_layout, VK_SHADER_STAGE_RAYGEN_BIT_KHR, 0, sizeof(push_constants), &push_constants); + vkCmdPushConstants(cmdbuf, g_rtx.descriptors.pipeline_layout, VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, 0, sizeof(push_constants), &push_constants); } vkCmdBindDescriptorSets(cmdbuf, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, g_rtx.descriptors.pipeline_layout, 0, 1, g_rtx.descriptors.desc_sets + 0, 0, NULL); @@ -879,7 +879,7 @@ static void createLayouts( void ) { g_rtx.descriptors.push_constants = (VkPushConstantRange){ .offset = 0, .size = sizeof(vk_rtx_push_constants_t), - .stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_KHR, + .stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, }; g_rtx.desc_bindings[RayDescBinding_DestImage] = (VkDescriptorSetLayoutBinding){ diff --git a/ref_vk/vk_rtx.h b/ref_vk/vk_rtx.h index 56f046c2..f1377dfe 100644 --- a/ref_vk/vk_rtx.h +++ b/ref_vk/vk_rtx.h @@ -17,7 +17,7 @@ void VK_RayModelDestroy( struct vk_ray_model_s *model ); void VK_RayFrameBegin( void ); // TODO how to improve this render vs ray model storage/interaction? -void VK_RayFrameAddModel( struct vk_ray_model_s *model, const struct vk_render_model_s *render_model, const matrix3x4 *transform_row, const vec4_t color ); +void VK_RayFrameAddModel( struct vk_ray_model_s *model, const struct vk_render_model_s *render_model, const matrix3x4 *transform_row, const vec4_t color, color24 entcolor ); typedef struct { VkBuffer buffer;