Skip to content

Picture in Picture Port | True PiP [Regular Branch]#579

Draft
TheLostInPlace wants to merge 16 commits into
themrdemonized:all-in-one-vs2022-wpofrom
TheLostInPlace:final-pip-regular
Draft

Picture in Picture Port | True PiP [Regular Branch]#579
TheLostInPlace wants to merge 16 commits into
themrdemonized:all-in-one-vs2022-wpofrom
TheLostInPlace:final-pip-regular

Conversation

@TheLostInPlace

@TheLostInPlace TheLostInPlace commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

True picture-in-picture scopes + per-scope optics + SVP DLSS-SR scaffolding (DX11)

Summary

Adds true picture-in-picture (PiP) scope rendering to the 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 culling (frustum + small-object), 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 0 the render is
byte-identical to stock, and the DX10/9/8 renderers (R1/R2/R3) are fully insulated. This is the
single-threaded (non-MT) renderer, so all of the added state is plain, with no atomics or
cross-thread synchronization.

  • Base branch: all-in-one-vs2022-wpo
  • Scope: 117 files, +4175 / -802, 16 commits

Requirements

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__svpscope has nothing
to draw. The real per-scope optics path (r__svp_optics_real) reads the eye-relief / exit-pupil
values from the 3DSS scope config; scopes without those entries fall back to geometry-derived values.

What's new (user-facing)

  • True PiP scope — a live second-viewport render of the scene sampled by the lens shader (real
    parallax, depth, and lighting inside the optic), with smooth and analog (variable) zoom, magnifier
    reticle, integrated/variant scope fixes, and an over-zoom guard
  • Real per-scope optics — eye relief and exit pupil taken from the 3DSS scope config drive a
    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
  • 3DSS cosmetic gate — for true-PiP optical scopes, suppresses the 3DSS flat-scope parallax-
    shadow crescent / blackout, chromatism, and NVG blur at the source (thermals and see-through optics
    keep their stock look)
  • Lens cosmetics — edge chromatic aberration, barrel distortion, exit-pupil dimming, radial
    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
  • SVP culling — frustum culling and magnification-aware small-object culling of the scope geometry
    (the SVP g-buffer is draw-call bound, so this is the main performance lever), plus optional cone
    occlusion culling and supersample
  • Per-viewport lighting, shadows, motion vectors, and skybox so the scope image is correctly lit
    and TAA-stable while panning (including a per-viewport sky-prev fix so the sky reprojects correctly
    under the scope camera)
  • Recoil gate — an optional runtime gate for script-mod per-shot camera kick so the scope stays
    on the eyeline; base engine/weapon recoil is untouched
  • Scope-pipeline debug visualization
  • Gated DLSS-SR plumbing for the scope render (reconstruction not yet implemented)

Console Variables (default collapsed)

Console variables

The r__ cvars are registered only under DX11, so they do not exist on DX10/9/8. The g_zoom_* cvars are engine-side and apply on every renderer.

Core

cvar type default purpose
r__svpscope int [0, 2] 0 enable true PiP scope rendering (0 off, 1 eyepiece, 2 objective — objective aliases to eyepiece on this branch, see limitations)

Real optics & eye-box (the physical model, master-gated by r__svp_truepip)

cvar type default purpose
r__svp_truepip float [0, 1] 0 physical eye-box master strength + 3DSS cosmetic gate (0 off = stock 3DSS shadow)
r__svp_optics_real float [0, 1] 1.0 real per-scope eye-relief + exit-pupil from the 3DSS config (1) vs scope geometry (0)
r__svp_optics_soft float [0.02, 0.6] 0.15 eye-box falloff width (lens-local)
r__svp_optics_gain float [0, 5] 1.0 eye-offset sensitivity (crescent onset speed)
r__svp_optics_zoomvig int [0, 1] 1 magnification-scaled eye-box vignette toggle
r__svp_optics_zoomvig_blend float [0, 1] 1.0 zoom-vignette blend (0 static exit-pupil .. 1 mag-scaled)
r__svp_eyebox_relief float [0, 1] 0 two-zone eye-relief zone strength (0 = single-zone)
r__svp_eyebox_relief_size float [0.1, 1] 0.5 eye-relief clear-zone radius (lens-local)
r__svp_eyebox_relief_soft float [0.02, 0.6] 0.25 eye-relief falloff softness
r__svp_eyebox_aspect float [0.3, 3] 1.0 clear-zone ellipse stretch (1 = circular)

Lens FX (gated by r__svp_lensfx; cosmetics also active under r__svp_truepip)

cvar type default purpose
r__svp_lensfx int [0, 1] 0 enable lens FX (edge CA, barrel, exit-pupil dim, tunnel)
r__svp_lensfx_strength float [0, 2] 1.0 lens FX overall strength
r__svp_lens_ca float [0, 0.02] 0.0018 chromatic aberration in the ring
r__svp_lens_distort float [0, 0.05] 0.0040 barrel distortion in the ring
r__svp_lens_floor float [0, 1] 0.10 tunnel ring brightness floor
r__svp_lens_refmag float [1, 16] 6.0 tunnel reference magnification (open at or below)
r__svp_lens_vigk float [0, 4] 1.5 tunnel close rate vs magnification
r__svp_lens_blur float [0, 0.03] 0.0040 radial edge blur amount
r__svp_lens_fringe float [0, 1] 0 radial chromatic fringing toward the edge
r__svp_lens_vignette float [0, 1] 0 radial vignette darkening (independent of the tunnel)
r__svp_lens_vignette_r float [0, 1] 0.6 vignette onset radius (0 center .. 1 rim)
r__svp_glass_dirt float [0, 1] 0 dirty-glass procedural grunge on the ocular
r__svp_glass_rim float [0, 1] 0 soft highlight rim at the lens-glass edge
r__svp_dof float [0, 0.10] 0.040 field-curvature edge ring blur (rim softens, center sharp)
r__svp_dof_onset float [0, 1] 0.55 ring blur onset radius
r__svp_eyebox float [0, 1] 0 legacy dynamic eye-box crescent (3DSS override)
r__svp_eyebox_shift float [-25, 25] 0 legacy crescent drift gain (negative flips the side)
r__svp_lens_menu_key int [0, 9] 0 lens FX tuner open key (PiP options dropdown index)
r__svp_stabilize float [0, 1] 1.0 sway reduction, blends the lens toward aim (0 full sway, 1 tracks aim)

Performance

cvar type default purpose
r__svp_cull int [0, 1] 1 frustum-cull the scope geometry to the scope cone
r__svp_cull_ssa float [0, 8] 4.0 magnification-aware small-object cull strength (0 off)
r__svp_cull_grass int [0, 1] 1 cull grass instances to the scope cone
r__svp_occlude int [0, 1] 0 rebuild the HOM occlusion map from the scope cone (helps indoors/urban)
r__svp_supersample float [1, 2] 1.0 SSAA the scope image (applies on vid_restart)
r__svp_adaptive_res float [0, 2] 1.2 size the scope render to the on-screen lens disc (inert on this branch, see limitations)
r__svp_lod float [0, 1] 0 scale scope LOD selection to its pixel coverage (inert on this branch)
r__svp_skip_motionblur int [0, 1] 0 skip motion blur on the scope pass
r__svp_skip_ssr int [0, 2] 1 scope reflections (0 reflective+SSR, 1 flat+SSR, 2 flat no-SSR)
r__svp_skip_volumetric int [0, 1] 0 skip volumetric lights on the scope pass
r__svp_skip_grass int [0, 1] 0 skip grass/details on the scope pass
r__svp_sss_sun int [0, 1] 0 keep the SSS sun contact-shadow term on the scope (expensive)
r__svp_diag int [0, 1] 0 scope perf diagnostics log

Recoil

cvar type default purpose
r__truepip_recoil int [0, 2] 2 gate the script recoil mod's per-shot camera kick (0 normal, 1 off in true-PiP, 2 off always); base engine recoil untouched

Reticle / DLSS scaffolding / debug / dynamic zoom

cvar type default purpose
r__svp_obj_dist float [0, 3] 1.0 objective derivation front-distance scale (objective mode aliased, see limitations)
r__svp_obj_size float [0.1, 6] 0.65 objective radius = eyepiece radius * this
r__svp_reticle_mag int [0, 1] 1 engine-drive the 3DSS reticle magnification so the FFP reticle scales
r__svp_dlss int [0, 1] 0 enable the DLSS-SR scope path (currently a passthrough stub)
r__svp_render_scale float [0.4, 1.0] 1.0 scope render-extent scale, inert until DLSS is enabled
r__scope_debug int [0, 4] 0 scope-pipeline debug visualization
g_zoom_smooth float [0, 60] 12 dynamic-scope zoom smoothing rate (lerp per second), 0 is instant stepped
g_zoom_analog float [0, 200] 0 dynamic-scope analog zoom, 0 is the discrete config steps, higher gives finer steps

How it works

Second viewport / double-pass. When PiP is active the optic camera is built into
Device.matrices[1] (svpCamera) and the scene is rendered a second time into a dedicated
second-viewport target (TargetSVP) with its own per-target g-buffer, depth, and color. The pass is
selected by the existing second-viewport frame flag (IsSVPFrame), so the main pass and the scope
pass each render with the correct camera and targets.

Lens composite. The scope target is sampled by the lens shader and composited on-screen through
phase_3DSSReticle with the reticle, supporting smooth and analog zoom. With r__svpscope 0 the
legacy see-through scope path is preserved as the fallback.

Real optics & cosmetic gate. With r__svp_truepip on, 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 grows
with 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-map accumulation), motion
vectors, and the skybox previous-frame transform are tracked per viewport. Previous-frame matrices,
foliage / skinned transforms, and the sky-prev matrix live in [2] arrays indexed by the active
viewport, so the scope image is correctly lit and stays motion-vector / TAA stable when panning.

Culling. The scope geometry is frustum-culled to the cone, and a magnification-aware small-object
cull (r__svp_cull_ssa) drops tiny distant clutter the magnified cone can't resolve; grass is culled
to the cone, with optional cone occlusion culling for indoor/urban scenes.

Recoil gate. r__truepip_recoil controls a small runtime gate (zzz_truepip_recoil_gate.script,
backed by an is_svp_active() Lua binding) that neutralizes a script recoil mod's per-shot
camera/PP/FOV kick while a true-PiP scope is active. It is a runtime monkey-patch only — it edits no
files, and the base Anomaly engine/weapon recoil is untouched.

DX11-only insulation. Every PiP/DLSS code path in the shared Layers/xrRender files is wrapped
in #if defined(USE_DX11), and the cvars above are not registered on DX10/9/8, 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:

  • scope rendered at a render-extent (g-buffer, lighting, and motion vectors scale together)
  • sub-pixel jitter baked into the scope projection (placeholder Halton sequence)
  • engine AA skipped under the gate so the eval receives a raw aliased and jittered image
  • a plain-bool history-reset flag fired on the events that should reset temporal history (ADS-in,
    lens first appears, zoom-type change, target re-create), read and cleared at the seam
  • a POD input contract (SvpDlss.h) carrying color, depth, and motion-vector SRVs, the output
    target, matrices, jitter, and camera params, with zero sl:: / NGX dependencies
  • EvalSVP_DLSS is a 1:1 copy passthrough, and replacing its body is the only remaining step

SvpDlss.h documents the open interface items (depth form, output format, exposure, colour space,
jitter convention, resource state) for whoever wires up the actual eval. The contract is identical
to the MT branch's, so the eval body is shared between them.

Invariants held:

  • at r__svp_dlss == 0 the output and GPU work are byte-identical to the non-DLSS path for any
    r__svp_render_scale (the scale is forced to 1.0 at the gate)
  • the branch is single-threaded: the second-viewport state and the history-reset flag are plain,
    with no atomics or cross-thread synchronization needed

Compatibility & safety

  • DX11 (R4): the feature
  • DX10/9/8 (R3/R2/R1): insulated, PiP/DLSS paths compiled out under #if defined(USE_DX11),
    cvars unregistered, shared gates collapse to stock
  • Off by default: r__svpscope 0 is stock behaviour
  • Zero regression when off: verified byte-identical render at the gate

Testing

Tested on GAMMA (Anomaly 1.5.3 base, with 3D Shader Scopes, SSS, Atmospherics):

  • gate-off: no visual or performance regressions
  • PiP on: scope renders the live scene with correct lighting and parallax; variable zoom, magnifier
    reticle, smooth zoom, real per-scope eye-box, and the 3DSS cosmetic gate all working
  • lens cosmetics (CA, fringing, vignette, dirty-glass, ring blur) and the in-game tuner verified
  • small-object cull verified clean (no popping) in open terrain and dense areas
  • skybox reprojects correctly under the scope camera (no sky smear/ghosting on pan)
  • both scope modes (r__svpscope 1 and 2) confirmed clean in-game
  • DLSS gate on: scope upscales through the stub (passthrough) with no artifacts beyond expected aliasing
  • full engine build green across R1 to R4 (DX11-AVX)

Known limitations

  • The DLSS-SR reconstruction is not implemented, so r__svp_dlss 1 runs a passthrough stub
  • Objective mode (r__svpscope 2) is aliased to the eyepiece (1) on this branch: the
    second-viewport composite paints onto the eyepiece lens without reprojecting the objective view, so
    true objective mode isn't supported here (the objective derivation is kept for a future
    reprojection-aware path)
  • Adaptive scope resolution (r__svp_adaptive_res) and LOD scaling (r__svp_lod) are present
    but currently inert on this single-threaded branch (the per-frame scope-target resize hook is
    MT-only); the small-object cull (r__svp_cull_ssa) is the active performance lever, and supersample
    applies on vid_restart
  • The recoil gate (r__truepip_recoil) targets a script recoil mod's camera kick; with no such mod
    present 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, and
the DLSS input contract all follow that implementation. The per-scope optics, cosmetic gate, lens
cosmetics, and SVP culling were added on top.

  • m22spencer: original author of the true PiP scope implementation
  • gc64 (CnRJay/xray-monolith-gc64): the fork that adopted it, the source this port is taken from
  • Redotix99, 3D Shader Based Scopes (3DSS): the scope lens and reticle content this builds on
  • themrdemonized: the base xray-monolith engine this targets

Files changed

117 files, grouped by area

Gamedata (new)

  • gamedata/scripts/zzz_extra_scope_features.script: magnification and zoom utility
  • gamedata/scripts/zzz_truepip_recoil_gate.script: optional script-recoil gate
  • gamedata/scripts/lens_fx_tune.script, gamedata/configs/ui/ui_lens_fx_tune.xml: in-game lens FX tuner page
  • gamedata/scripts/options_modded_exes_pip.script: PiP options page
  • gamedata/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 shaders

Console / cvars

  • xrRender_console.cpp / .h, xrEngine/xr_ioc_cmd.cpp
  • xrGame/console_registrator_script.cpp: is_svp_active() Lua binding for the recoil gate

Shared render layer (xrRender, all renderers)

  • r__dsgraph_build.cpp, r__dsgraph_render.cpp, r__dsgraph_structure.h: scope-pass routing, SVP cull + objective capture
  • rendertarget_phase_nightvision.cpp: scope camera, lens composite, optics/eye-box, capture seam, DLSS eval call
  • dxEnvironmentRender.cpp: per-viewport skybox previous-frame transform
  • Blender_Recorder_StandartBinding.cpp: 3DSS cosmetic gate (parallax shadow / chromatism / NVG bits)
  • R_Backend.h, R_Backend_Runtime.cpp / .h, R_Backend_xform.cpp / .h: per-viewport matrices
  • SkeletonCustom.h, SkeletonX.cpp, FTreeVisual.cpp: per-viewport skinned/foliage transforms
  • Light_DB.cpp / .h, r__occlusion.cpp, rendertarget_phase_blur.cpp: per-viewport lighting/occlusion/blur
  • Shader.h, HW.h, dxFontRender.cpp, dxRenderDeviceRender.cpp, Debug/dxPixEventWrapper.h

DX11 / R4 (PiP engine)

  • SvpDlss.h (new): DLSS input contract
  • r4.cpp / .h, r4_R_render.cpp, r4_rendertarget.cpp / .h, r4_rendertarget_phase_combine.cpp
  • r2_R_calculate.cpp, r2_R_lights.cpp, r2_R_sun.cpp, r4_R_rain.cpp, r4_loader.cpp,
    r4_rendertarget_phase_smap_D.cpp, r4_rendertarget_phase_smap_S.cpp, r4_rendertarget_phase_ssao.cpp

DX10 layer

  • dx10EventWrapper.cpp / .h, dx10HW.cpp, dx10ResourceManager_Scripting.cpp, dx10SH_RT.cpp

Engine (xrEngine)

  • device.cpp / .h: second viewport, per-viewport matrices, history-reset flag
  • CameraManager.cpp, x_ray.cpp, bone.h, Stats.cpp / .h, GameFont.h

Core (xrCore)

  • _matrix.h, Xr_ini.cpp, xr_ini.h, _stl_extensions.h

Game (xrGame)

  • Actor.cpp / .h, ActorInput.cpp, Level.cpp, Weapon.cpp / .h, WeaponAK74.cpp, game_cl_single.h

Include / build

  • Include/xrRender/FactoryPtr.h, .gitignore, /LTCG:INCREMENTAL on the WPO link configs, project files (.vcxproj)

…le fixes

PiP/SVP scope rendering (DX11), DLSS-SR scaffolding behind r__svp_dlss,
smooth/analog scope zoom, hybrid reticle fixes, per-viewport motion vectors,
AVX2 build flags, 3DSS magnification script.
@TheLostInPlace TheLostInPlace marked this pull request as draft June 19, 2026 06:40
@TheLostInPlace

Copy link
Copy Markdown
Contributor Author

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 ;-;

@TheLostInPlace TheLostInPlace marked this pull request as ready for review June 19, 2026 06:45
@TheLostInPlace

Copy link
Copy Markdown
Contributor Author

Alright that was a quick investigation, turns out that weapon had an improperly positioned eyepiece mesh resulting in the PiP drawing incorrectly

@TheLostInPlace

Copy link
Copy Markdown
Contributor Author

#578 (comment)

- 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
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 pulls the SVP camera orientation toward the main view in
proportion to the live recoil so a PiP scope tracks your aim instead of the
weapon bone during fire. 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, and the
CWeapon zoom methods exposed to Lua so the tuner can drive the scope.
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.

recoil-comp (added in the previous commit) is orientation-only, so the magnified
view never zooms with recoil. The MT intermediate that also blended the eyepiece
position (which fought svpCamera's FOV sizing and caused the drift) was not
introduced in this port, so position steadiness is recoil_hold's job.
The scene is captured against the main frustum and rendered twice, so the SVP
resubmitted the whole main frustum world through a magnified cone that sees only
a fraction of it, paying full vertex and draw cost for geometry the GPU then
clips. Reject each item 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 would clip. Static world geometry carries no per
item matrix so its world space vis.sphere is tested directly, dynamics scale the
object space sphere by their world matrix. Gated to the SVP gbuffer pass so the
main view and non PiP renderers stay byte identical. Measured on MT the SVP
gbuffer drops from about 17ms to 2 to 8ms scaling with zoom. Default on,
r__svp_cull 0 restores the old path.

Keeps a temporary [SVPCULL] tested and culled diagnostic, stripped once the in
game numbers check out.
…ter + SSS fixes

Recoil
- Add r__svp_pupil_boost (default 6), 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, 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 r__svp_skip_ssr, 0 reflective water, 1 flat water plus SSR (default), 2 matte.
  force_water_reflect un-flattens the SVP water at level 0.
- The scope water SSR temporal reprojection already reprojects against the per
  viewport history here (mm_saved_viewproj and saved_position indexed by viewport)
  so the matte vs reflective flicker the MT fix targets does not occur, no port.

SSS
- Add r__svp_sss_sun (default off). The non-MT already runs the SVP SSS pass per
  viewport, this sets force_svp_sss around the SVP sun cascade accum so the scope
  sun keeps the SSS contact term.

Ported from MT 3463300, adapted to the non-MT render structure: the recoil removal
lands in the inline lens derive (no deriveScopeLens), the SSS sun hook in
render_sun_cascades (no dual_accum), and the combine gates key on IsSVPFrame.
…l-pip-regular

# Conflicts:
#	src/Layers/xrRenderPC_R4/r4.cpp
@TheLostInPlace

Copy link
Copy Markdown
Contributor Author

Mmm... something broke here while I was porting MT code fixes and optimizations, I decide to try and run non-mt and it's busted

Trying to figure out, might not get to it till tomorrow

…cull

- Eyepiece derives from the captured N.val.Matrix, not get_xform_world (post
  V->Render), which sat ~15cm off and blacked the exit pupil
- r__svp_occlude (default 0): rebuild HOM from the scope cone for indoor occlusion
- SVP frustum-cull reject hooks across the static/dynamic/landscape draw loops
- r__svp_pupil_track ramps pupil_boost with the live bore off-axis drift, so the
  exit pupil stays tight when steady and opens only under recoil (default 0)
- 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)

Ported from MT 08479f9, adapted to non-MT (no true_pip_on, gate on IsSVPActive)
@themrdemonized themrdemonized marked this pull request as draft June 22, 2026 11:00
svp_cull_reject tested dynamic objects by transforming their vis.sphere, but a
skinned sub-visual sphere is baked at the rest pose and does not track the
animated bones, so a close NPC (a bent head, a hood) read outside the scope cone
and got dropped. Skip the cull for dynamic entirely, only ~57 objects so the
savings are negligible, and the static world (no skinning) is unaffected.

Ported the NPC-cull half of MT e01733a. The other half (shared wmark/sorted list
consumption) does not apply to non-MT: it re-traverses the dsgraph per viewport
instead of sharing one capture, so each pass rebuilds and clears its own lists.
per-scope optics + two-zone eye-box + scope_lensfx cosmetics, SVP small-object cull, 3DSS cosmetic gate, per-viewport skybox motion vectors, recoil gate via is_svp_active engine binding, svpscope-2 aliased to the eyepiece (no objective camera on regular), LTCG:INCREMENTAL on the WPO configs, dead-cvar cleanup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant