vk rt: fix reprojection
This commit is contained in:
parent
da447d9e5b
commit
ed69eeb5af
|
@ -26,33 +26,35 @@ typedef struct {
|
||||||
matrix3x4 bones_worldtransform[MAXSTUDIOBONES];
|
matrix3x4 bones_worldtransform[MAXSTUDIOBONES];
|
||||||
matrix4x4 model_transform;
|
matrix4x4 model_transform;
|
||||||
float time;
|
float time;
|
||||||
int bones_update_frame_index;
|
uint bones_frame_updated;
|
||||||
|
uint frame_updated;
|
||||||
} prev_state_t;
|
} prev_state_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
prev_state_t prev_states[PREV_FRAMES_COUNT][PREV_STATES_COUNT];
|
prev_state_t prev_states[PREV_FRAMES_COUNT][PREV_STATES_COUNT];
|
||||||
int frame_index;
|
uint frame_index;
|
||||||
int current_frame_id;
|
uint prev_frame_index;
|
||||||
int previous_frame_id;
|
uint current_frame_id;
|
||||||
|
uint previous_frame_id;
|
||||||
} prev_states_storage_t;
|
} prev_states_storage_t;
|
||||||
|
|
||||||
prev_states_storage_t g_prev = { 0 };
|
prev_states_storage_t g_prev = { 0 };
|
||||||
|
|
||||||
static inline int clampIndex( int index, int array_length )
|
|
||||||
{
|
|
||||||
if (index < 0)
|
|
||||||
return 0;
|
|
||||||
else if (index >= array_length)
|
|
||||||
return array_length - 1;
|
|
||||||
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
prev_state_t* prevStateInArrayBounds( int frame_storage_id, int entity_id )
|
prev_state_t* prevStateInArrayBounds( int frame_storage_id, int entity_id )
|
||||||
{
|
{
|
||||||
int clamped_frame_id = clampIndex( frame_storage_id, PREV_FRAMES_COUNT );
|
int clamped_entity_id = entity_id;
|
||||||
int clamped_entity_id = clampIndex( entity_id, PREV_STATES_COUNT );
|
|
||||||
return &g_prev.prev_states[clamped_frame_id][clamped_entity_id];
|
if (entity_id >= PREV_STATES_COUNT)
|
||||||
|
{
|
||||||
|
gEngine.Con_Printf("Previous frame states data for entity %d overflows storage (size is %d). Increase it\n", entity_id, PREV_STATES_COUNT);
|
||||||
|
clamped_entity_id = PREV_STATES_COUNT - 1; // fallback to last correct value
|
||||||
|
}
|
||||||
|
else if (entity_id < 0)
|
||||||
|
{
|
||||||
|
clamped_entity_id = 0; // fallback to correct value
|
||||||
|
}
|
||||||
|
|
||||||
|
return &g_prev.prev_states[frame_storage_id][clamped_entity_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PREV_FRAME() prevStateInArrayBounds( g_prev.previous_frame_id, entity_id )
|
#define PREV_FRAME() prevStateInArrayBounds( g_prev.previous_frame_id, entity_id )
|
||||||
|
@ -62,42 +64,65 @@ void R_PrevFrame_StartFrame( void )
|
||||||
{
|
{
|
||||||
g_prev.frame_index++;
|
g_prev.frame_index++;
|
||||||
g_prev.current_frame_id = g_prev.frame_index % PREV_FRAMES_COUNT;
|
g_prev.current_frame_id = g_prev.frame_index % PREV_FRAMES_COUNT;
|
||||||
g_prev.previous_frame_id = g_prev.frame_index - 1;
|
g_prev.previous_frame_id = (g_prev.frame_index - 1) % PREV_FRAMES_COUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void R_PrevFrame_SaveCurrentBoneTransforms( int entity_id, matrix3x4* bones_transforms )
|
void R_PrevFrame_SaveCurrentBoneTransforms( int entity_id, matrix3x4* bones_transforms )
|
||||||
{
|
{
|
||||||
prev_state_t *state = CURRENT_FRAME();
|
prev_state_t *current_frame = CURRENT_FRAME();
|
||||||
|
|
||||||
if (state->bones_update_frame_index == g_prev.frame_index)
|
if (current_frame->bones_frame_updated == g_prev.frame_index)
|
||||||
return; // already updated for this entity
|
return; // already updated for this entity
|
||||||
|
|
||||||
state->bones_update_frame_index = g_prev.frame_index;
|
current_frame->bones_frame_updated = g_prev.frame_index;
|
||||||
|
|
||||||
for( int i = 0; i < MAXSTUDIOBONES; i++ )
|
for( int i = 0; i < MAXSTUDIOBONES; i++ )
|
||||||
{
|
{
|
||||||
Matrix3x4_Copy(state->bones_worldtransform[i], bones_transforms[i]);
|
Matrix3x4_Copy( current_frame->bones_worldtransform[i], bones_transforms[i] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void R_PrevFrame_SaveCurrentState( int entity_id, matrix4x4 model_transform )
|
void R_PrevFrame_SaveCurrentState( int entity_id, matrix4x4 model_transform )
|
||||||
{
|
{
|
||||||
prev_state_t* state = CURRENT_FRAME();
|
prev_state_t* current_frame = CURRENT_FRAME();
|
||||||
Matrix4x4_Copy( state->model_transform, model_transform );
|
|
||||||
state->time = gpGlobals->time;
|
if (current_frame->frame_updated == g_prev.frame_index)
|
||||||
|
return; // already updated for this entity
|
||||||
|
|
||||||
|
Matrix4x4_Copy( current_frame->model_transform, model_transform );
|
||||||
|
current_frame->time = gpGlobals->time;
|
||||||
|
current_frame->frame_updated = g_prev.frame_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
matrix3x4* R_PrevFrame_BoneTransforms( int entity_id )
|
matrix3x4* R_PrevFrame_BoneTransforms( int entity_id )
|
||||||
{
|
{
|
||||||
return PREV_FRAME()->bones_worldtransform;
|
prev_state_t* prev_frame = PREV_FRAME();
|
||||||
|
|
||||||
|
// fallback to current frame if previous is outdated
|
||||||
|
if (prev_frame->bones_frame_updated != g_prev.frame_index - 1)
|
||||||
|
return CURRENT_FRAME()->bones_worldtransform;
|
||||||
|
|
||||||
|
return prev_frame->bones_worldtransform;
|
||||||
}
|
}
|
||||||
|
|
||||||
void R_PrevFrame_ModelTransform( int entity_id, matrix4x4 model_matrix )
|
void R_PrevFrame_ModelTransform( int entity_id, matrix4x4 model_matrix )
|
||||||
{
|
{
|
||||||
Matrix4x4_Copy(model_matrix, PREV_FRAME()->model_transform);
|
prev_state_t* prev_frame = PREV_FRAME();
|
||||||
|
|
||||||
|
// fallback to current frame if previous is outdated
|
||||||
|
if (prev_frame->frame_updated != g_prev.frame_index - 1)
|
||||||
|
prev_frame = CURRENT_FRAME();
|
||||||
|
|
||||||
|
Matrix4x4_Copy(model_matrix, prev_frame->model_transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
float R_PrevFrame_Time( int entity_id )
|
float R_PrevFrame_Time( int entity_id )
|
||||||
{
|
{
|
||||||
return PREV_FRAME()->time;
|
prev_state_t* prev_frame = PREV_FRAME();
|
||||||
|
|
||||||
|
// fallback to current frame if previous is outdated
|
||||||
|
if (prev_frame->frame_updated != g_prev.frame_index - 1)
|
||||||
|
return gpGlobals->time;
|
||||||
|
|
||||||
|
return prev_frame->time;
|
||||||
}
|
}
|
||||||
|
|
|
@ -522,7 +522,8 @@ void VK_RayFrameAddModel( vk_ray_model_t *model, const vk_render_model_t *render
|
||||||
}
|
}
|
||||||
|
|
||||||
applyMaterialToKusok(kusochki + i, geom, render_model->color, HACK_reflective);
|
applyMaterialToKusok(kusochki + i, geom, render_model->color, HACK_reflective);
|
||||||
Matrix4x4_Copy((kusochki + i)->prev_transform, render_model->prev_transform);
|
|
||||||
|
Matrix4x4_ToArrayFloatGL(render_model->prev_transform, (float*)(kusochki + i)->prev_transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* gEngine.Con_Reportf("model %s: geom=%d kuoffs=%d kustoff=%d kustsz=%d sthndl=%d\n", */
|
/* gEngine.Con_Reportf("model %s: geom=%d kuoffs=%d kustoff=%d kustsz=%d sthndl=%d\n", */
|
||||||
|
|
|
@ -688,8 +688,8 @@ void VK_RenderModelDraw( const cl_entity_t *ent, vk_render_model_t* model ) {
|
||||||
|
|
||||||
if (g_render_state.current_frame_is_ray_traced) {
|
if (g_render_state.current_frame_is_ray_traced) {
|
||||||
if (ent != NULL && model != NULL) {
|
if (ent != NULL && model != NULL) {
|
||||||
R_PrevFrame_ModelTransform( ent->index, model->prev_transform );
|
|
||||||
R_PrevFrame_SaveCurrentState( ent->index, g_render_state.model );
|
R_PrevFrame_SaveCurrentState( ent->index, g_render_state.model );
|
||||||
|
R_PrevFrame_ModelTransform( ent->index, model->prev_transform );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Matrix4x4_Copy( model->prev_transform, g_render_state.model );
|
Matrix4x4_Copy( model->prev_transform, g_render_state.model );
|
||||||
|
|
|
@ -2129,6 +2129,7 @@ static void R_StudioDrawPoints( void )
|
||||||
R_LightStrength( pvertbone[i], pstudioverts[i], g_studio.lightpos[i] );
|
R_LightStrength( pvertbone[i], pstudioverts[i], g_studio.lightpos[i] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
R_PrevFrame_SaveCurrentBoneTransforms( RI.currententity->index, g_studio.worldtransform );
|
||||||
matrix3x4* prev_bones_transforms = R_PrevFrame_BoneTransforms( RI.currententity->index );
|
matrix3x4* prev_bones_transforms = R_PrevFrame_BoneTransforms( RI.currententity->index );
|
||||||
for( i = 0; i < m_pSubModel->numverts; i++ )
|
for( i = 0; i < m_pSubModel->numverts; i++ )
|
||||||
{
|
{
|
||||||
|
@ -2141,11 +2142,10 @@ static void R_StudioDrawPoints( void )
|
||||||
R_StudioComputeSkinMatrix( &pnormweight[i], g_studio.worldtransform, skinMat );
|
R_StudioComputeSkinMatrix( &pnormweight[i], g_studio.worldtransform, skinMat );
|
||||||
Matrix3x4_VectorRotate( skinMat, pstudionorms[i], g_studio.norms[i] );
|
Matrix3x4_VectorRotate( skinMat, pstudionorms[i], g_studio.norms[i] );
|
||||||
}
|
}
|
||||||
|
|
||||||
R_PrevFrame_SaveCurrentBoneTransforms( RI.currententity->index, g_studio.worldtransform );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
R_PrevFrame_SaveCurrentBoneTransforms( RI.currententity->index, g_studio.bonestransform );
|
||||||
matrix3x4* prev_bones_transforms = R_PrevFrame_BoneTransforms( RI.currententity->index );
|
matrix3x4* prev_bones_transforms = R_PrevFrame_BoneTransforms( RI.currententity->index );
|
||||||
for( i = 0; i < m_pSubModel->numverts; i++ )
|
for( i = 0; i < m_pSubModel->numverts; i++ )
|
||||||
{
|
{
|
||||||
|
@ -2153,8 +2153,6 @@ static void R_StudioDrawPoints( void )
|
||||||
Matrix3x4_VectorTransform( prev_bones_transforms[pvertbone[i]], pstudioverts[i], g_studio.prev_verts[i] );
|
Matrix3x4_VectorTransform( prev_bones_transforms[pvertbone[i]], pstudioverts[i], g_studio.prev_verts[i] );
|
||||||
R_LightStrength( pvertbone[i], pstudioverts[i], g_studio.lightpos[i] );
|
R_LightStrength( pvertbone[i], pstudioverts[i], g_studio.lightpos[i] );
|
||||||
}
|
}
|
||||||
|
|
||||||
R_PrevFrame_SaveCurrentBoneTransforms( RI.currententity->index, g_studio.bonestransform );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate shared normals for properly scaling glowing shell
|
// generate shared normals for properly scaling glowing shell
|
||||||
|
@ -2210,7 +2208,7 @@ static void R_StudioDrawPoints( void )
|
||||||
qsort( g_studio.meshes, m_pSubModel->nummesh, sizeof( sortedmesh_t ), R_StudioMeshCompare );
|
qsort( g_studio.meshes, m_pSubModel->nummesh, sizeof( sortedmesh_t ), R_StudioMeshCompare );
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: rewind normals at start
|
// NOTE: rewind normals at start
|
||||||
pstudionorms = (vec3_t *)((byte *)m_pStudioHeader + m_pSubModel->normindex);
|
pstudionorms = (vec3_t *)((byte *)m_pStudioHeader + m_pSubModel->normindex);
|
||||||
|
|
||||||
for( j = 0; j < m_pSubModel->nummesh; j++ )
|
for( j = 0; j < m_pSubModel->nummesh; j++ )
|
||||||
|
|
Loading…
Reference in New Issue