Expose viewport bg color in editor preferences#10295
Closed
boxrocket6803 wants to merge 862 commits intoFacepunch:masterfrom
Closed
Expose viewport bg color in editor preferences#10295boxrocket6803 wants to merge 862 commits intoFacepunch:masterfrom
boxrocket6803 wants to merge 862 commits intoFacepunch:masterfrom
Conversation
Attempt to fix animation perf regression introduced by Facepunch#4128 Parallel.ForEach(IList<T>) uses static range partitioning which may cause load imbalance on hybrid P/E-core CPUs. Use Partitioner.Create(list, loadBalance: true) instead to restore dynamic chunk stealing that aws already used when using Parallel.ForEach(IEnumerable<T>)
…d trackball and view based rotation gizmos This commit adds a blender style trackball and view space rotation to all rotate gizmos. This is a breaking change to anything that currently uses the rotate method as you now must use the output directly rather than multiply it. Also added a method to get distance vector, not sure why it's only a float. --- Co-authored-by: William Lemon <William.Lemon2@gmail.com>
It will show as a dropdown in the editor which will allow you to pick an implementation.
* Verify CreateGameResults cookie before use * don't modify Output directly --------- Co-authored-by: nixx quality <nixx@is-fantabulo.us>
Can be used to train a dictionary for compression and analysing network packets.
* Fix native resource networking Native resource networking never properly worked, because it relied on ids that may not exist on a connecting client. - `Resource.ResourceId` is now Obsolete - Added `internal Resource.ResourceIdLong` - Networking now uses the 64 bit id - Register all Resource Paths during package load, so networking for native packages works even if they are not loaded - Client automatically loads networked resource if not cached - Clothing container now serializes path instead of ID but maintains backwards compatibility. - Drop ResourceId usage in tools
…nch#4146) Co-authored-by: nixx quality <nixx@is-fantabulo.us>
…JSON (Facepunch#4147) Fixes and issue where clothings referenced via their ResourceID (e.g. free clothings) would not save correctly Fixes Facepunch#10083
- Make a few Json Diff-related functions/classes public - Make `GameObject.DiffObjectDefinitions` public - Add static `Package.MountAsync()` - Make `Scene.SerializeProperties()` public
* Add Panel.OnDragEnter, OnDragLeave, OnDrop, maintain drop target and clear after drop
Co-authored-by: Mahir Muratovic <73573263+Kaikenny@users.noreply.github.com>
fixes "Error calling event 'hotloaded' on 'Editor.ComponentSheet'
… same behaviour elsewhere (Facepunch#4152)
* Use command lists for UI rendering
So far we only had a way to get the Color buffer of a render target, this lets us use the depth target as well in commandlists.
* Use ToArray to avoid collection modified while iterated exception Not sure this ever actually happened but better to be save. * Remove ValidatePrefabLookup from SerializePrefabInstance ValidatePrefabLookup may have modified GUIDs incorrectly on undo/redo. Also Serialize should be read-only op. ValidatePrefabLookup is still called at enough other places.
* Add Json.Deserialize<T>( ref Utf8JsonReader reader ) * Add Json.Serialize<T>( Utf8JsonWriter writer, T target )
…of derived type - not always property type
May fixes some issues when enabling/disabling nav areas.
Keep temp list so we can sort in place Cache occlusion sort predicate in static to avoid action allocation
Fixes timing scopes to more accurately represent a per-frame main thread breakdown, and prevents spikes when GC is executed. - **GcPause** - New separate timing scope showing time spent in GC per frame - GC pause time is subtracted from all other scopes, so each scope now only tracks its own code execution and no longer includes GC overhead - e.g. when GC occurs during the audio scope, the audio scope no longer spikes to 20ms - **AudioMixingThread** removed from the main scopes - Runs on a separate thread, so its timings are effectively meaningless in the main thread view - All other scopes are main thread only - No longer relevant given the audio optimisation work done over the past months - **Scene** scope removed - Didn't make much sense as it was an aggregate wrapping many other timing scopes - Replaced with a finer `Update` scope that tracks `Component.FixedUpdate`/`Update` - **Editor** scope no longer shows in-game - Scopes reschuffled - e.g. verlet rope physics traces are now tracked under the physics scope - Audio occlusion queries are now tracked under the audio scope https://files.facepunch.com/lolleko/2026/March/02_12-59-QuixoticMarten.png
* Move duplicated ProjectInfo building to extension methods * Add moviemaker package reference to editor packages
When serializing and deserializing to/from JSON we need to explicitly write nulls.
Because for development/editing we need to differentiate the following cases:
1. JSON is of an older version (field missing) -> initialize with code defined default
2. JSON is of the current version and field is actually null -> initialize with null
For networking we don't need to differentiate between those cases since client and server have the same version of the code at runtime.
So in networking case we can omit nulls from the JSON and skip all of these:
```
"OnComponentDestroy": null,
"OnComponentDisabled": null,
"OnComponentEnabled": null,
"OnComponentFixedUpdate": null,
"OnComponentStart": null,
"OnComponentUpdate": null,
"OnPropBreak": null,
"OnPropTakeDamage": null,
```
However, this wont reduce the amount of data that ends up on the wire, because compression already does a good job at deduplicating those strings.
```
Raw JSON with nulls : 41Kb
Raw JSON skip nulls : 27Kb (13Kb saved, 33.6% smaller, 1.51x ratio)
LZ4 fast with nulls : 7Kb (34Kb saved, 81.9% smaller, 5.54x ratio)
LZ4 fast skip nulls : 7Kb (34Kb saved, 82.6% smaller, 5.76x ratio)
```
The main benefit instead comes from saving CPU resources as this makes compression/decompression faster, because there is less data to process.
```
LZ4 with nulls compress : 0.210 ms/op
LZ4 with nulls decomp : 0.232 ms/op
LZ4 skip nulls compress : 0.165 ms/op
LZ4 skip nulls decomp : 0.074 ms/op
```
* Shadows Rewrite: C#, bindless, flexible, quality options, less VRAM... Introduces a new shadow mapper written entirely in C#, as well as rewritten shader code for sampling shadow maps. This fully removes and replaces Source 2's native shadow mapping giving us greater flexibility and allowing us to open-source it all. The main goal for the new shadow mapper is greater flexibility whilst reducing complexity. Older shaders are incompatible with the new lighting buffers, and will need to be recompiled to receive lighting properly. What's new: - Bindless per-light shadow maps instead of a shared shadow atlas — this means games can avoid the shadow atlas cost if not using many shadows, but also allows games with many shadows to not be limited by atlas space. - Directional lights have developer configurable cascade count (1-4) and control over split ratio (logarithmic/uniform blend via lambda parameter), useful for games where you may not need multiple cascades. User quality settings define a maximum cascade count which always overrides developer settings, allowing low end hardware to use fewer. - Directional lights have a dedicated cbuffer and uniform fast path in rendering code, and are no longer binned and looped over with local lights. Every pixel on screen is always affected by a directional light. - CSM cascade selection uses bounding spheres instead of depth comparison, with per-cascade texel snapping to eliminate sub-texel shimmer. - Point lights use a TextureCube for cube shadows for much simpler rendering and mapping, along with hardware PCF filtering. - Local light shadow resolution is derived from each light's screen-space size. Shadows below a configurable threshold are not rendered at all. Lights are sorted by screen size, and r.shadows.max caps the total count, culling least important lights first. - User settings have been added for shadow quality (Low/Medium/High) controlling max resolution, max cascades, and PCF filter quality. - Local light shadow maps use D16 depth format, halving memory compared to D32. CSMs remain D32 for precision at large distances. (Although this could be a TODO, I bet we could make it work in D16) - ShadowHardness: New per-light property controlling shadow sharpness. Defaults to soft (0.0) and scales up to 4x sharper. For directional lights, hardness is automatically scaled per cascade proportional to texel density (wider cascades get softer shadows), and clamped so the filter never exceeds a full texel — ensuring consistent softness across cascade transitions. - Shadow debug overlay showing all information about allocated shadow maps, their textures, cascades and more. - Many new convars to control - r.shadows.max: Maximum number of shadow-casting local lights, sorted by screen size, least important culled first - r.shadows.maxresolution: Max texture size for a projected light shadow map (128–4096) - r.shadows.quality: Shadow filter quality (0=Off, 1=Low, 2=Med, 3=High, 4=Experimental Penumbra) - r.shadows.csm.maxcascades: Maximum number of cascades for directional light shadows (1–4) - r.shadows.csm.maxresolution: Maximum resolution for each cascade shadow map (512–8192) - r.shadows.csm.distance: Maximum distance from camera that directional light shadows render (500–50000) - r.shadows.debug: Show shadow debug overlay with CSM textures, cascade bounds, and memory budget - r.shadows.csm.enabled: Enable or disable directional light (CSM) shadows - r.shadows.local.enabled: Enable or disable local light (spot/point) shadows - r.shadows.depthbias: Rasterizer constant depth bias during shadow map rendering - r.shadows.slopescale: Rasterizer slope-scaled depth bias during shadow map rendering - r.shadows.size_cull_threshold: Screen size percentage below which local light shadows are culled - SceneLight refactored into a base class with ScenePointLight, SceneSpotLight, SceneDirectionalLight. SceneOrthoLight removed. - Simplified Light.hlsl: Light is now a class, DynamicLight merged into Light, ProbeLight and LightmappedLight no longer inherit from DynamicLight. - GPULight/BinnedLight struct reorganized and trimmed: explicit typed fields instead of packed uint4 Params, shadow data replaced with a shadow index into a separate StructuredBuffer, removed embedded shadow matrices and atlas bounds. - ViewLightingConfig cleaned up: removed ViewLightingFlags, Shadow3x3PCFConstants, EnvironmentMapSizeConstants, LegacyAmbientLightColor. - Baked light mode flags fixed: BAKED lights (lightmaps only) no longer create shadow maps. MIXED_SHADOWS gated to Stationary lights only (was unconditionally applied). RENDER_ALL_GEOMETRY flag removed. DirectLightMode enum documented across Hammer entity definitions. - Removed light cookie sheets; cookie UV derived from light transform (LightToWorld transpose). Cookie sampling simplified to a single bindless texture lookup.
* Shadows Rewrite: C#, bindless, flexible, quality options, less VRAM... Introduces a new shadow mapper written entirely in C#, as well as rewritten shader code for sampling shadow maps. This fully removes and replaces Source 2's native shadow mapping giving us greater flexibility and allowing us to open-source it all. The main goal for the new shadow mapper is greater flexibility whilst reducing complexity. Older shaders are incompatible with the new lighting buffers, and will need to be recompiled to receive lighting properly. What's new: - Bindless per-light shadow maps instead of a shared shadow atlas — this means games can avoid the shadow atlas cost if not using many shadows, but also allows games with many shadows to not be limited by atlas space. - Directional lights have developer configurable cascade count (1-4) and control over split ratio (logarithmic/uniform blend via lambda parameter), useful for games where you may not need multiple cascades. User quality settings define a maximum cascade count which always overrides developer settings, allowing low end hardware to use fewer. - Directional lights have a dedicated cbuffer and uniform fast path in rendering code, and are no longer binned and looped over with local lights. Every pixel on screen is always affected by a directional light. - CSM cascade selection uses bounding spheres instead of depth comparison, with per-cascade texel snapping to eliminate sub-texel shimmer. - Point lights use a TextureCube for cube shadows for much simpler rendering and mapping, along with hardware PCF filtering. - Local light shadow resolution is derived from each light's screen-space size. Shadows below a configurable threshold are not rendered at all. Lights are sorted by screen size, and r.shadows.max caps the total count, culling least important lights first. - User settings have been added for shadow quality (Low/Medium/High) controlling max resolution, max cascades, and PCF filter quality. - Local light shadow maps use D16 depth format, halving memory compared to D32. CSMs remain D32 for precision at large distances. (Although this could be a TODO, I bet we could make it work in D16) - ShadowHardness: New per-light property controlling shadow sharpness. Defaults to soft (0.0) and scales up to 4x sharper. For directional lights, hardness is automatically scaled per cascade proportional to texel density (wider cascades get softer shadows), and clamped so the filter never exceeds a full texel — ensuring consistent softness across cascade transitions. - Shadow debug overlay showing all information about allocated shadow maps, their textures, cascades and more. - Many new convars to control - r.shadows.max: Maximum number of shadow-casting local lights, sorted by screen size, least important culled first - r.shadows.maxresolution: Max texture size for a projected light shadow map (128–4096) - r.shadows.quality: Shadow filter quality (0=Off, 1=Low, 2=Med, 3=High, 4=Experimental Penumbra) - r.shadows.csm.maxcascades: Maximum number of cascades for directional light shadows (1–4) - r.shadows.csm.maxresolution: Maximum resolution for each cascade shadow map (512–8192) - r.shadows.csm.distance: Maximum distance from camera that directional light shadows render (500–50000) - r.shadows.debug: Show shadow debug overlay with CSM textures, cascade bounds, and memory budget - r.shadows.csm.enabled: Enable or disable directional light (CSM) shadows - r.shadows.local.enabled: Enable or disable local light (spot/point) shadows - r.shadows.depthbias: Rasterizer constant depth bias during shadow map rendering - r.shadows.slopescale: Rasterizer slope-scaled depth bias during shadow map rendering - r.shadows.size_cull_threshold: Screen size percentage below which local light shadows are culled - SceneLight refactored into a base class with ScenePointLight, SceneSpotLight, SceneDirectionalLight. SceneOrthoLight removed. - Simplified Light.hlsl: Light is now a class, DynamicLight merged into Light, ProbeLight and LightmappedLight no longer inherit from DynamicLight. - GPULight/BinnedLight struct reorganized and trimmed: explicit typed fields instead of packed uint4 Params, shadow data replaced with a shadow index into a separate StructuredBuffer, removed embedded shadow matrices and atlas bounds. - ViewLightingConfig cleaned up: removed ViewLightingFlags, Shadow3x3PCFConstants, EnvironmentMapSizeConstants, LegacyAmbientLightColor. - Baked light mode flags fixed: BAKED lights (lightmaps only) no longer create shadow maps. MIXED_SHADOWS gated to Stationary lights only (was unconditionally applied). RENDER_ALL_GEOMETRY flag removed. DirectLightMode enum documented across Hammer entity definitions. - Removed light cookie sheets; cookie UV derived from light transform (LightToWorld transpose). Cookie sampling simplified to a single bindless texture lookup.
…acepunch#4409) * Instead of in a EditorEvent.Hotload, which only happens in the editor * Fixes exceptions on connected clients after hotload (Facepunch#10246, Facepunch#10210)
…acepunch#4409) * Instead of in a EditorEvent.Hotload, which only happens in the editor * Fixes exceptions on connected clients after hotload (Facepunch#10246, Facepunch#10210)
* Add DisableClientRecording config property in MovieRecorderSystem * Fix handling missing prefabs when creating targets * Fix AutoBind finding prefab scenes(?) * Include current game's ident in __references for movie recordings * Make exceptions when serializing blocks survivable * Survive trying to compress NaN / infinite transforms / rotations * MemberProperty: use delegate instead of reflection when getting value * PropertyBlockWriter: avoid allocating _samples list for constants * Fix creating targets from prefab with multiple same-type components * Add TextRendererCapturer, fix recording strings
* Add DisableClientRecording config property in MovieRecorderSystem * Fix handling missing prefabs when creating targets * Fix AutoBind finding prefab scenes(?) * Include current game's ident in __references for movie recordings * Make exceptions when serializing blocks survivable * Survive trying to compress NaN / infinite transforms / rotations * MemberProperty: use delegate instead of reflection when getting value * PropertyBlockWriter: avoid allocating _samples list for constants * Fix creating targets from prefab with multiple same-type components * Add TextRendererCapturer, fix recording strings
Contributor
There was a problem hiding this comment.
Pull request overview
Exposes the Scene View (editor camera) viewport background color as an editor preference, preserving the previous hard-coded default.
Changes:
- Replaced the hard-coded scene viewport clear color with
EditorPreferences.CameraBackgroundColor. - Added a new
EditorPreferences.CameraBackgroundColorpreference backed by an editor cookie (defaulting to the old value). - Surfaced the new preference on the Scene View preferences page.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| game/addons/tools/Code/Scene/SceneView/SceneViewportWidget.cs | Uses the new preference for the editor camera background clear color. |
| game/addons/tools/Code/Editor/EditorPreferences/PageSceneView.cs | Adds the background color field to the Scene View preferences UI. |
| engine/Sandbox.Tools/EditorPreferences.cs | Introduces the new persisted preference (cookie-backed) with the prior default. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Rewrites Vulkan per-thread resource management to use a pooled PerThreadDataVulkan_t slot system with a TLS fast-path, replacing the previous thread-index/map/array approach and updating Vulkan call sites to pass PerThreadDataVulkan_t* instead of thread indices. * Remove ThreadIndex, SetAssociatedThreadIndex & MaxDeviceThreads (see what breaks) * Refactor per-thread vulkan data into a single pooled struct Replace fixed-array per-thread Vulkan data with a dynamic slot pool. Threads grab slots on demand, hot path is just a TLS read, completly lock-free Two mechanisms manage slot lifetime: - Ref counting: render contexts and the render thread AddRef to keep their slot alive as long as they need it. - Idle reclaim: slots nobody is holding onto get recycled after N frames of inactivity. Keeps short-lived threads (async shader compiles, texture uploads) from leaking slots, while still letting a thread that calls GetPerThreadData() every frame hang onto the same slot and all its resources (command pools, descriptor pools, pipeline cache, etc). Moved VkPipelineCache into the per-thread struct with lazy creation. * Add CRenderDeviceVulkan::GetPerThreadData() acquires from pool * Use PerThreadData eveywhere instead of ThreadIndex And do proper thread data shutdown cleanup * Main render thread gets it's own permaned PerThreadData instance * Rework pipelinecache to use PerThreadData instead of VkPipelineCache directly
* Fix GCN/Polaris crash when averaging clusters, snap positionSs to the top-left pixel of the 2x2 quad to avoid cluster divergence without QuadLaneReadAt * update shaders
) **Broadcast** now encodes the wire payload just once and sends the same bytes to every recipient, before we did one redundant compression per connection. This primarily reduces CPU load on the server/host. **Chunking** Large messages are now compressed before chunking rather than after. Resulting in slightly smaller payloads. The receiver now decompresses a single reassembled payload instead of decompressing every chunk independently, significantly reducing CPU load on receiving clients. **Refactor** Chunking and compression are now low-level wire concerns handled by Connection rather than being mixed into the high-level message types. The old `InternalMessageType.Chunk` enum is removed; chunk framing uses a dedicated wire flag byte alongside `FlagRaw` and `FlagCompressed`. **Results (Chunking changes)** Synthetic data, results on real payloads may differ. Benchmarks (1000 GOs / 2000 components, ~1MB payload, 500 iterations): Wire size (chunk-first-then-compress): 275KB Wire size (compress-first): 259KB (5.7% smaller) Send chunk-first: 0.85 ms/op (old) Send compress-first: 0.88 ms/op (new) Recv chunk-first: 1.16 ms/op (old) Recv compress-first: 0.34 ms/op (new, 3.4x faster)
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
Allows the background color for the editor camera to be set via editor preferences, as opposed to being hard coded. By default it uses the previously hard coded value.
Motivation & Context
I personally prefer dark gray in my viewport backgrounds.
Video
2026-03-27.18-29-32.mp4
Checklist