Skip to content

Player Shadows

A player’s sun shadow is a cascade shadow map, and the cascades stop at client.render.shadowDistance (120 m by default) and get coarse well before that. From a third-person camera at 40 m or 275 m a player can look like they float. The grounding shadow is a small mark under the feet that reads at any camera distance.

It is soft by default (client.render.playerShadow soft); none turns it off. It is also the Player shadow dropdown on the Video page of the options window. It is a local drawing choice: it is never replicated, and another player’s choice changes nothing for you.

ValueLook
noneNo shadow. It costs nothing: the shader block is compiled out.
circleA hard-edged dark disc on the ground under the player.
softA radial gradient disc, darkest at the feet and fading out to its rim. The default.
ambientAn occlusion-style contact shadow from the body’s ellipsoid, darkening the ground around the feet and falling off with distance and angle like ambient occlusion.

All three are drawn by one path. The circle is the soft disc with a tenth of the edge width, and the ambient style multiplies the same footprint by the body’s occlusion.

Not a preference. The footprint belongs to the avatar: the compiler measures how much ground its feet, legs and body cover and writes it into the compiled avatar as shadowRadius and shadowBodyRadius, and an avatar’s author can override either on the dh.avatar. The disc is that radius times the size the avatar is drawn at, so it hugs the feet and legs and never spans the arms. A player with no avatar, or one with no humanoid legs to measure, gets the reference hull’s radius (0.4 m). The ambient style takes its body radius the same way. The soft and ambient styles draw that footprint a quarter larger (playerShadowSoftScale, playerShadowAmbientScale), because a gradient fades out at its rim and would otherwise read smaller than the circle.

PreferenceDefaultMeaning
client.render.playerShadowsoftThe style.
client.render.playerShadowSoftScale1.25The soft disc’s radius against the circle’s.
client.render.playerShadowAmbientScale1.25The ambient footprint’s radius against the circle’s.
client.render.playerShadowOpacity0.55How dark it is at its darkest.
client.render.playerShadowSoftness0.5How much of the radius the edge fades over. The circle uses a tenth of it.
client.render.playerShadowFadeHeight2The height above the ground, in meters, at which it has faded out.
client.render.playerShadowShrink0.6The fraction of its radius it shrinks to at the fade height.
client.render.playerShadowDistanceScale0.004The smallest radius per meter of camera distance, so a far player still gets a mark.
client.render.playerShadowAmbientCurve0.35The exponent of the ambient style’s occlusion; lower reaches further from the body.
client.render.playerShadowAmbientShare0.5How much of the shadow also darkens ambient light.

Nothing is traced. The opaque shader already knows the surface it is shading, so a point under a player’s feet and inside the footprint is darkened. That is why it lands on slopes, stairs, voxel worlds and Source maps alike. Rising off the ground is just a larger vertical gap between the feet and the point, and the shadow fades and shrinks with that gap. A surface above the feet beyond a 45 degree slope, a wall and a ceiling take none.

It darkens the direct term (the sun, a lamp, and a lightmap’s baked direct share) by the shadow’s coverage, and the ambient term by the playerShadowAmbientShare of it. Neither reads the sun the cascades left standing, so ground in a wall’s shade, in a baked shadow, or under a lit voxel world’s sky gate takes the shadow as sunlit ground does: a player standing in shade still has one. On a lightmapped surface (an imported Source map, a CS2 import, an engine bake) the baked direct and indirect light are the terms darkened. Two players standing together combine rather than add.

It follows the body’s own opacity, so a body the third-person camera is dithering out takes its shadow with it.

Every pawn asks for its shadow in PlayerPawnVisual.Submit, whether it is drawn as a model or as the placeholder box, so the local player, remote players and the editor’s body all get one on every shell. The six players nearest the eye are shaded.

Its shader variant bit is PlayerShadow.