Add CascadeDistance to DirectionalLight component#10464
Closed
zhuberty wants to merge 935 commits intoFacepunch:masterfrom
Closed
Add CascadeDistance to DirectionalLight component#10464zhuberty wants to merge 935 commits intoFacepunch:masterfrom
zhuberty wants to merge 935 commits intoFacepunch:masterfrom
Conversation
* Can query FileIds, Author * Store the published file id so we can open an existing workshop item instead of publishing a new one each time, hook up OnComplete action while we're here
* Calculate file sizes and sha256 in parallel, since this is I/O bound * Batch all files and use a single rclone call
* [MakeDirty] allocates a Action delegate even if it's not used. * Use field keyword instead of manual backing fields * Add fast path for render object cloning, avoids expensive round trip through JsonPopulator
Avoids list allocation for GameObjects that have no components
Avoid RenderGroupKey allocations This would allocate a lot easily 60Mb/s. Instead of a dedicated struct we now compute a 64bit hash and use that for render grouping. Remove per frame HashSet, List and LINQ allocations
* More accurate and less allocation heavy version of Task.Delay - Shoot a single task delay for longer intervals - Only use expensive polling for the last sub threshold * Avoid ExecutingJob allocations when not tracking jobs
* Start moving SSR to bindless * Classify pass stub * Separable bilateral upscale, 0.3ms > 0.08ms, not happy with it still * start classify and intersect indirect * Commandlist support for UAV barriers and clearing a texture and gpubuffer * Simplify this, move classify to it's own shader * All indirect * ResourceState.IndirectArgument missing from ResourceStateToVulkanFlags switch * Fix indirect, all works * classify doesnt get skybox * Add Clear method to CommandList for clearing render target colors * bilateral upscale indirect too * Cleanup * Simplify bilateral upscale, With RADIUS=1, separable saves only 3 taps (6 vs 9), but costs 3 barriers + shared memory + atomics — the synchronization overhead far exceeds 3 extra texture loads of doing it with a normal X Y loop * Dotnet format, increase roughness threshold (we can afford it 😘 ) and dont need to discard these buffers on disable * compile shaders * this shouldnt be a property * Add FillGPUBuffer method for efficient buffer filling using native GPU commands
…4200) CollisionEventSystem is quite alloc heavy especially the action wiring causes 10+ heap allocations per collider.
Collect pending acks in List rather than spamming async tasks. Process List in Tick.
So we don't allocate when a GameObejct doesn't have any tags Fast & alloc free pass for GameTags.SetFrom
Let's see if this helps
* Remove unnecessary static singletons in MainMenu code * Empty SceneWorld delete queues during shutdown * Dresser cancel async load operation on destroy * Use reflection to null references to static native resources on shutdown This way we don't have to remember doing this manually. * Fix SoundOcclusionSystem using static lists to reference resources * Sound System: Use weak references to refer to scenes * Cleanup static logging listeners that kept strong refs to panels * UISystem Cleanup, make sure all panel/stylesheet refs are released * RenderTarget and RenderAttributes shutdown cleanup * Rework AvatarLoader, ThumbLoader & HTTPImageLoader Cache First try to go through ResourceLibrary.WeakIndex which might already hold the texture. If there is no hit, go through a second cache that caches HTTP & Steam API response bytes instead of textures. We want to cache the response bytes rather than the actual Texture, so stuff cached sits in RAM not VRAM. Before avatars and thumbs would reside in VRAM. * Fix rendertarget leak in CommandList.Attr.SetValue GetDepthTarget() / GetColorTarget() return a new strong handle (ref count +1). We need to DestroyStrongHandle() that ref. So handles don't leak. * Call EngineLoop.DrainFrameEndDisposables before shutdown * NativeResourceCache now report leaks on shutdown * Override Resource.Destroy for native resources, kill stronghandles * Deregister SceneWorld from SceneWorld.All during destruction * Ensure async texture loading cancels on shutdown * SkinnedModelRender bonemergetarget deregister from target OnDisabled * Clear shaderMaterials cache during shutdown * Refactor Shutdown code Mostly renaming methods from Clear() -> Shutdown() Adding separate GlobalContext.Shutdown function (more aggressive than GlobalContext.Reset). Clear some static input state. * Deregister surfaces from Surface.All in OnDestroy * RunAllStaticConstructors when loading a mount * Advanced managed resource leak tracker enabled via `resource_leak_tracking 1` Works by never pruning the WeakTable in NativeResourceCache. So we can check for all resources if they are still being held on to and log a callstack.
* Support types like Curve, Gradient, ParticleGradient in movies * Fix TransformOperation.OnReduce: old implementation was nonsense, could stack overflow * Add optional filePath parameter to GenerateScreenshotFilename * Force movie project to save even if we don't think it's changed * ITemporaryEffect.IsActive pseudo-property for movie recordings * Add ITrack.GetPathString() extension * Safety when trying to compress a sample block * Skip updating playback rate on renderers with a bone merge target * Move PropertySignal<T>.FromSamples to PropertySignal * Fix view not always updating when zooming * Enabled tracks defaults to false when applying * Movie export: manually call Scene.EditorTick, pause updates elsewhere (fixes Facepunch#10137) * CanMakeTrackFromProperties: default to only allowing user types
Introduced in Facepunch/sbox#4242 , which added some additional panel cleanup
Ignore static members when serializing or cloning components, makes no sense and breaks cloning with Expression Trees (that was introduced in Facepunch/sbox#4202) Fixes Facepunch#10161
Synthesizer never disposed its SpeechSynthesizer, causing background VoiceSynthesis threads to accumulate indefinitely (30+ seen in crash dumps). This may have caused crashes in TTS heavy games like DXRP. In addition we now properly terminate the SoundStream so SoundHandle.IsPlaying will become false after the stream has been played. See: Facepunch#4184
…te (Facepunch#4489) * Raise GameInstance load exceptions in editor instead of silently continuing with a shutdown instance * Key ResourceLoader watchers on AssemblyQualifiedName instead * Init AssetTypeAttribute Name from TargetType name if it's null
* Common components * Replace PackageCard with GameCard in content blocks, wrapped grid layout * Move GameCard to New/ folder, use ThumbWide for all sizes * Add `overflow: clip` and `overflow: clip-whole` modes * New game hub layout, hero * Layout + hero tweaks * Hero tweaks * Clean up content blocks, make it so that game cards don't clip on hover * Dynamic mask * Don't bother building CL for panels outside scroll view (400% perf benefit in main game hub) * Disable 3D bg when not visible (50% performance benefit) * Cards take their sizes from the image within them * Stash tweaks before big refactor * Initial hero carousel * Better carousel transitions * Try and reduce allocs inside CL combos * `background-playback-state` CSS property (`paused` or `running`, applies to video `background-image`) * Make out-of-focus carousel elements more obvious (no playing video, darkened) * New branding * Tweak navbar * Carousel shows full thumb if not visible, helps with visual noise * Accurate vote percentage 🙈 * Fix some carousel jankiness * Navbar feels less disjointed * Rebake menu lighting & envmaps * Finalize https://files.facepunch.com/alexguthrie/1b0311b1/bZKOQIQD0o.jpg * Trim down visual noise https://files.facepunch.com/alexguthrie/1b0311b1/oJh4qqaPsC.jpg * Gradient https://files.facepunch.com/alexguthrie/1b0511b1/uCyZyolkXE.jpg * Format * .heading labels use heading vars * Carousel slower time between auto switch * No play button on GameCard * Content blocks full width * Adjust GameCard sizes * Content block header padding * Add MenuHelpers.PlayGame, GameModal uses it, make hero "Play Now" button use it --------- Co-authored-by: Matt Stevens <matt@mattstevens.co.uk>
* Convert Model to Mesh https://files.facepunch.com/louie/1b0811b1/sbox-dev_gwjjqTHfS7.mp4 * Match hammer keybind
Fix transform update regression from 7b853ce Rotation.AlmostEqual default threshold was too loose (0.0001 dot-product ~ 1.62° angular tolerance), causing SetLocalTransform to silently drop small transform updates. - Rotation.AlmostEqual: default delta 0.0001 -> 0.0000001 (~0.05°), use MathF.Abs(Dot) to handle antipodal quaternions (q === -q) - Transform.AlmostEqual: use Rotation's own default instead of passing the Position/Scale delta to a dot-product metric
This reverts commit 2caf916.
Add `DeferGeneration` property to skip navmesh generation during scene load, allowing tiles to be generated and unloaded on demand at runtime. New public API: - `NavMesh.DeferGeneration` - skip tile generation on load - `NavMesh.RequestTileGeneration`/`RequestTilesGeneration` - fire-and-forget via cache loop - `NavMesh.UnloadTile`/`UnloadTiles` - remove tiles from the navmesh
* preload resolutions on init
Managed will queue deletion no need to check for proper destruction this early
…acepunch#4525) * WildcardMatch use MatchesSimpleExpression instead of expensive regex * More WildcardMatch tests
Dot-based AlmostEqual returned false for zero quaternions (default==default would be false), breaking the transform guard that catches uninitialized transforms.
* Don't UpdatePrefabInstances if the edited PrefabScene is the only one open in editor * Avoid some allocations when processing prefab guid mappings * Json Diff use 64bit hash isntead of paths for presence tracking, which avoids a ton of string allocations * Less LINQ in prefab GUID tracking code
zhuberty
commented
Apr 14, 2026
| /// Set to 0 to use the global <c>r.shadows.csm.distance</c> ConVar value (default 15000). | ||
| /// </summary> | ||
| [Property, Group( "Shadows" ), Title( "Shadow Distance" ), Range( 0, 50000 )] | ||
| [InfoBox( "Maximum shadow cascade distance in world units. 0 uses the global quality setting." )] |
Author
There was a problem hiding this comment.
the InfoBox doesn't really need to be here. the on-hover tooltip should be enough.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a
ShadowCascadeDistanceproperty to theDirectionalLightcomponent, allowing per-light control over the maximum shadow cascade distance. When set to0(the default), the light falls back to the globalr.shadows.csm.distanceConVar value.Motivation & Context
Previously, the maximum shadow cascade distance for directional lights was only controllable via the global
r.shadows.csm.distanceConVar (defaulting to 15000 units). There was no way to override this on a per-light basis from the editor or in code, making it difficult to tune shadow quality for individual scenes or lights without affecting all directional lights globally.Fixes:
Implementation Details
DirectionalLight.cs— Added aShadowCascadeDistancefloat property (grouped under "Shadows", titled "Shadow Distance", range 0–50000) with an[InfoBox]hint. The setter propagates the value to the underlyingSceneDirectionalLightscene object immediately if it is valid, following the same pattern used by other properties on this component.SceneDirectionalLight.cs— Added aCascadeDistancefloat property (default0f) to the scene-level light object. Includes XML doc comments explaining the override semantics.ShadowMapper.Directional.cs— Updated thefarClipcalculation to use a pattern match: if the light is aSceneDirectionalLightwith aCascadeDistance > 0, that value is used; otherwise the globalCascadeDistanceConVar fallback is used. This keeps the override opt-in and non-breaking.The value
0is used as a sentinel meaning "use the global setting," which avoids introducing a nullable type and keeps the property simple to use in the editor.Screenshots / Videos (if applicable)
Recording.2026-04-13.134357.mp4
Checklist