Skip to content

Commit

Permalink
Make particles face in view direction (not toward viewer)
Browse files Browse the repository at this point in the history
Make RT_SPRITE entities whose shaders were registered with RSF_SPRITE
face opposite the view direction, instead of toward the viewer. This
prevents pathological cases where the normal of a closeby sprite
is oriented nearly orthogonally to the view direction, making its 2-D nature
obvious and ugly. I found that to happen with the alien evolve acid
particle system if I walked backward right after evolving from Dretch to
Mantis.

RT_SPRITE entities without the RSF_SPRITE shader flag continue to face
toward the viewer. Light flares go in this category.
  • Loading branch information
slipher committed Sep 9, 2024
1 parent 6d59ec5 commit 367ef31
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 4 deletions.
3 changes: 3 additions & 0 deletions src/engine/renderer/tr_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -1293,6 +1293,9 @@ enum class realtimeLightingRenderer_t { LEGACY, TILED };

bool interactLight; // this shader can interact with light shaders

// For RT_SPRITE, face opposing the view direction rather than the viewer
bool entitySpriteFaceViewDirection;

int autoSpriteMode;

uint8_t numDeforms;
Expand Down
5 changes: 5 additions & 0 deletions src/engine/renderer/tr_shader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6363,6 +6363,11 @@ shader_t *R_FindShader( const char *name, shaderType_t type,
implicitCullType = CT_FRONT_SIDED;
}

if ( flags & RSF_SPRITE )
{
shader.entitySpriteFaceViewDirection = true;
}

// attempt to define shader from an explicit parameter file
shaderText = FindShaderInShaderText( strippedName );

Expand Down
23 changes: 19 additions & 4 deletions src/engine/renderer/tr_surface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -596,20 +596,35 @@ static void Tess_SurfaceSprite()
tess.surfaceShader->name );
}

VectorSubtract( backEnd.currentEntity->e.origin, backEnd.viewParms.pvsOrigin, delta );
VectorSubtract( backEnd.currentEntity->e.origin, backEnd.viewParms.orientation.origin, delta );

if( VectorNormalize( delta ) < NORMAL_EPSILON )
return;

CrossProduct( backEnd.viewParms.orientation.axis[ 2 ], delta, left );
vec3_t forward;
if ( tess.surfaceShader->entitySpriteFaceViewDirection )
{
// Face opposite to view direction, triggered by RSF_SPRITE.
// Good for particles that may appear very close to the viewer and thus have extreme
// difference between the view direction and the direction to the viewer, so
// as to avoid cases where they appear obviously planar
VectorCopy( backEnd.viewParms.orientation.axis[ 0 ], forward );
}
else
{
// Face toward viewer. Used by light flares
VectorCopy( delta, forward );
}

CrossProduct( backEnd.viewParms.orientation.axis[ 2 ], forward, left );

if( VectorNormalize( left ) < NORMAL_EPSILON )
VectorSet( left, 1, 0, 0 );

if( backEnd.currentEntity->e.rotation != 0 )
RotatePointAroundVector( left, delta, left, backEnd.currentEntity->e.rotation );
RotatePointAroundVector( left, forward, left, backEnd.currentEntity->e.rotation );

CrossProduct( delta, left, up );
CrossProduct( forward, left, up );

VectorScale( left, radius, left );
VectorScale( up, radius, up );
Expand Down

0 comments on commit 367ef31

Please sign in to comment.