Commit Graph

7 Commits

Author SHA1 Message Date
Sam Pavlovic
65bbb0997f CSM Exclusion Culling (#4491) 2026-04-08 10:44:46 +02:00
Matt Stevens
1ed034cecd Shadows (#4109)
* 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.
2026-03-27 12:07:24 +00:00
Lorenz Junglas
54932b6725 (Shutdown) Leak Fixes (#4242)
* 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.
2026-03-09 17:02:27 +01:00
Sam Pavlovic
9ad402acae GPU Profiler (#3972)
* GPU Profiler proto by hooking up timestampmgr, simpler and more robust than previous attempt, let's fill this up with useful stuff now

https://files.facepunch.com/sampavlovic/1b3111b1/sbox_Spw1PjMXty.png

* Track all layers for GPU Profiler

* Add SetManagedPerfMarker

* Filter out bullshit, smooth out better, sort timings by cost

https://files.facepunch.com/sampavlovic/1b0211b1/sbox-dev_5Oi1pmpstq.png

* Clear entries when we disable gpu profiler
2026-02-03 09:47:18 +00:00
Sam Pavlovic
c8a483ed6f Clustered Culling (#3755)
* Clustered prototype

* Cleanup

* Cleanup, clustered culling uses switch case for readability, put generic math classes in math folder,

* Decals evaluate as a sphere, simpler, API for envmaps and lights dont take positionSs anymore

* Revert this shit on complex

* TiledCullingLayer > ClusteredCullingLayer

* Remove references to UseClusteredLighting/UseTiledLighting, just make it work everywhere

* Remove old tiled culling files

* Remove ClusterFrustum.hlsl since we have a generic one

* Remove OBB as we just test simple bounds for decal

* Final cleanups

* Remove references to tiled culling from native engine

* Adjust toolsvis for clustered

* Rename tiled culling references to clustered culling in render pipeline and tools visualization

* Build shaders

* Format

* Fix fog's near frustum cull plane and clustered warning from Mr. Copilot

* remove the last crumbs from tiled rendering

* Update shaders

* skybox rendering  use ClusteredCullingLayer instead of TiledCullingLayer

* Volume fog still referencing MAX_LIGHTS_PER_TILE, should have it using clusters but slower for now
2026-01-15 13:56:11 -03:00
Sam Pavlovic
d753fa0e24 Vulkan Raytracing Support (#2409)
* Re-enable CreateBLAS in RenderDeviceVulkan

* Update SPVRemapper to suppot raytracing opcode remapping

* Null initialize BLAS on RenderMesh

* Clean proper to generate BLAS on mesh data loading

* SceneRaytracingSystem stub

* Glue SceneRaytracing

* Remove pipelines from SceneRaytracing for now, just do TLAS, tie it to SceneRaytracingSystem, updates only once per frame just like how we want in a clean way
https://files.facepunch.com/sampavlovic/1b0611b1/ngfx-ui_Ck3ckzQQFT.png

* Send Descriptor Set of Raytracing World to RenderAttribute

* RTAO example using RayQuery

* RayTracingShader API stub

* Set SM6.0 and dxlevel 120 as default

* Instead of making raytracing opt-in, add -nogpuraytracing to force disable it

* Add IRenderDevice::IsRayTracingSupported() to easily query support for it

* Fix IsRayTracingSupported()

* RTAO Adjustments

* Allow Rayquery through AS on Compute and Pixel shaders even if not optimal, avoids it crashing when acessing it on compute

* Strip CRaytraceSceneWorld to just generating TLAS, dont need anything else for now and we need a better way to handle UGC than what's there

* Bindless::RaytracingAccelerationStructure()

* Simplify interface too

* Stub for UpdateSkinnedForRaytracing

* Dotnet format and fix documentation, make RTAO run at correct stage

* Only support raytracing in tools mode for now

* Move raytracing stuff to Raytracing.hlsl

* Stub RTX shader

* Internal Raytracingshader and remove useless stuff exposed from it

* VfxProgramHasRenderShader should check for VFX_PROGRAM_RTX too, that's the source from everything else failing

* Add arbitrary entry point support to shaders, needed as RTX shaders use [shader("XXX")] instead of MainXXX directly

* RenderTools::TraceRays API, preliminary implementation, RTAO uses RaytracingShader

* Make RT support internal, allow RT on game

* Remove RaytracedAmbientOcclusion, will be on scenestaging when ready

* Update engine/Sandbox.Engine/Systems/Render/RayTracingShader.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Fix rebase

* Update shaders

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-27 22:40:02 -03:00
s&box team
71f266059a Open source release
This commit imports the C# engine code and game files, excluding C++ source code.

[Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
2025-11-24 09:05:18 +00:00