Picture in Picture Port | True PiP [Multithreaded Branch] - #578
TheLostInPlace wants to merge 44 commits into
Conversation
- true picture-in-picture scope rendering (r__svpscope) - on-screen lens composite, reticle, smooth and analog zoom, scope debug - per-viewport lighting, shadows and motion vectors - DLSS-SR engine scaffolding (r__svp_dlss), eval stubbed
The cvar is DX11-only now so the script gets nil on DX9/DX10; treat nil as not-SVP
|
Temporarily putting the PR on draft while I investigate an edge case of scopes not rendering their PiP viewport onto the eyepiece properly on (1) weapon that I have found so far, I thought I fixed the error for all weapons ;-; |
|
Alright that was a quick investigation, turns out that weapon had an improperly positioned eyepiece mesh resulting in the PiP drawing incorrectly For issues with PiP:
In general, you want the blue line to go through the scope, with the upvector lines properly pointing up, and the eyepiece detection circle on the eyepiece |
- derive the eyepiece from the lens bone skinning matrix instead of the kinematics root, so a scope skinned to an offset bone sits on the glass and tracks ADS instead of landing at a fixed offset - force the SVP camera up to world up so a canted scope renders upright while its reticle stays canted - among multiple lens surfaces keep the eye-nearest in-front one (the ocular) - take the eyepiece center from the lens AABB
|
Here's a download link to the current MT build of the PiP exes with the db0 and PDB. Keep in mind this was tested with the following primary stack on GAMMA:
Installation is similar to how you would install the current exes, so re-pasting it here: InstallationStart Guide |
New options_modded_exes_pip.script page exposing the SVP scope cvars as dropdowns/sliders: r__svpscope (OFF/Eyepiece/Objective), g_zoom_smooth, g_zoom_analog, r__svp_render_scale, r__svp_dlss, r__scope_debug. Registered in the Visual group next to 3D Scopes. Adds the eng localization in ui_mm_modded_exes.xml: page title, menu entry, control labels and hints, plus the ui_mm_lst_Eyepiece/ui_mm_lst_Objective list-value strings the r__svpscope dropdown resolves through.
Engine scope_lensfx pass over the composited disc (works with any scope mod, never touches 3DSS): magnification tunnel, radial blur, barrel distortion and exit-pupil dimming, plus a dynamic eye-box crescent. Gated by r__svp_lensfx / r__svp_eyebox, every value a cvar. r__svp_recoil_comp: during fire, pull the SVP camera (orientation and position) toward the main view in proportion to the live recoil so a PiP scope stays usable like a shader scope instead of jumping with the weapon-bone kick. SVP-only, the real recoil is untouched. In-game tuner overlay (lens_fx_tune.script + ui_lens_fx_tune.xml) plus the lens cvars and the tuner open key in the Modded Exes Picture in Picture page. Expose CWeapon zoom methods to Lua so the tuner can drive the scope. WIP checkpoint: scope image holds in full auto, but the weapon-model recoil can still dip the scope body across the lens.
r__svp_recoil_hold (0-1): while a PiP/SVP scope is up, damp the weapon shoot-shake and inertion in CWeapon::UpdateHudAdditional so the optic stays on the eyeline during fire instead of riding the gun. SVP-only, default off; iron sights / 3DSS / hipfire keep their full movement. r__svp_recoil_comp is now orientation-only. Blending the eyepiece position toward the camera fought svpCamera's FOV sizing (it projects the eyepiece radius), so the magnified view zoomed out as recoil accumulated then snapped back. Position steadiness is recoil_hold's job now. Clean up comments to be more concise
The captured graph is culled to the main frustum and rendered twice; the SVP re-submitted the whole main-frustum world through a magnified cone that sees a fraction of it. Reject items whose world bounding sphere is fully outside the SVP frustum, built from the same matrices[1] SetActive renders the SVP with so it removes exactly what the GPU clips. Gated to the SVP gbuffer pass so the main view and non-PiP / non-MT renderers stay byte-identical. Static geometry carries no per-item matrix, so its world-space vis.sphere is tested directly. Measured: SVP gbuffer ~17ms to 2-8ms, ~13-18ms off the scoped frame, scaling with zoom (96% culled at max). Default on, r__svp_cull 0 restores the old path.
|
Let me know if there are any issues with this (pop in, LOD issues, etc) |
…ter + SSS fixes Recoil - Add r__svp_pupil_boost, enlarges the 3DSS scope exit pupil while a PiP scope is up so full-auto recoil no longer collapses the lens to black. The blackout is the 3DSS parallax exit-pupil shadow driven by V_tangent, a larger EXIT_PUPIL widens the clear disc and divides down the recoil shift. - Remove r__svp_recoil_comp, recoil_hold and recoil_smooth plus the g_pip_recoil plumbing, they steered the SVP image not the shadow and never fixed the blackout. - Default stabilize and zoom_smooth to 1, pupil_boost to 6, eyebox_shift to 0. Performance - Add r__svp_cull_grass, per-instance frustum reject so the SVP grass is culled to the scope cone instead of replaying the whole main field, with the cull frustum arming decoupled so grass and geometry cull toggle apart. - Add r__svp_skip_motionblur, skip_volumetric and skip_grass for the scope pass. Reflections and water - Add the r__svp_skip_ssr tri-state, 0 reflective water, 1 flat water plus SSR (default), 2 matte. - Fix the scope water SSR temporal reprojection, build the per-viewport current and previous matrices for the SVP so it stops accumulating against the main view stale matrices (the matte vs reflective flicker). SSS - Add r__svp_sss_sun, compute the SVP SSS pass so the scope keeps the sun contact shadow term.
Resolve the r4.cpp shader_compile conflict by composing both shader-cache changes: upstream's source-CRC cache key (440495c) keys the read/write, and our r__shader_debug skips the cache entirely plus emits debug flags for RenderDoc. The two are orthogonal so both are kept.
r__svp_pupil_track ramps pupil_boost with the live bore off-axis drift, so the exit pupil stays tight when the aim is steady and only opens under recoil (default 0 keeps the constant boost) r__svp_reticle_mag drives shader_scope_params (curMag/min/max) from the engine each SVP frame, so the FFP reticle scales with zoom regardless of the 3DSS zoom script state (default 1)
|
I'm at a point where this isn't much more to port over/fix/adjust as far as I am aware with my testing, so the PR is "complete" for now so to speak. I know you mentioned that you won't merge anything render related till SSS24, so just wanted to let you know the state of the PR Edit: Swallowed my words after doing some testing with Ascii on SSS24 + PiP |
…tion r__svp_cull dropped close skinned NPCs' face and hood because a dynamic visual's vis.sphere is the rest-pose bound and does not track the animated bones, so it now culls only the static world the SVP and main share the captured sorted and wmark lists and whichever pass runs first was clearing them, leaving the other empty. clear on the last consumer instead: gbuffer is main-first so wmarks clear on the SVP pass, combine is SVP-first so the translucent list clears on the main pass. fixes bullet holes and decals missing in the scope, and translucent geometry vanishing from the main
…diagnostics - objective auto-derived per scope from HUD geometry (geomscan): scan a snapshot of the HUD geometry (taken before render_hud clears the lists) for the forward-most on-axis node = the objective glass plane. no data table; r__svp_obj_dist is now a fine-tune scale - real front-lens capture when a scope flags a distinct objective surface, geometric fallback otherwise - recoil gate: r__truepip_recoil + zzz_truepip_recoil_gate.script monkey-patches GAMMA Enhanced Recoil shoot_effect (0 normal / 1 off-in-pip / 2 off) - scope/weapon/mag bridge to the render side + svpcam offset log + magenta camera cube overlay - temp scope_debug probes (lenssurf/lensbox/scopediag/bone scan) pending strip
…ip diagnostics 3DSS gate (s3ds_param_4) never fired. pip used IsSVPActive(), which is false at 3DSS shader-bind time, and the !see_through guard blocked nearly every scope (bit 2 is the see-around-the-tube feature, on for almost all). Switch to true_pip_on and drop the see_through guard (the gate preserves bit 2 anyway). Parallax shadow / chromatism / nvg-blur now clear in true-pip optical mode (verified firing settings 30 -> 12). Objective radius: eyepiece-relative (eyepiece.radius * r__svp_obj_size, one global knob). The front-node geomscan swung ~6x across scopes, conflating the glass with the bell housing, so no single obj_size fit. Drop the geomscan radius and the lateral-extent attempt; geom_front still drives the objective position. Remove the now-dead r__svp_optics_er / r__svp_optics_obj cvars; the eyebox derives eye-relief and objective from real geometry. Strip the temp [truepip] log diagnostics (svpcam / header / objcap / lensbox / geomscan / eyebox / lenssurf / 3dss-probe / 3dss-gate) plus the SVP_DiagScope dead-end bone probe and the g_pip_scope_section/g_pip_weapon_section log bridge. Keep debug_scope (the world camera cube + lens outlines) and SVP_LensBoneXform.
…cvars Eye-box now reads real per-scope eye-relief (cm) and exit-pupil (ratio) straight from the 3DSS config (s3ds_param_1.y/.z, already live on the engine global) instead of deriving them from scope geometry. New cvar r__svp_optics_real (1 = real, 0 = geometry fallback). The geometry path is mathematically unchanged, so non-3DSS scopes do not regress. Magnification-scaled eye-box vignette: the static real exit-pupil does not tunnel at high zoom, so r__svp_optics_zoomvig (on/off) + r__svp_optics_zoomvig_blend (0 = static, 1 = exit-pupil / mag) tighten the clear zone as magnification rises, restoring the per-scope "tube closes in as you zoom" darkening. The real-path eye-offset shift uses a larger base (0.8 vs 0.10) because the real eye-relief K runs ~8x below the old camera->eyepiece HUD-distance proxy. Drop the dead recoil cvars. r__svp_pupil_boost + r__svp_pupil_track never fired (their gate used IsSVPActive(), which is false at 3DSS shader-bind time) and are moot now that the s3ds_param_4 bit-gate clears the parallax shadow at its source. r__svp_zoom_smooth was vestigial (base recoil does not punch the FOV). The s3ds_param_1 binding collapses to a plain pass-through. r__truepip_recoil (the script-recoil gate) is now the sole recoil cvar. (A temporary scope_debug>=2 "optics:" log remains in the eye-box for first-test verification, to strip once the optics defaults are locked.)
Zoom-vignette confirmed good in-game, so remove the scope_debug>=2 "optics:" Msg that was left in for first-test verification. No behavior change.
…oke fix SVP perf: r__svp_cull_ssa (default 4) magnification-aware small-object cull of the scope gbuffer, the draw-call-bound dominant cost (~-45% of the SVP geometry pass); r__svp_adaptive_res (default 1.2) sizes the SVP render to the on-screen eyepiece disc, latched once per ADS; r__svp_lod (default off) coverage-scaled LOD, a no-op on the single-LOD world but kept; r__svp_diag + RENDER_GBUFFER[SVP]/SVP_ACCUM/COMBINE_SVP markers for profiling. Lens cosmetics (all default-off): two-zone eyebox, dirty-glass, radial fringe, vignette. Body-DoF and lens grain removed. Fix: priority-1 forward geometry (anomaly smoke) was missing from the main view when scoped, the SVP combine consumed render_static/dynamic(1) before the main combine ran. Build: LTCG:INCREMENTAL on the WPO configs.
|
RC-1 Build for testing: RC1 |
…+ non-PiP hardening Reticle: solve the custom-reticle curMag so current_zoom = scope_mag (full FFP), so the PiP reticle matches the 2D scope size instead of rendering at ~half. The custom reticle sizes off current_zoom = (curMag-minMag)*0.4+1, and feeding scope_mag raw only reaches 0.4*scope_mag+0.6. r__svp_reticle_curmag becomes an FFP scale multiplier (default 1.0). NPC cull: exempt dynamics (non-null pMatrix) from the SVP small-object SSA cull at both render sites, so the perf cull only skips tiny static clutter and never NPCs or items. The static-cull perf win is untouched. Recoil gate: default r__truepip_recoil to 1 (PiP-only) instead of 2. Mismatch hardening: gate the PiP option page and the lens-FX tuner behind a runtime capability check so the gamedata does not crash on a non-PiP engine.
…draw-list cleanup - reticle now sizes to mag/min so it matches the 2D/3DSS reticle on every scope (fixes both low-min like CQBSS and high-min like 1P59/MarchF) - SpecterDR/PS-320 no longer black out at max zoom, curMag bounded so the exit-pupil shadow stays sane - r__svp_clean_optics (default 1, PiP only) strips the 3DSS fake cosmetics: parallax shadow, chromatism, nvg blur, fisheye - r__svp_roll_stabilize toggle for lean/cant (default 0 realistic tilt, 1 leveled) - consolidated the SVP draw-list clear band-aids into one svp_clear_shared_list helper - removed the eyebox/lens-FX engine pass and swept ~28 dead cvars - removed the experimental lens-FX tuner gamedata to rebuild cleanly later
…, HUD-in-SVP barrel, grass defer-clear, SVPCOP/SVP-CFG diagnostics, minMag+NDC floors, pip-ship BuildBoth/RC
…/set idiom leaked one D3D ref per call, hundreds/sec while ADS, monotonic VRAM growth (3 sites: reticle alias, RT remap, debug overlay)
…e - the lens composite blends srcalpha with forced o.a, propagating source alpha would turn the lens transparent
… stock pass - CHK_DX is a no-op so VRAM-exhausted creation silently produced a half-built target with NULL surfaces bound every frame
…on capturing this and TargetSVP could fire after a device reset deleted the target (latent use-after-free)
…gs, 4 fixes, verification evidence, runtime test plan)
… image gets dof/lut in its own combine AND again over the composited lens, the gates land each exactly once (default 0 keeps the current look)
…lowing signs/lamps/anomalies were main-only and rendered dark through the scope (default 0 = stock)
… ms + draw-call/vert deltas via existing RCache.stat, gated r__svp_diag (no timer existed for the SVP pass)
…rity matrix, 3 Tier-1 implemented, 10 Tier-2 blueprints, coverage checklist)
… thermal/tube sights - barrel through the scope: captured-HUD replay with the eye-ray anchor, window (1:1) and magnified mapping modes (r__svp_hud_fov_match), sway compensation, eff-mag gate, svpscope 2 only - full-barrel: scope-body skip (aimed-lens cylinder + wrap test), near plane at the eye, near-field bokeh defocus at the capture seam (svp_nearblur, golden-angle gather) - aimed-lens selection in deriveScopeLens, the last-wins loop latched wrong lenses on multi-lens weapons (ACE52+CQBSS tube rings) - zoom-0 tube sights: captured-ocular SVP activation, 1x re-imaging, thermal objective clip and sharp capture, the fakescope overlay stands down under true PiP - true-PiP shader sentinel (w = -2, legacy Lua -1 persists in user.ltx), svp_optics reticle field constant, ST_PIP_PRECISE bit (r__svp_reticle_precise, default 0), auto-boresight (r__svp_boresight, opt-in) - svpscope mode split: 1 = classic eyepiece-camera PiP, 2 = realism with the near-eye camera owned by the mode (r__svp_near_eye removed), eyebox drift shadow + r__svp_stabilize removed - diagnostics: [SVP-BARREL]/[SVP-AIM]/[SVP-HUD]/cant probes, cop_diag levels, aim-confirm overlay
… TBN switch dead weight every view-coupled V_tangent use is zeroed or replaced under true PiP, so the mesh-tangent vs cotangent frame can no longer affect anything visible
…e-lens pick the hud skip test located pieces at their rest pose, addon scopes sit at their attach bone, and hidden markswitch lenses could win the eyepiece pick. [SVP-LENS] candidate probe added
…05/007/009) - r__svp_light_capture: the fog-distance light cull is a naked-eye heuristic, relax to the far plane while the SVP renders so distant lights reach the magnified image - r__svp_local_exposure (+_bias): grade the scope image by its own measured luminance via s_tonemap_svp, dark-room-to-bright-outdoors no longer blows out - r__svp_bloom: run ssfx bloom on the SVP pass so magnified bright sources flare
…stitution design, hazard register scouted via 6-agent sweep + first-hand verification: the far accumulate samples via fuckingsun->X.D.combine (xform param dead for FAR), the SVP target already owns an unused rt_smap_depth, SetActive remaps make the texture swap symmetric. Main atlas never written.
…rch-grounded) - r__svp_twilight: the exit pupil (ocular*ratio shrunk by zoom) vs the env-adapted eye pupil, image dims by the squared ratio at high mag in low light (Zeiss ~4mm rule), day unaffected, electronic sights exempt, floor 0.25, [SVP-TWL] diag - r__svp_parallax: the bench-measured real reticle shift (~0.15 mrad at full eye deflection, sub-pixel) restored into the centered field via svp_optics.y, 0 = pinned, up to 10x
|
There have been some pretty significant changes that require a 3DSS Patch I made to make certain things work properly, so I would not merge/review until I change the PR from draft to review. Progress tracker: https://discord.com/channels/912320241713958912/1521006040550867044 The state of the non-mt port is also on hold for now, wrangling the MT branch is taxing enough as is for now. |
- the barrel near plane now sits at the FRONT lens: max of the objective distance and the measured scope-body extent, so under-tube attachments (lasers) never render in the image and clip-on optics (skeet thermal) push the plane forward with them - r__svp_hud_full 2 (new default) = front-plane clip, 1 = the old full-barrel-from-eye, 0 = objective clip with the body rendered - the piece scan measures every frame (thermals too) and drops coaxial clip-on bodies past the objective (t 1.4-2.6, tight radial keeps the barrel out)
…he eye the front-plane near clip cut the barrel mesh mid-length (hard planar slice). the camera now slides up the anchored aim ray TO the front plane with a small near, so everything behind the front lens falls behind the camera and the barrel ahead keeps its full mesh
… eye the entrance-pupil camera pushed the whole barrel out of the narrow magnified cone (closer viewpoint = larger angular offset), no barrel rendered. mode 2 now keeps mode 1 geometry (eye camera, near 0.08, no cut plane) and drops pieces WHOLLY behind the front plane in the piece scan, spanning pieces (barrel, rail) render whole, discrete rear attachments (lasers) never appear. g_svp_hud_skip_scope carries the mode
|
Closing in favor of #615 |

True picture-in-picture scopes + per-scope optics + SVP DLSS-SR scaffolding (DX11)
Summary
Adds true picture-in-picture (PiP) scope rendering to the MT engine: the scoped image is a real
second render of the scene from the optic's camera, composited through the lens instead of the flat
FOV/zoom trick. On top of that it adds a physically-derived optics layer (real per-scope eye
relief / exit pupil, two-zone eye-box, lens cosmetics), a 3DSS cosmetic gate that removes the
flat-scope parallax-shadow crescent for optical scopes, SVP performance levers (frustum + small-
object culling, adaptive scope resolution, supersample), and all engine-side scaffolding for a future
DLSS-SR upscale of the scope render (reconstruction left as a documented stub).
The feature is DX11-only (R4), additive, and off by default. With
r__svpscope 0the render isbyte-identical to stock MT, and the DX10/9/8 renderers (R1/R2/R3) are fully insulated.
all-in-one-vs2022-wpo-mtRequirements
PiP renders the scene into the in-world scope lens, so it relies on the 3D Shader Scopes (3DSS)
GAMMA addon to supply that lens geometry and reticle. 3DSS is already bundled in GAMMA, so GAMMA
users have it by default and no extra setup is needed. Without 3DSS (or an equivalent scope-lens
setup) there is no lens surface for the PiP image to composite into, and
r__svpscopehas nothingto draw. The real per-scope optics path (
r__svp_optics_real) reads the eye-relief / exit-pupilvalues from the 3DSS scope config; scopes without those entries fall back to geometry-derived values.
What's new (user-facing)
parallax, depth, and lighting inside the optic), with smooth and analog (variable) zoom, magnifier
reticle, and an over-zoom fix
physical eye-box (the dark vignette tightens as you move off the exit pupil and as magnification
rises), with an optional two-zone (exit-pupil + eye-relief) model
shadow crescent / blackout, chromatism, and NVG blur at the source (thermals and see-through optics
keep their stock look)
chromatic fringing, radial vignette, procedural dirty-glass grunge + edge rim, and a field-curvature
edge ring blur, all gated and tunable, with an in-game tuner page
geometry, adaptive scope resolution (render the scope to the on-screen lens disc), and optional
supersample
and TAA-stable while panning (including a per-viewport sky-prev fix so the sky reprojects correctly
under the scope camera)
on the eyeline; base engine/weapon recoil is untouched
Console Variables (default collapsed)
Console variables
The
r__cvars are registered only under DX11, so they do not exist on DX10/9/8. Theg_zoom_*cvars are engine-side and apply on every renderer.Core
r__svpscopeReal optics & eye-box (the physical model, master-gated by
r__svp_truepip)r__svp_truepipr__svp_optics_realr__svp_optics_softr__svp_optics_gainr__svp_optics_zoomvigr__svp_optics_zoomvig_blendr__svp_eyebox_reliefr__svp_eyebox_relief_sizer__svp_eyebox_relief_softr__svp_eyebox_aspectLens FX (gated by
r__svp_lensfx; cosmetics also active underr__svp_truepip)r__svp_lensfxr__svp_lensfx_strengthr__svp_lens_car__svp_lens_distortr__svp_lens_floorr__svp_lens_refmagr__svp_lens_vigkr__svp_lens_blurr__svp_lens_fringer__svp_lens_vignetter__svp_lens_vignette_rr__svp_glass_dirtr__svp_glass_rimr__svp_dofr__svp_dof_onsetr__svp_eyeboxr__svp_eyebox_shiftr__svp_lens_menu_keyr__svp_stabilizePerformance
r__svp_cullr__svp_cull_ssar__svp_cull_grassr__svp_lodr__svp_adaptive_resr__svp_supersampler__svp_skip_motionblurr__svp_skip_ssrr__svp_skip_volumetricr__svp_skip_grassr__svp_sss_sunr__svp_diagRecoil
r__truepip_recoilObjective mode (
r__svpscope 2)r__svp_obj_distr__svp_obj_sizeReticle / DLSS scaffolding / debug / dynamic zoom
r__svp_reticle_magr__svp_dlssr__svp_render_scaler__scope_debugg_zoom_smoothg_zoom_analogHow it works
Double-pass / second viewport. When PiP is active the frame runs an extra scene pass for the
optic camera into a dedicated second-viewport target (
TargetSVP). A hybrid frame selector routeswork between the scope pass and the main pass:
true_pip_on): per-pass selection driven bym_render_pass_is_svpLens composite. The scope target is sampled by the lens shader and composited on-screen with the
reticle, supporting smooth and analog zoom.
Real optics & cosmetic gate. With
r__svp_truepipon, the eye-box is built from real geometry:eye relief and exit pupil come from the 3DSS scope config (
r__svp_optics_real), the clear zone growswith the exit pupil and tightens with magnification, and the eye offset is the real bore-vs-aim drift.
For optical scopes it also clears the 3DSS flat-scope SETTINGS bits (parallax shadow, chromatism, NVG
blur) and strips the fisheye so the magnified image is clean, while thermals and see-through optics are
left untouched.
Per-viewport correctness. Lighting, shadows (via the shared-shadow accumulation hook), motion
vectors, and the skybox previous-frame transform are tracked per viewport. Previous-frame matrices,
foliage transforms, and the sky-prev matrix live in
[2]arrays indexed by the active viewport, so thescope image is correctly lit and stays motion-vector / TAA stable when panning.
Performance. The scope geometry is frustum-culled to the cone, and a magnification-aware small-
object cull (
r__svp_cull_ssa) drops tiny distant clutter that the magnified cone can't resolve — theSVP g-buffer is draw-call bound, so this is the main lever. Adaptive resolution sizes the scope render
to the on-screen lens disc, and supersample optionally over-renders for SSAA.
Recoil gate.
r__truepip_recoilcontrols a small runtime gate (zzz_truepip_recoil_gate.script)that neutralizes a script recoil mod's per-shot camera/PP/FOV kick while scoped, so the optic stays on
the eyeline. It is a runtime monkey-patch only — it edits no files, and the base Anomaly engine/weapon
recoil is untouched.
DX11-only insulation.
true_pip_onis hard-forcedfalseon DX10/9/8 and the cvars above arenot registered there, so every shared render path collapses to stock for R1/R2/R3.
DLSS-SR scaffolding (gated, eval stubbed)
All engine-side plumbing for a Streamline DLSS-SR upscale of the scope render is present behind
r__svp_dlss, with the reconstruction itself left as a documented stub for the Streamlineintegration:
first appears, zoom-type change, target re-create)
SvpDlss.h) carrying color, depth, and motion-vector SRVs, the outputtarget, matrices, jitter, and camera params, with zero
sl::/ NGX dependenciesEvalSVP_DLSSis a bilinear/copy passthrough, and replacing its body is the only remaining stepSvpDlss.hdocuments the open interface items (depth form, output format, exposure, colour space,jitter convention, resource state) for whoever wires up the actual eval.
Invariants held:
r__svp_dlss == 0the output and GPU work are byte-identical to the non-DLSS path for anyr__svp_render_scalegame-to-render flag is a
std::atomicCompatibility & safety
true_pip_onfalse, cvars unregistered, shared gates collapse to stockr__svpscope 0is stock behaviourTesting
Tested on Anomaly 1.5.3 with GAMMA (3D Shader Scopes, SSS, Atmospherics):
reticle, smooth zoom, real per-scope eye-box, and the 3DSS cosmetic gate all working
Known limitations
r__svp_dlss 1runs a passthrough stubr__truepip_recoil) targets a script recoil mod's camera kick; with no such modpresent it is a no-op (base engine recoil is never touched)
Attribution
The true picture-in-picture scope code was written by m22spencer. This is a port of it from the
gc64 fork that adopted it (CnRJay/xray-monolith-gc64).
The DX11 second-viewport rendering, the lens composite (
draw_scope), the per-viewport history, andthe DLSS input contract all follow that implementation. The per-scope optics, cosmetic gate, lens
cosmetics, and SVP performance work were added on top.
xray-monolithengine this targetsFiles changed
74 files, grouped by area
Gamedata (new)
gamedata/scripts/zzz_extra_scope_features.script: magnification and zoom utilitygamedata/scripts/zzz_truepip_recoil_gate.script: optional script-recoil gategamedata/scripts/lens_fx_tune.script,gamedata/configs/ui/ui_lens_fx_tune.xml: in-game lens FX tuner pagegamedata/scripts/options_modded_exes_pip.script: PiP options pagegamedata/shaders/r3/scope_lensfx.{ps,s}: lens FX (CA, barrel, dim, eye-box, cosmetics)gamedata/shaders/r3/scope_{debug,depth_write,color_write,vertex,custom_depth,defines}.*: scope debug and depth/colour-write shadersConsole / cvars
xrRender_console.cpp/.h,xrEngine/xr_ioc_cmd.cppxrGame/console_registrator_script.cpp:is_svp_active()Lua binding for the recoil gateShared render layer (xrRender, all renderers)
R_calculate.cpp: DX10/9/8 PiP gater__dsgraph_build.cpp,r__dsgraph_render.cpp,r__dsgraph_manager.h,r__dsgraph_types.h: scope-pass routing, shared shadows, SVP cull + objective capturerendertarget_phase_nightvision.cpp: scope capture seam, lens composite, optics/eye-box, eval calldxEnvironmentRender.cpp: per-viewport skybox previous-frame transformR_sun.cpp,lights_render.cpp: per-viewport lighting and shadowsR_Backend.h,R_Backend_Runtime.h,R_Backend_xform.cpp/.h: per-viewport matricesFTreeVisual.cpp,SkeletonCustom.h,SkeletonX.cpp,Shader.h,Blender_Recorder_StandartBinding.cpp,HW.h,dxRenderDeviceRender.cppDebug/renderdoc_app.h(new),Debug/dxPixEventWrapper.hDX11 / R4 (PiP engine)
SvpDlss.h(new): DLSS input contractr4.cpp/.h,r4_R_render.cpp,r4_rendertarget.cpp/.h,r4_rendertarget_phase_combine.cppDX10 layer
dx10EventWrapper.cpp/.h,dx10HW.cpp,dx10ResourceManager_Scripting.cpp,dx10SH_RT.cppEngine (xrEngine)
device.cpp/.h: second viewport, matrices, atomic reset flagCameraManager.cpp,x_ray.cpp,bone.hxrEngine.vcxproj:/LTCG:INCREMENTALon the WPO configsCore (xrCore)
_matrix.h,Xr_ini.cpp,xr_ini.hGame (xrGame)
Actor.cpp/.h,ActorInput.cpp,Level.cpp,Weapon.cpp/.h,WeaponAK74.cppBuild
.gitignore