Skip to content

Commit 167e896

Browse files
committed
Make particles face in view direction (not toward viewer)
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.
1 parent 6b7a7dd commit 167e896

File tree

3 files changed

+27
-4
lines changed

3 files changed

+27
-4
lines changed

src/engine/renderer/tr_local.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1295,6 +1295,9 @@ enum class realtimeLightingRenderer_t { LEGACY, TILED };
12951295

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

1298+
// For RT_SPRITE, face opposing the view direction rather than the viewer
1299+
bool entitySpriteFaceViewDirection;
1300+
12981301
int autoSpriteMode;
12991302

13001303
uint8_t numDeforms;

src/engine/renderer/tr_shader.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6341,6 +6341,11 @@ shader_t *R_FindShader( const char *name, shaderType_t type, int flags )
63416341
shader.fitScreen = true;
63426342
}
63436343

6344+
if ( flags & RSF_SPRITE )
6345+
{
6346+
shader.entitySpriteFaceViewDirection = true;
6347+
}
6348+
63446349
// attempt to define shader from an explicit parameter file
63456350
shaderText = FindShaderInShaderText( strippedName );
63466351

src/engine/renderer/tr_surface.cpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -596,20 +596,35 @@ static void Tess_SurfaceSprite()
596596
tess.surfaceShader->name );
597597
}
598598

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

601601
if( VectorNormalize( delta ) < NORMAL_EPSILON )
602602
return;
603603

604-
CrossProduct( backEnd.viewParms.orientation.axis[ 2 ], delta, left );
604+
vec3_t forward;
605+
if ( tess.surfaceShader->entitySpriteFaceViewDirection )
606+
{
607+
// Face opposite to view direction, triggered by RSF_SPRITE.
608+
// Good for particles that may appear very close to the viewer and thus have extreme
609+
// difference between the view direction and the direction to the viewer, so
610+
// as to avoid cases where they appear obviously planar
611+
VectorCopy( backEnd.viewParms.orientation.axis[ 0 ], forward );
612+
}
613+
else
614+
{
615+
// Face toward viewer. Used by light flares
616+
VectorCopy( delta, forward );
617+
}
618+
619+
CrossProduct( backEnd.viewParms.orientation.axis[ 2 ], forward, left );
605620

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

609624
if( backEnd.currentEntity->e.rotation != 0 )
610-
RotatePointAroundVector( left, delta, left, backEnd.currentEntity->e.rotation );
625+
RotatePointAroundVector( left, forward, left, backEnd.currentEntity->e.rotation );
611626

612-
CrossProduct( delta, left, up );
627+
CrossProduct( forward, left, up );
613628

614629
VectorScale( left, radius, left );
615630
VectorScale( up, radius, up );

0 commit comments

Comments
 (0)