Skip to main content

VRChat Shader Globals

VRChat provides multiple global shader parameters Shader creators can use to implement VRChat-specific features.

warning

Do not use the _VRChat prefix for shader variables in custom shaders outside of what is documented on this page. That prefix is considered a protected namespace, and new variables may be introduced at any time, including undocumented ones.

The following shader globals are currently available:

VariableTypeContents
_VRChatCameraModefloat
  • 0 - Rendering normally
  • 1 - Rendering in VR handheld camera
  • 2 - Rendering in Desktop handheld camera
  • 3 - Rendering for a screenshot
_VRChatCameraMaskuintThe cullingMask property of the active camera, available if _VRChatCameraMode != 0
_VRChatMirrorModefloat
  • 0 - Rendering normally, not in mirror
  • 1 - Rendering in a mirror viewed in VR
  • 2 - Rendering in a mirror viewed in desktop mode
_VRChatFaceMirrorModefloat1 when rendering the face mirror (VR and Desktop use different camera types!), 0 otherwise
_VRChatMirrorCameraPosfloat3World space position of mirror camera (eye independent, "centered" in VR), (0,0,0) when not rendering in a mirror
_VRChatScreenCameraPos/
_VRChatPhotoCameraPos
float3World space position of main screen camera/
handheld photo camera ((0,0,0) when camera is not active)
_VRChatScreenCameraRot/
_VRChatPhotoCameraRot
float4World space rotation (quaternion) of main screen camera/
handheld photo camera ((0,0,0,0) when camera is not active)

VRChat Time Global

The _VRChatTime globals provide various information about time. You can use them for clocks or animation syncing.

All globals listed below contain unsigned integer bit-patterns and should be defined as uint. The following tables list the contents of each one, the numbers in brackets are bit-ranges (inclusive, zero-indexed).

VariableContents
_VRChatTimeUTCUnixSecondsThe lower 32 bits of the current UTC time in seconds since the Unix epoch. Note that this should be treated as an unsigned number and will thus not (yet) overflow in 2038. If system time is set to pre-1970 this value is undefined.
_VRChatTimeNetworkMsSynchronized network time in milliseconds. This is the same value as returned by Networking.GetServerTimeInMilliseconds in Udon. This is technically a signed value, but may be treated as unsigned. It should only be used for synchronization and offsets, as the absolute value does not represent any meaningful quantity. This value can wrap.
Variable (Bits)Contents
_VRChatTimeEncoded1 (0-4)Hour component of the current time of day (UTC).
_VRChatTimeEncoded1 (5-10)Minute component of the current time of day (UTC).
_VRChatTimeEncoded1 (11-16)Second component of the current time of day (UTC & Local, shared).
_VRChatTimeEncoded1 (17-21)Hour component of the current time of day (Local).
_VRChatTimeEncoded1 (22-27)Minute component of the current time of day (Local).
_VRChatTimeEncoded1 (28-31)Reserved.
Variable (Bits)Contents
_VRChatTimeEncoded2 (0-9)Millisecond component of the current time of day (UTC & Local, shared).
_VRChatTimeEncoded2 (10)Sign bit of timezone offset. 1 if offset is negative.
_VRChatTimeEncoded2 (11-26)Timezone offset from UTC to Local time in seconds.
_VRChatTimeEncoded2 (27-31)Reserved.

All timezone offsets from UTC and local time values are affected by the "preferred timezone" setting in the VRChat menu.

"Current time of day" always refers to the local user's time of day. That is, if a custom shader on an avatar uses these values to display a clock for example, it will always show the local time of the observer, not the wearer.

Time values are available in the VRChat client and all VRChat SDKs while in play mode.

The VRChat SDK ships a header file with helper functions to decode the time formats. The HLSL code snippet below shows the include path and lists available functions:

#include "Packages/com.vrchat.base/ShaderLibrary/VRCTime.cginc"

uint VRC_GetUTCUnixTimeInSeconds();
uint VRC_GetNetworkTimeInMilliseconds();
void VRC_GetUTCTime(out uint hours, out uint minutes, out uint seconds, out uint milliseconds);
void VRC_GetLocalTime(out uint hours, out uint minutes, out uint seconds, out uint milliseconds);
int VRC_GetTimezoneOffsetSeconds();