Found some interesting settings that might help solve or reduce culling in Half Life Alyx without needing PP

As you guys know, Half Life Alyx does object culling on the right peripheral vision for both Pimax and StarVR One headsets. This is fixed by running parallel projection, but what if we can mod Half Life Alyx files to get the game to stop this culling on the right peripheral?

So far I’ve found some very interesting settings in the Half Life Alyx game folder.

For example in a bunch of files, there are references to Culling, Camera, or FOV settings. Maybe if we change some of them this can be fixed.

I used FileSeek software in order to find all files that references the words: cull, camera, and fov. Most important keyword is probably frustum. Because the issue is called frustum culling. I bolded all the interesting parts.

In game/core/base.fgd

  // FGDFIXME: why are these different from the ones above?
  15: "Distort"
  16: "Hologram (Distort + fade)"
  **23: "Cull By Distance (TEST)"**
  24: "Spotlight FX"
  26: "Fade Near"

I wonder where this number is used.

PointClass base(Targetname, EnableDisable) tags( Info ) iconsprite( “materials/editor/info_visibility_box.vmat” ) centered_box_oriented( box_size )
= info_visibility_box : “A dynamic visibility culling box which can be used to hide objects at runtime and can be toggled on and off by entity I/O.”
[
box_size(vector) : “Box Size” : “128 128 128”
cull_mode(choices) : “Mode” : “0” : “Should the box hide objects inside or outside of its bounds. If inside is selected, any objects fully inside the box will be hidden. If outside is selected, all active visibility boxes are considered, and objects not intersecting any visibility boxes will be hidden.”=
[
0: “Hide objects inside”
1: “Hide objects outside”
]
]

I wonder what would happen if changed the mode to 1

SolidClass base(Targetname) color(0 128 255) = func_areaportalwindow :
“An entity that can be used to optimize the visibility in a map. If you seal off an area with them, when the viewer moves the specified distance away from them, they will go opaque and the parts inside the area will not be drawn. The ‘target’ brush model should enclose the func_areaportal window so no parts of it are culled by the window. If you use the optional foreground brush model, then it should enclose the ‘target’ brush model.”
[
target(target_destination) : “Rendered Window” : : “The name of a brush model to render as the window.”
FadeStartDist(integer) : “Fade Start Distance” : 128 : “When the viewer is closer than this distance, the alpha is set to ‘TranslucencyLimit’.”
FadeDist(integer) : “Fade End Distance” : 512 : “When the viewer is at this distance, the portal becomes solid and closes off.”
TranslucencyLimit(string) : “Translucency limit” : “0” : “This value limits the translucency of the bmodel and prevents it from becoming invisible when the viewer is right on top of it.”
BackgroundBModel(string) : “Foreground bmodel” : “” : “(Optional) brush model that is drawn after the fading brush model. This model should have alpha in its textures so you can see through it.”
PortalVersion(integer) [readonly] : “Portal Version” : 1 : “(Don’t change). Differentiates between shipping HL2 maps and maps using new engine features.”

// Inputs
input SetFadeStartDistance(integer) : “Set fade start distance.”
input SetFadeEndDistance(integer) : “Set fade end distance.”
]

Tweaking Fade start and end distance might do something

PointClass base(Targetname) = env_zoom :
“An entity that can be used to control the player’s FOV. Useful for scenes where the player’s view is being controlled, or player-usable binoculars/telescopes, etc.”
[
Rate(float) : “Seconds to reach target” : “1.0” : “Amount of time it should take to reach the specified FOV.”
FOV(integer) : “Target FOV” : 75 : “FOV that this entity should set the player’s FOV to when active.”

// Inputs
input Zoom(void) : “Start controlling the player’s FOV.”
input UnZoom(void) : “Stop controlling the player’s FOV.”

spawnflags(flags) =
[
1: “Allow Suit Zoom” : 0
]
]

This looks like the holy grail. I wonder what setting this number to 180 or 210 would do?

PointClass base(Targetname,Parentname) editormodel(“models/editor/camera.vmdl”) = point_viewcontrol :
“A camera entity that controls the player’s view. While it’s active, the player will see out of the camera.”
[
fov(float) : “Field of view” : “90” : “Player FOV (if Set FOV spawnflag is set)”
fov_rate(float) : “Seconds to reach FOV target” : “1.0” : “Amount of time it should take to reach the specified FOV”

target(target_destination) : “Entity to Look At” : : “Name of the entity that the camera should point at and track while active.”
targetattachment(string) : “Target Attachment Name” : : “If set, the camera will focus on the specified attachment on the ‘Entity to Look At’.”
wait(integer) : “Hold Time” : 10 : “The amount of time the camera should control the player’s view for, after which it deactivates itself. If the camera should stay active until told to deactive, set the ‘Infinite Hold Time’ spawnflag.”
moveto(target_destination) : “Path Corner” : : “The first path corner in a track that the camera should move along once it’s activated. If not specified, the camera won’t move.”
interpolatepositiontoplayer(boolean) : “Interpolate Position To Player” : 0 : “Gradually interpolate player’s position to here on start. (Episodic only)”

spawnflags(flags) =
[
1: “Start At Player” : 1
2: “Follow Player” : 1
4: “Freeze Player” : 0
8: “Infinite Hold Time” : 0
16:“Snap to goal angles” : 0
32:“Make Player non-solid” : 0
64:“Interruptable by Player” : 0
128:“Set FOV” : 0
]
speed(string) : “Initial Speed” : “0” : “The starting speed that the camera moves at, if it’s on a path track.”
acceleration(string) : “Acceleration units/sec^2” : “500” : “The speed at which the camera accelerates to path corner’s desired speeds.”
deceleration(string) : “Stop Deceleration units/sec^2” : “500” : “The speed at which the camera decelerates to path corner’s desired speeds.”

// Inputs
input Enable(void) : “Enable the point_viewcontrol, and start controlling the player’s view.”
input Disable(void) : “Disable the point_viewcontrol, and stop controlling the player’s view.”

// Outputs
output OnEndFollow(void) : “Fired when the point_viewcontrol deactivates, due to the Disable input being received, the Entity to Look At being destroyed, or the Hold Time expiring.”
]

There’s also other files with interesting references to those keywords like gameinfo.cgi, halflife2.fgd, hlvr.fgd, etc. I’ll let you guys know if I find a solution.

9 Likes

In SteamLibrary\steamapps\common\Half-Life Alyx\game\hlvr\cfg\configschema.vcfg

I see the following:
“schema”

{
“app”
{
“r_size_cull_threshold”
{
“type” “float32”
“defaultValue” “0.3”
}

  "phys_step_threaded"
  {
  	"type" "bool"
  	"defaultValue"	"false"
  }

}

“machine”
{
}

“user”
{
}
}

When I increased r_size_cull_threshold from 0.3 to 0.6 and 0.9 it seemed to improve the culling a bit. on the right eye. The r might refer to right side. When I set it really high like 20 or 30 though, the culling was way worse lol making entire doors disappear in front of me. So I’m gonna play around with it more. Someone should experiment with setting it to 1 or 0. I’m guessing 0.3 means 30% of screen size.

When I google “r_size_cull_threshold” I find this page:
https://dotaskills.ru/dota-2-konsol-polnyy-damp

r_size_cull_threshold 0 cheat Threshold of screen size percentage below which objects get culled
r_size_cull_threshold_shadow 2 cheat Threshold of sun shadow map size percentage below which objects get culled
3 Likes

I found a pastebin file with a list of Half Life Alyx console commands:

https://pastebin.com/i4pQfnYG

I think the key command is:
vr_expand_cull_frustum : 2 : : degrees to add to fov to compensate for just-in-time HMD

More on how to use console commands:

6 Likes

May be we can try with adding it in the steam launch parameters like:
“-console -vconsole +vr_expand_cull_frustum {value}”

Edit: I think 25 is the good value for pimax headset in normal fov.

4 Likes

Awesome, so it worked? Try it directly through console first.

1 Like

Yes it work great, still have some issue with volumetric fog and shadows but it’s not bad to play (I’ll keep this configuration)

3 Likes

There’s volumetric fog settings I’ve seen in one of the files, it can be reduced or eliminated. As for shadows, yeah I’ll have to look into that. I can’t believe no one figured out this console command before me lol.

2 Likes

Amazing! So does it work on the StarVR One as well? I am out of the office now (damn, I should never leave that place for cases like this!) so I cannot try… :slight_smile:

2 Likes

I haven’t tried it yet on the StarVR. I’ll give it a shot later today!

2 Likes

@mixedrealityTV Okay, so I tested it out using the launch options. It works but with some glitches/tradeoffs.

When I set the value to 25, the culling is reduced on my right peripheral. When I increased it to 40, the main menu at the start of Half Life Alyx is not there. You have to move your head forward toward the menu. Then when you select a menu option, you have to again tilt your head forward until the new menu appears. At 40 value, once in game, objects were being culled right in front of me in both eyes, so I knew it was too much.

Next I tried value of 30 and this seems be a sweet spot. I still have to lean in closer to menus for them to show up, but the culling in the right peripheral is much further out of the peripheral. So it did improve it a lot! Some other downsides though are when I open the weapon menu, the weapon icons are shown but not the weapon ammo values, for that you have to move your head around a bit to make them show up. I also noticed from a far distance the bottles at the bar only appeared once I got to a certain distance. So it appears this frustum culling settings does not just affect the peripheral but also objects far in the front.

Personally I think I like Alyx better at the 30 value. But I think some other settings need to be changed to fix these minor problems. I’m going to experiment with other console commands and file settings.

3 Likes

Okay so I’ve found the best configuration is the following launch options:

-console -vconsole +vr_expand_cull_frustum 30 +vr_enable_volume_fog 0 +vr_main_menu_to_player_distance -40

First command will reduce object pop-ins on the right peripheral vision, however some objects from a far distance like bottles and cups on a table may not load right away until you get closer to them. This doesn’t happen that often so overall I’m very happy to have reduced on my right peripheral

Second command disables volumetric fog. In wide fov headsets like the StarVR One the fog seems too strong. Once I disabled it, the picture quality in HL: Alyx looks SO much better on this headset and the blacks look like they’re supposed to in this OLED headset.

Third command brings the main menu much closer to the player. When the game first loads, the menu will not be visible. You’ll need to stand at the feet mark and lean your head forward towards the menu for it to pop up. If you find your scrolling or selection doesn’t animate, you need to lean in again. When you select something from the menu, just lean in a bit for it to display too. This is the unfortunate tradeoff of doing the expanded frustum culling. Main benefit to this command, is that when I open the menu while in a game, it works perfectly fine without needing to lean in to it. So that’s why I offset the distance.

Let me know guys what these settings look like for you on Pimax or StarVR One. I have also tried 35 but that one made objects from a distance cull too close for my tastes. So 30 seems to be a balance. I’m currently trying to figure out how to fix the culling distance while leaving the first command enabled.

4 Likes

Good news, @VR-TECH @vrftw @crispybuttphd I found a built in command in Half Life Alyx for Mura correction. Just add

+vr_mura_correction 1

to the launch options from my post above. I think it looks better with mura correction and volumetric fog enabled. I wonder what you guys will think of the difference.

3 Likes

Iirc, that was controlled in HL2 by a different setting. It has nothing specifically to do with VR. I think it might be controlled by r_staticprop_lod.

2 Likes

I’ll look into that. So far I’ve tried

+r_occlusion_culling 0

Which disables distance culling altogether and it seems to have helped with most objects. I’ll have to do more testing. There is a slight performance loss with it disabled though. Like 75 to 90fps with slight jitters.

I suspect the reason why the more you expand the frustum culling FOV, the shorter the distance that objects get culled is, that the camera is looking through a triangle view. When you bendout that triangle, the FOV gets wider but the end of the triangle gets shorter. So that’s why I’m hoping another command or settings would disable distance culling outside of the camera’s view to some extent.

LOD stands for level of detail. Iirc it’s an integer additive offset, which controls the complexity of the model displayed for a given distance. That setting or a related one sets the distance at which a model is drawn (or not). Basically, it controls the complexity of the scene and allows distant objects to be drawn with less detail or hidden from view, until they get close enough to matter.

1 Like

So Sebastian, is the StarVR a loaner or a keeper?

Nice work man!! Currently My StarVR or Pimax give me error 108 with Steam VR. I’m prepping for my project. Hope I can sort out this out over the weekend

2 Likes

+vr_mura_correction 1

Really curious about that one. I’ll be trying tomorrow. Does it really reduce the mura on SVR1?

1 Like

Oh my god you guys! I’ve found the secret command that disables culling once and for all!

Use this in launch options:

-console -vconsole +sc_no_cull 1 +vr_enable_volume_fog 0

The last command is optional depending on if you like fog or not. After adding sc_no_cull, there is now absolutely no culling at all on my right peripheral vision! I have the full field of view and it’s incredible! The only problem left is the ocassional black smearing occuring on the right eye and that’s no big deal. Wow. I also did not notice any reduction in performance at all by turning off the culling.

@mixedrealityTV @VR-TECH @vrftw @crispybuttphd

12 Likes

You the man!!! That’s truly incredible, thanks for digging into this!

4 Likes