Display Guide
August 5, 2026 · View on GitHub
FnQL splits display settings across three layers: how the window or fullscreen mode is created, how the scene is rendered internally, and which post-processing controls are applied to the final image. This guide covers renderer choice, video mode selection, framebuffer-based rendering, anti-aliasing, bloom, soft particles, and the related scene presentation controls.
For menu and cinematic layout on widescreen displays, use the separate Aspect Handling Guide. Retail cgame owns HUD projection and world FOV. For screenshot output and capture-specific options, use the Screenshot Guide.
Renderer Choice
cl_renderer selects the rendering backend and requires vid_restart.
cl_renderer glx: Canonical OpenGL-lineage renderer and client default, with compatibility tiers, streaming, static-world, material, postprocess, output, and profiling paths.cl_renderer vk: Vulkan raster renderer with FBO rendering, HDR, multisampling, supersampling, render scaling, shader-based SDR gamma/overbright, greyscale, and bloom.cl_renderer rtx: Vulkan ray-tracing renderer; full RT mode requires a ray-tracing-capable Vulkan GPU. See the RTX Renderer Guide.
Only glx, vk, and rtx are valid renderer selectors. See GLX.md for GLx diagnostics and troubleshooting.
Display Modes And Window Behavior
These settings control the actual game window or fullscreen mode. Treat them as vid_restart settings.
r_mode: Main video mode selector.-2: Use the current desktop resolution.-1: User_customWidthandr_customHeight.0..N: Use a predefined mode from\modelist.
r_modeFullscreen: Optional dedicated fullscreen override. Leave it empty to reuser_mode, or set it to one of the same values you would normally use forr_mode.r_fullscreen:1for fullscreen,0for windowed mode.r_customWidthandr_customHeight: Custom resolution used byr_mode -1.r_customPixelAspect: Advanced custom pixel aspect value forr_mode -1orr_mode -2. Leave this at1unless you intentionally need non-square pixel behavior.r_displayRefresh: Fullscreen refresh-rate override.0uses the current monitor refresh rate.r_noborder: Removes the title bar and borders in windowed mode.vid_xposandvid_ypos: Saved window position in windowed mode.r_swapInterval: V-Sync control.0: Do not wait for v-blank.1: Sync swaps to the monitor refresh rate.
Windowed placement is checked against the display's usable work area using the complete native frame, including resize borders and the title bar. This keeps the chrome reachable after a DPI change, dock/taskbar change, monitor removal, or renderer restart. On Wayland, the compositor owns top-level placement and server-side decorations by protocol, so FnQL leaves that policy to it instead of issuing unsupported position requests.
Fullscreen picks one of two forms automatically. A request that matches the current desktop resolution with r_displayRefresh 0 uses borderless desktop fullscreen: no display mode change, so alt-tab, other monitors, and the desktop layout are left alone. Any other resolution, or an explicit r_displayRefresh, switches the display to the closest matching mode at or above the requested size. The console line ...fullscreen <width>x<height>@<rate>Hz (exclusive|desktop) reports what was actually applied; if no mode is large enough for the request, the engine says so and falls back to desktop fullscreen.
Practical setups:
- Exclusive fullscreen at desktop resolution:
seta r_fullscreen "1"
seta r_mode "-2"
vid_restart
- Borderless desktop-sized window:
seta r_fullscreen "0"
seta r_mode "-2"
seta r_noborder "1"
vid_restart
- Custom fixed window size:
seta r_fullscreen "0"
seta r_mode "-1"
seta r_customWidth "1600"
seta r_customHeight "900"
vid_restart
Fast Windowed/Fullscreen Toggle
vid_restart fast (alias: vid_restart keep_window) restarts the renderer while keeping the game window alive. When only the windowed/fullscreen state, borders, size, or position changed, the existing window is morphed in place instead of being destroyed and re-created, which avoids the desktop flicker and focus churn of a full restart:
seta r_fullscreen "0"
vid_restart fast
Alt+Enter toggles r_fullscreen and issues vid_restart fast automatically.
The fast path is safe to use unconditionally: if the window cannot be reused — for example after changing r_colorbits, r_stencilbits, r_depthbits, r_stereoEnabled, HDR output requests, or switching between OpenGL and Vulkan renderers — the engine automatically falls back to a full window re-creation. The console prints ...reusing existing window when the in-place toggle was taken.
Framebuffer Path, Internal Resolution, And Anti-Aliasing
These settings control the render path behind the display output.
r_fbo: Enables framebuffer-object rendering. This is the foundation for the modern display path and is required for bloom, motion blur, enhanced liquid refraction, optional global fog, HDR, multisample anti-aliasing, supersampling, greyscale, and arbitrary internal render resolutions.r_hdr: Selects the HDR-capable FBO render pipeline.0: Display-referred SDR compatibility path.1: High-precision FBO path. With the default legacy tone mapper this preserves Quake III's display-referred lighting; non-legacy tone mapping, color grading, and explicit HDR output use scene-linear color.-1: Legacy debug alias forr_hdrPrecision -1without enabling scene-linear HDR.
r_hdrPrecision: Controls the internal FBO color storage used by the display pipeline.0: Automatic. SDR uses 8-bit normalized storage;r_hdr 1usesRGBA16Ffloating-point scene storage.-1: Debug 4-bit storage for deliberate banding tests.8: Force 8-bit storage.16: Force 16-bit normalized storage for SDR/debug testing;r_hdr 1still usesRGBA16F.
r_hdrBloomFormat: Controls scene-linear HDR bloom/extract intermediate storage without changing the main scene target.0: Automatic. RGB bloom triesR11G11B10Fand falls back toRGBA16Fif the driver rejects the FBO.1: ForceRGBA16Fbloom intermediates for conservative parity.2: PreferR11G11B10Ffor positive RGB bloom intermediates.3: PreferRG16Ffor positive two-channel intermediates; current RGB bloom safely falls back.
r_srgbTextures: Allows authored color textures to use hardware sRGB decode when ther_hdr 1path is actually running scene-linear color. Lightmaps, fog, dynamic-light masks, and data textures remain linear/data.r_framebufferSRGB: AllowsGL_FRAMEBUFFER_SRGBonly when the draw target itself is sRGB-encoded. The current OpenGL/GLx SDR final shader keeps it disabled because the shader already writes SDR sRGB output.r_outputBackend: Selects the final hardware output backend.0: Automatic. Conservative by default; Vulkan keeps usingr_hdrDisplayto request HDR10, while GLx selects a non-SDR transform only whenr_hdr 1and platform HDR/EDR state are visible.1: Force SDR sRGB.2: Request Windows scRGB output on an HDR/Advanced Color display path.3: Request HDR10/PQ output. Vulkan maps this to an HDR10 swapchain when the surface exposesVK_COLOR_SPACE_HDR10_ST2084_EXT.4: Request macOS extended-linear-sRGB/EDR output when SDL reports EDR headroom.5: Request Linux experimental HDR telemetry/prototype output, gated byr_outputAllowExperimentalLinuxHDRplus explicit SDL compositor/protocol HDR checks.
r_outputAllowExperimentalLinuxHDR: Allows the Linux experimental HDR telemetry/prototype backend only when the platform reports HDR headroom and an explicit compositor/protocol path. Leave this disabled unless you are validating a known HDR-capable Wayland path.- On SDR output, GLx treats paper white as the max output reference for the final transform. HDR-only max-luminance headroom is used only when a hardware HDR/EDR backend is actually active.
- Output primaries are explicit in the GLx final transform. SDR sRGB and Windows scRGB use sRGB/BT.709 primaries, HDR10/PQ uses BT.2020, and macOS EDR uses Display P3. The Linux experimental HDR path is the only native-primaries state: it performs no primaries matrix and expects the compositor/protocol path to own native colorimetry. Unknown primaries are not selectable output states.
r_ext_multisample: Geometry-edge multisample anti-aliasing. GLx and Vulkan share this cvar. Common values are0,2,4,8, and16; the renderer resolves unsupported requests to the best supported sample count not above the request.r_ext_alpha_to_coverage: Optional multisample smoothing for alpha-tested texture edges such as grates, foliage-style cutouts, and masked decals. Requiresr_ext_multisample. Default is0for legacy alpha-test parity.r_ext_supersample: Enables supersample anti-aliasing.r_renderWidthandr_renderHeight: Internal render resolution whenr_renderScale > 0.r_renderScale: Controls how the internal render image is scaled to the actual window or fullscreen size.0: Disabled.1: Nearest-neighbor stretch.2: Nearest-neighbor with preserved aspect ratio.3: Linear stretch.4: Linear with preserved aspect ratio.
Guidance:
- Use
r_fbo 1if you want any modern post-processing or internal render scaling. - Use
r_ext_multisamplefor cleaner geometry edges. - Use
r_ext_alpha_to_coverage 1with MSAA if alpha-tested texture edges need extra smoothing. - Use
r_ext_supersample 1when you want higher image quality and can afford the extra GPU cost. - Use
r_renderWidth,r_renderHeight, andr_renderScalewhen you want a lower or higher internal render resolution than the actual window size.
Example: render internally at 1280x720 and scale to your current display with linear filtering and preserved aspect ratio:
seta r_fbo "1"
seta r_renderWidth "1280"
seta r_renderHeight "720"
seta r_renderScale "4"
vid_restart
Scene Presentation Controls
These settings affect the rendered scene itself rather than the window mode.
r_gamma: Gamma correction factor. This is one of the first settings to check if the whole frame looks too dark or too washed out.r_ignorehwgamma: Force the software/shader gamma path and never write the display's hardware ramp. Latched; requiresvid_restart.r_tonemap: Final-pass tone scale forr_hdr 1.0: Legacy gamma/overbright behavior.1: Simple Reinhard, the per-channelx / (1 + x)curve. Existing configs that referred to this asReinhardkeep the same behavior for this release cycle.2: ACES-fitted filmic curve. This is the common fitted approximation, not the official ACES output transform; existing configs that referred to it asACESkeep the same behavior for this release cycle.
r_tonemapExposure: Exposure multiplier for scene-linear tone mapping and bloom extraction.r_autoExposure: Automatic exposure for the shared OpenGL postprocess tone-map path.0: Disabled.1: Time-constant adaptation. This is the default; it updates from elapsed render time, clamps exposure inputs, and uses the deterministic luminance reduction path.2: Legacy parity mode using the old frame-cadenced adaptation and GL_LINEAR reduction behavior.3: Modern-tier histogram percentile reduction. This is opt-in; it carries low/median/high percentile luminance through the reduction chain on floating-point targets and falls back to mode1on older fixed-point tiers.
r_glxAutoExposure: GLx scene-linear auto-exposure reduction.0: Manual exposure fromr_tonemapExposure. This is the default.1: Tiered automatic mode: histogram percentile on modern post/output tiers, simple-average fallback on older tiers. The selected algorithm is reported byglxpostprocessand compact GLx diagnostics.2: Force the simple-average fallback.3: Force histogram percentile on modern tiers, with conservative fallback when the tier cannot support it.
r_glxAutoExposurePercentile: Percentile used by the GLx histogram path. Default80.r_glxAutoExposureTargetLuma: Scene-linear luminance target for GLx auto exposure. Default0.18.r_glxAutoExposureMin/r_glxAutoExposureMax: Clamp the resolved GLx exposure. Defaults0.125and8.0.r_glxAutoExposureAdapt: Per-frame blend factor for GLx exposure changes. Default0.15;1applies the current reduction immediately.r_colorGrade: Scene-linear grading stage forr_hdr 1.0: Disabled. This is the conservative default and preserves the compatibility image.1: Lift/gamma/gain plus white-point adaptation.2: 3D LUT atlas.3: Lift/gamma/gain, white-point adaptation, then the 3D LUT atlas.
r_colorGradeLift: Per-channel lift as"r g b"before tone mapping. Default is"0 0 0".r_colorGradeGamma: Per-channel grading gamma as"r g b". Default is"1 1 1".r_colorGradeGain: Per-channel scene-linear gain as"r g b". Default is"1 1 1".r_colorGradeWhitePoint: Source scene white point in Kelvin for Bradford adaptation. Default is6504.r_colorGradeAdaptWhitePoint: Target white point in Kelvin. Default is6504.r_colorGradeLUT: Optional 3D LUT atlas image forr_colorGrade 2or3. The atlas layout is widthN*N, heightN, with blue slices arranged horizontally.r_colorGradeLUTScale: Scene-linear RGB range represented by the LUT. Default4.0maps0..4into the LUT domain.r_greyscale: Full-frame desaturation. Requiresr_fbo 1.
Use ASPECT_CORRECTION.md for menu and cinematic layout. Native QL cgame geometry and world FOV are passed through without an engine-side post-correction.
Hardware Gamma Ramps
A display's gamma ramp is owned by the desktop, not by the game: it is global to the monitor and survives the process. FnQL therefore takes it over only when it has something to add that the renderer cannot do itself.
- With
r_fbo 1(the default for every renderer) gamma is applied by the output shader, so the ramp is left alone and the monitor keeps its ICC calibration. Nothing changes on the desktop when you alt-tab. - The ramp is written only in fullscreen, only when
r_fbois off andr_gammaorr_overBrightBitsactually asks for a correction. It is handed back on focus loss, monitor changes,vid_restart, quit, and crash. - Windows drops ramps while a mode set or ICC reload is in flight even after reporting success, so each write is confirmed by reading the ramp back, and the ramp is re-asserted after display changes and on returning to the game.
r_ignorehwgamma 1disables the hardware path outright. Remote Desktop sessions and displays that report broken ramps are detected and skipped.
If the game or the desktop looks too dark after alt-tabbing, check r_gamma
first and confirm r_fbo 1; a monitor left on a stale ramp can also be reset by
reapplying its color profile from Windows display settings.
Soft Particles
Soft particles use the scene depth buffer to fade supported translucent effects as they intersect world geometry. This softens the hard clipping that can otherwise appear where smoke, explosions, blood trails, and similar sprites meet floors, walls, or other map surfaces. The effect is visual-only: it does not change demos, protocol behavior, assets, or game logic.
r_depthFade: Enables soft-particle depth fade for supported translucent shaders. Default is1. This is latched, so usevid_restartafter changing it.
Supported shaders include the built-in explosion, smoke, plasma, bullet, rail, BFG, and blood effect shaders that FnQL marks for depth fade automatically, plus content shaders that declare q3map_depthFade <distance> <bias>. Opaque shaders, depth-writing shaders, and blend modes that cannot be faded safely keep their normal behavior.
Renderer notes:
- OpenGL-lineage renderers use the depth-texture path for this effect.
- Vulkan uses the same kind of depth snapshot. If MSAA is requested, depth fade takes precedence and the main scene uses the single-sample depth-copy path.
Typical setup:
seta r_depthFade "1"
vid_restart
Dynamic Lighting And Shadowing
FnQL keeps classic Quake III dynamic lights available, then adds optional higher-quality dynamic-light rendering and shadow maps on the GLx/OpenGL-lineage and Vulkan paths. These effects are visual-only renderer features: they do not change demos, protocol behavior, map data, or game logic.
Dynamic lighting controls:
r_dynamiclight: Enables dynamic lights such as weapon flashes and projectile lights. Default is1.r_dlightMode: Selects the dynamic-light renderer.0: Vanilla Quake III style dynamic lights.1: High-quality per-pixel dynamic lights on world surfaces.2: Same as1, and also applies dynamic lights to entity models.- The desktop default is
2; constrained ARM builds retain the compatibility default0.
r_dlightScale: Scales dynamic-light radius. Default is0.5.r_dlightIntensity: Scales dynamic-light intensity without changing radius. Default is1.0.r_dlightFalloff: Blends the high-quality dynamic-light attenuation toward a smoother edge falloff. Default is1.r_dlightSaturation: Adjusts dynamic-light color saturation in linear light. Default is0.8.
Classic model shadow controls:
cg_shadows: Selects the classic player/model shadow mode.0: Disabled.1: Classic blob/blur-style model shadows.2: Stencil shadow volumes. This needs an available stencil buffer;cl_stencilbits 8is the usual compatible setting.3: Black planar projection shadows.
Dynamic-light shadow-map controls:
r_dlightShadows: Enables dynamic-light shadow-map planning, atlas rendering, and filtered sampling. Default is1. This is latched, so usevid_restartafter changing it.r_dlightShadowFilter: Selects shadow filtering. Default is2.0: Hard shadows.1: 2x2 PCF.2: Four-tap poisson PCF.
r_dlightShadowResolution: Requested per-face shadow-map resolution. Valid range is64..1024, default is256. The renderer rounds this down to a power of two and may reduce it to fit the atlas.r_dlightShadowMaxLights: Maximum dynamic lights allowed to cast shadows in one view. Default is4. Lower values give each light more atlas space; higher values favor coverage over sharpness.r_dlightShadowStrength: Controls how strongly shadow-map occlusion dims the dynamic light. Default is0.95.r_dlightShadowBias: Receiver bias in world units. Default is4.r_dlightShadowCasterDepthBias: Constant depth bias while rendering shadow casters. Default is1.r_dlightShadowCasterSlopeBias: Slope-scaled caster depth bias. Default is1.r_dlightShadowCasterNormalBias: Light-aware caster normal offset in world units. Default is0.25.r_dlightShadowDebug: Prints dynamic-light shadow planning and atlas counters. Use this orr_speeds 4when you want to confirm the effective atlas size and per-face resolution.r_muzzleFlashDlightOffset: Moves recognized weapon muzzle-flash lights along the submitted flash model's forward axis, in world units. Default is8; use0for the retail origin.r_muzzleFlashDlightShadows: Allows recognized weapon muzzle-flash lights to cast shadows. Default is1; set it to0to keep the light while disabling only its shadows.
Quality-first dynamic-light shadow-map setup:
seta r_dynamiclight "1"
seta r_dlightMode "2"
seta r_dlightShadows "1"
seta r_dlightShadowFilter "2"
seta r_dlightShadowResolution "1024"
seta r_dlightShadowMaxLights "2"
vid_restart
If the debug output reports a smaller face size than requested, reduce r_dlightShadowMaxLights before increasing any bias values. Bias tuning is mainly for fixing acne, shimmering, or detached-looking shadows; the defaults are the best first pass for normal play.
Directional cascaded shadow maps are available with r_csmShadows 1 on GLx and Vulkan. They use parsed q3map_sun/q3map_sunExt/q3map_sunExt2 sky shader parameters for the sun direction, color, and strength, and shadow opaque BSP world geometry, entity models, and brush models.
Texture Picmip
Picmip lowers texture upload resolution to trade sharpness for memory use and speed. It is a latched texture-loading setting, so changes require vid_restart or a fresh renderer start before already-loaded images are rebuilt.
Controls:
r_picmip: Texture reduction amount.0keeps full upload resolution. Higher values progressively shift eligible images down by powers of two.r_picmipFilter: Filters which shader paths are allowed to user_picmip. Default is1.0: Legacy behavior. Any picmip-capable shader or raw image can be reduced unless it was explicitly markednopicmip.1: Allowtextures/*. This is the default and keeps normal world-material textures under picmip while treating most UI, model, effect, and utility shaders likenopicmip.2: Allowmodels/*.4: Allowsprites/*.8: Allow 2D/UI-style paths:gfx/*,icons/*,menu/*,ui/*, andfonts/*.- Add values to combine groups. For example,
3allowstextures/*andmodels/*;15allows every built-in group.
r_nomip: Applies picmip only while map/world images are loading. This is stricter thanr_picmipFilterbecause it limits when picmip is applied, not only which shader names are eligible.r_neatsky: Disables mipmapping and picmip for skybox images.
Notes:
r_picmipFilteris intentionally shader-name based. It classifies the shader being registered, not every individual image referenced by a shader stage. A shader namedtextures/foo/barcan still picmip its eligible stages, even if one stage loads an image outsidetextures/.- Authored shader keywords still win.
nopicmipandnomipmapskeep their historical meaning. - Use
r_picmipFilter 0for old configs or visual comparisons that expect every picmip-capable image to be reduced. - Use
r_picmipFilter 1when you want world textures to scale down without blurring HUD, menu, font, and most model/effect assets. - Use
r_picmipFilter 3when you also want player, weapon, and item model skins to followr_picmip.
Example quality/performance setup:
seta r_picmip "1"
seta r_picmipFilter "1"
vid_restart
Example aggressive legacy-style setup:
seta r_picmip "2"
seta r_picmipFilter "0"
vid_restart
Cel Shading
Cel shading is split between model presentation and BSP world edge detection.
Model cel shading applies to model entities, including player models, weapons, and inline brush models. It can quantize model lighting into hard bands and draw a stencil-style silhouette shell around eligible models. World cel shading is separate: it draws screen-space outlines from the world depth buffer so BSP geometry gets dark edge accents without changing lightmaps, vertex data, demos, protocol behavior, or assets.
The GLx/OpenGL-lineage and Vulkan renderers expose the same user-facing controls.
Controls
r_celShading: Model cel-shading master toggle. Default is0.0: Disabled.1: Enable cel shading on model entities, including inline brush models.
r_celShadingModelShadows: Quantizes model lighting into cel shadow bands whenr_celShadingis enabled. Default is1.r_celViewWeapon: Lets the first-person weapon participate in model cel shading and model cel outlines. Default is1.r_celShadingSteps: Number of diffuse lighting bands for model cel shading. Valid range is2..8, default is4. Lower values push a harsher hard-step look. Higher values keep more intermediate tone.r_celOutline: Enables the silhouette shell around cel-shaded model entities. Default is1.r_celOutlineScale: Model outline shell expansion amount. Valid range is1.0..1.25, default is1.03. Values just above1.0keep the outline tight. Larger values make it thicker.r_celOutlineAlpha: Model outline opacity multiplier. Valid range is0.0..1.0, default is1.0.r_celViewWeaponOutlineScale: First-person weapon outline shell expansion amount. Valid range is1.0..1.10, default is1.006. This is separate because viewmodels sit much closer to the camera than other models.r_celViewWeaponOutlineAlpha: First-person weapon outline opacity multiplier. Valid range is0.0..1.0, default is1.0.r_celOutlineColor: Model outline color as"r g b a". Default is"0 0 0 255". The alpha channel is also multiplied byr_celOutlineAlphaorr_celViewWeaponOutlineAlpha.r_celShadingWorld: Enables BSP world cel outlines. Default is0.0: Disabled.1: Draw screen-space depth-edge outlines over opaque BSP world geometry.
r_celShadingWorldWidth: World outline radius in pixels. Valid range is1.0..8.0, default is2.0. Increase this for thicker world edges.r_celShadingWorldAlpha: World outline opacity. Valid range is0.0..1.0, default is1.0.r_celShadingWorldDepthThreshold: Depth discontinuity threshold for world edge detection. Valid range is0.0001..0.02, default is0.0015. Lower values catch subtler depth edges; higher values restrict the effect to stronger geometry breaks.
Notes:
r_celOutlinedepends on a stencil buffer being available.r_celShadingWorlduses depth edges only. It does not quantize or cel-shade BSP lightmaps.r_celShadingWorldaffects the main BSP world only. Inline brush models remain underr_celShading.r_celShadingWorldneeds the renderer depth-texture path. If that path is unavailable, the cvar is harmless and the world outline pass is skipped.- Model cel outlines, world cel outlines, and player highlight passes are drawn late enough to remain visible over bloom.
- The model outline color is shared across eligible model entities.
Recommended starting point:
seta r_celShading "1"
seta r_celShadingModelShadows "1"
seta r_celViewWeapon "1"
seta r_celShadingSteps "4"
seta r_celOutline "1"
seta r_celOutlineScale "1.03"
seta r_celOutlineAlpha "1.0"
seta r_celViewWeaponOutlineScale "1.006"
seta r_celViewWeaponOutlineAlpha "1.0"
seta r_celOutlineColor "0 0 0 255"
seta r_celShadingWorld "1"
seta r_celShadingWorldWidth "2.0"
seta r_celShadingWorldAlpha "1.0"
seta r_celShadingWorldDepthThreshold "0.0015"
For a harsher stylized model-lighting look, reduce r_celShadingSteps to 2 or 3. For a softer result, keep the outline enabled but raise r_celShadingSteps to 5 or 6. For stronger world edges, raise r_celShadingWorldWidth; for fewer world edges, raise r_celShadingWorldDepthThreshold.
Map Flares And Lens Effects
Quake Live maps can author flare surfaces as part of the BSP. FnQL keeps the original visibility, fog, distance falloff, and fade behavior, while offering an enhanced optical presentation on GLx/OpenGL and Vulkan.
r_flares 0: Disable map flares. This remains the default.r_flares 1: Draw the classic Quake III corona only. Existing configurations retain their original presentation.r_flares 2: Draw the classic corona and supplement it with a broad source halo, a restrained horizontal lens streak, and chromatic aperture ghosts along the light-to-screen-centre axis.
The enhanced effect reuses the retail flare image through a dedicated additive surface, so black texels stay neutral and no replacement assets or map-format change are required. It also reuses the classic flare's occlusion and fade result; hidden lights cannot leave detached lens ghosts behind. Bloom is optional, but enabling it can make the brightest corona layers spread more naturally.
Enhanced Liquids
The OpenGL-lineage renderers, including GLx, and Vulkan can add warped same-frame scene-color refraction, a Fresnel-weighted screen-space reflection, and visual interaction ripples to existing liquid surfaces. Warped scene color is drawn behind each qualifying transparent water face before the map's authored stages; those stages still provide their original tint, scroll, animation, blend, and deformation. After the authored stages, a grazing-angle reflection pass mirrors the same captured pre-transparency snapshot back onto the surface — it never resamples the live color buffer, so the duplicated and smeared camera-image feedback produced by the earlier experimental path cannot occur. Enhancements and ripples both default to off, so existing maps, configurations, and demos keep the classic presentation unless you opt in.
r_liquidselects qualifying liquids from their shader contents. The default0disables the enhancement,1enhances shaders marked as water, and2also enhances shaders marked as slime or lava with more subdued material-specific strengths. This setting is latched.r_liquidResolutionsets the snapshot resolution from0.25to1.0; the default is1.0, which samples the scene at full resolution and keeps warped edges crisp. Lower values reduce bandwidth but soften the refraction and can make displaced high-contrast edges crawl. This setting is latched.r_liquidRefractioncontrols the opacity of warped scene color behind the authored transparent stages, from0.0to1.0. The default is0.65; lower values retain more of the original destination.r_liquidWarpScalemultiplies the ambient wave distortion, from0.0to2.0with a default of1.0(about12pixels at 1080 lines). The distortion is scaled to the view height so it keeps the same angular size at every resolution, and it fades with eye distance and grazing angle so distant or near-horizon liquid does not shimmer.r_liquidReflectioncontrols the strength of the grazing-angle reflection pass, from0.0to1.0. The default is0.65;0completely skips the pass. Where the mirrored sample would land off screen or behind the camera, the pass falls back to a flat material-coloured sheen.r_liquidRipplessets the amplitude of visual disturbances from players and missiles entering, leaving, or moving through liquid, from0.0to2.0. The default is1.0;0disables the impulse feed entirely. A nonzeror_liquidmode is required.
When scene depth is available (it is by default; see r_depthFade), the refraction rejects warped samples that land on foreground geometry, which keeps the waterline crisp instead of smearing rims and ledges into the water. The reflection is a bounded single-tap screen-space approximation of the captured view, not a second mirrored world render.
These names replace the older r_liquidReflections, r_liquidReflectionScale, r_liquidWarp, r_liquidFresnel, and r_liquidRippleStrength cvars, which are no longer read.
The effect requires r_fbo 1. Changing r_liquid or r_liquidResolution reallocates the snapshot resource, so issue vid_restart after changing either one. Refraction, warp, reflection, and ripples can be tuned live. A balanced starting point is:
seta r_fbo "1"
seta r_liquid "1"
vid_restart
This is an intentionally inexpensive screen-space effect, not a second mirrored world render, a depth-ray-marched SSR, or a fluid simulation. Both the refraction and the reflection can only reuse the same-frame color already captured from the current view: objects outside the screen, behind the camera, occluded, or drawn later in the transparent sort cannot appear in either, and the reflection projects each mirrored ray to a single proxy distance rather than searching the depth buffer for a true hit. Warp and reflection fade near screen edges, and the reflection cleanly falls back to a material sheen where its sample is invalid. Unusually early custom sorts, alpha-tested liquid stages, depth-fade or line-mode stages, and nonstandard depth-test modes retain their fully authored appearance because a geometry-only underlay cannot reproduce their coverage safely. Ripples are bounded visual responses to player and missile motion with amplitude independent of ambient warp; they distort the sampled image but do not deform the liquid mesh or change collision, buoyancy, player movement, projectile paths, networking, game logic, or demo state. If the framebuffer path or private liquid snapshot is unavailable, the original authored liquid remains visible.
For the pass ordering, backend tiers, dedicated snapshot, and compatibility invariants, see Liquid Rendering.
Underwater View
While the camera is under water, slime, or lava, the OpenGL-lineage renderers, including GLx, and the Vulkan renderers can composite a submerged view over the finished scene: an animated screen warp with a slight colour separation, a darkened periphery, and a medium tint that deepens with distance. It is the view-side counterpart to Enhanced Liquids above — that setting draws water seen from outside, this one draws the world seen from inside it — and the two are independent. The layer defaults to off, so existing configurations and demos keep the classic presentation unless you opt in.
r_underwaterenables the layer for all three liquid types. The default is0. This setting is latched.r_underwaterWarpmultiplies the wave distortion, from0.0to2.0with a default of1.0(about11pixels at 1080 lines before the liquid's own multiplier). The distortion is scaled to the view height so it keeps the same angular size at every resolution.0flattens the warp.r_underwaterDispersionsets how far the red and blue channels separate across the warp, from0.0to1.0with a default of0.35.0keeps all three channels aligned.r_underwaterFogscales the distance tint, from0.0to1.0with a default of1.0. The colour and how quickly it closes in follow the liquid: water stays readable at short range, slime loses the scene within a room, and lava is nearly opaque.0disables the tint.r_underwaterVignettesets the edge darkening, from0.0to1.0with a default of0.35.0leaves the periphery at full brightness.
Entering and leaving a liquid ramps the whole layer over about a fifth of a second, so a surface crossing does not pop. The HUD and console are drawn after the layer and stay sharp. The distance tint needs a usable depth texture; without one the warp and edge darkening still apply.
The effect requires r_fbo 1. Changing r_underwater allocates renderer resources, so issue vid_restart after changing it. The other four settings can be tuned live. A balanced starting point is:
seta r_fbo "1"
seta r_underwater "1"
vid_restart
This is a post-process on the frame that has already been rendered, not a refracted re-render of the world. It bends and tints what was visible rather than revealing anything new, the screen border is stretched rather than filled, and there are no caustics, light shafts, or bubbles. Crossing the waterline switches the medium at the eye instead of splitting the view into above-surface and below-surface halves. Nothing about the layer touches collision, buoyancy, movement, projectile paths, networking, game logic, or demo state.
For the submersion feed, pass ordering, backend tiers, and compatibility invariants, see Underwater View.
Optional Global Fog
Map authors and mods can add a visual-only, depth-aware atmospheric layer with a maps/<map>.fog sidecar. FnQL does not ship map fog profiles, and the feature does not replace authored BSP fog or affect visibility, collision, game state, networking, demos, or module ABIs.
r_globalFog: Enables sidecar loading and composition on the OpenGL-lineage and Vulkan renderers. The default is0; changing it requiresvid_restart.r_globalFogStrength: Live opacity multiplier from0.0to1.0, with a default of1.0.r_fbo 1and a usable depth texture are required. Missing or invalid sidecars and optional-shader failures disable only the fog layer; they never preventglx,vk, orrtxfrom starting.
See Global Fog Sidecars for the bounded file format, search precedence, curve definitions, and fallback contract.
Bloom
Bloom extracts bright areas from the rendered frame, blurs them through a downsampled chain, and blends the result back over the original image. It is a post-processing effect, so it depends on the framebuffer path.
Requirements
r_fbo 1is required.- OpenGL and Vulkan both support bloom.
- OpenGL exposes the largest bloom control set. GLx preserves that same control surface as the canonical OpenGL-lineage renderer.
- Vulkan currently exposes the shared extraction and intensity controls, but not the OpenGL-only shape controls.
Shared Bloom Controls
These settings are available in both renderers.
r_bloom: Master bloom toggle.- On OpenGL, use
0,1, or2.0: Disabled.1: Bloom the rendered 3D scene.2: Also let bloom affect 2D and HUD elements drawn before the final post-process pass.
- On Vulkan, treat
r_bloomas0or1.
- On OpenGL, use
r_bloom_threshold: Brightness cutoff for extraction. Higher values restrict bloom to stronger highlights. Lower values let more of the frame glow.r_bloom_threshold_mode: How brightness is measured.0: Trigger when any color channel reaches the threshold.1: Trigger when the average ofr,g, andbreaches the threshold.2: Trigger using luma weighting. This is usually the cleanest and most predictable mode.
r_bloom_modulate: How strongly extracted color is biased toward already-bright areas.0: Leave extracted color unchanged.1: Multiply the color by itself for a more aggressive highlight push.2: Multiply the color by its luma for a cleaner brightness-weighted result.
r_bloom_intensity: Final bloom blend strength.r_flareSceneLinear: In ther_hdr 1scene-linear path, flare vertex colors are decoded to linear RGB before bloom extraction. Set this to0only when comparing against the legacy display-referred flare behavior.
Recommended tuning order:
- Enable
r_bloom 1. - Set
r_bloom_threshold_mode 2. - Adjust
r_bloom_thresholduntil only the highlights you want are being extracted. - Adjust
r_bloom_modulateif you want a tighter or more contrast-driven response. - Adjust
r_bloom_intensitylast.
GLx Bloom Controls
These settings are specific to the canonical OpenGL-lineage renderer, glx.
r_bloom_passes: Number of downsampled bloom levels used in the effect. More passes generally create a wider haze and cost more GPU time. The engine may clamp the effective chain length based on hardware limits or very small internal render sizes.r_bloom_blend_base: Which downsampled level to start blending from. Higher values skip the tighter levels and bias the result toward a broader, softer haze.r_bloom_filter_size: Blur filter size per bloom level. Higher values widen the blur and cost more.r_bloom_reflection: Lens reflection effect intensity.- Positive values add the reflection on top of the main bloom.
- Negative values keep only the reflection path and skip the main bloom texture.
Practical interpretation:
- Increase
r_bloom_passesif you want bloom to spread farther from bright sources. - Increase
r_bloom_blend_baseif you want less tight glow and more broad atmosphere. - Increase
r_bloom_filter_sizeif the bloom still feels too sharp. - Use
r_bloom_reflectioncarefully. It is a stylized effect and becomes obvious quickly.
Bloom Tuning Recipes
Subtle highlight bloom:
seta r_fbo "1"
seta r_bloom "1"
seta r_bloom_threshold "0.75"
seta r_bloom_threshold_mode "2"
seta r_bloom_modulate "2"
seta r_bloom_intensity "0.25"
Balanced bloom for bright maps and effects:
seta r_fbo "1"
seta r_bloom "1"
seta r_bloom_threshold "0.60"
seta r_bloom_threshold_mode "2"
seta r_bloom_modulate "2"
seta r_bloom_intensity "0.45"
GLx haze-heavy bloom:
seta cl_renderer "glx"
seta r_fbo "1"
seta r_bloom "1"
seta r_bloom_threshold "0.55"
seta r_bloom_threshold_mode "2"
seta r_bloom_modulate "2"
seta r_bloom_intensity "0.45"
seta r_bloom_passes "6"
seta r_bloom_blend_base "2"
seta r_bloom_filter_size "8"
vid_restart
GLx HUD-inclusive bloom:
seta cl_renderer "glx"
seta r_fbo "1"
seta r_bloom "2"
seta r_bloom_threshold "0.65"
seta r_bloom_threshold_mode "2"
seta r_bloom_intensity "0.35"
GLx lens reflection add-on:
seta cl_renderer "glx"
seta r_fbo "1"
seta r_bloom "1"
seta r_bloom_threshold "0.60"
seta r_bloom_threshold_mode "2"
seta r_bloom_intensity "0.40"
seta r_bloom_reflection "0.25"
Bloom Troubleshooting
If bloom seems too weak:
- Lower
r_bloom_threshold. - Use
r_bloom_threshold_mode 0or2. - Raise
r_bloom_intensity. - On OpenGL or GLx, increase
r_bloom_passesorr_bloom_filter_size.
If bloom is making the whole frame look milky:
- Raise
r_bloom_threshold. - Lower
r_bloom_intensity. - Use
r_bloom_threshold_mode 2. - On OpenGL or GLx, lower
r_bloom_passes, lowerr_bloom_filter_size, or reducer_bloom_blend_base.
If HUD elements are glowing and you do not want that:
- On OpenGL or GLx, use
r_bloom 1instead ofr_bloom 2.
If nothing happens at all:
- Confirm
r_fbo 1. - Confirm bloom is actually enabled with
r_bloom. - Lower
r_bloom_thresholdto test. - If you just changed renderer, display mode, or other latched video settings, use
vid_restart.
Motion Blur
The OpenGL-lineage renderers, including GLx, and Vulkan provide optional camera-driven screen motion blur. After the completed world view, the renderer measures camera rotation and lateral movement and applies a bounded seven-tap directional kernel to the current scene before bloom, tone mapping, and output encoding. Sampling is clamped to the 3D view rectangle, including when cg_viewsize is reduced. It does not blend previous-frame pixels, so a stationary view is unchanged and moving entities cannot leave persistent trails.
r_motionBlur: Master toggle. The default is0(disabled), andr_fbo 1is required.r_motionBlurStrength: Camera-motion shutter scale from0.0to1.0. The default0.25is deliberately subtle; higher values increase the directional blur radius.- HUD, console, and other 2D drawing are always added after motion blur and remain sharp.
r_hudExcludePostProcesscontinues to control the separate bloom/3D-HUD behavior.
Recommended subtle setup:
seta r_fbo "1"
seta r_motionBlur "1"
seta r_motionBlurStrength "0.25"
seta r_hudExcludePostProcess "1"
The blur is skipped below a sub-pixel motion threshold and capped at a 32-pixel radius, preventing needless work during stationary play and pathological smearing during fast turns. Long frame stalls, minimize/restore, stereo rendering, large camera cuts, and teleports reset the camera sample. GLX allocates its scratch buffer lazily when motion first needs it and can toggle the effect live. Vulkan allocates its scratch image at renderer initialization, so changing r_motionBlur there requires vid_restart.
When To Use vid_restart
Use vid_restart after changes to:
cl_rendererr_mode,r_modeFullscreen,r_fullscreenr_customWidth,r_customHeight,r_customPixelAspectr_displayRefreshr_noborderr_fbor_hdrr_hdrPrecisionr_ext_multisampler_ext_alpha_to_coverager_depthFader_renderWidth,r_renderHeight,r_renderScaler_ext_supersample- OpenGL or GLx
r_bloom_passes - OpenGL or GLx
r_hdrBloomFormat - Vulkan
r_bloom - Vulkan
r_motionBlur r_liquidorr_liquidResolutionr_underwater
For pure window-state changes (r_fullscreen, r_mode, r_noborder, window size or position), prefer vid_restart fast: it applies the change on the existing window when possible and falls back to a full restart automatically. See Fast Windowed/Fullscreen Toggle.
Settings that are usually safe to tune live:
r_swapIntervalr_gammar_greyscaler_bloom_thresholdr_bloom_threshold_moder_bloom_soft_kneer_bloom_modulater_bloom_intensityr_motionBlurStrengthr_tonemapr_tonemapExposurer_colorGrader_colorGradeLiftr_colorGradeGammar_colorGradeGainr_colorGradeWhitePointr_colorGradeAdaptWhitePointr_colorGradeLUTr_colorGradeLUTScaler_celShadingr_celShadingModelShadowsr_celViewWeaponr_celShadingStepsr_celOutliner_celOutlineScaler_celOutlineAlphar_celViewWeaponOutlineScaler_celViewWeaponOutlineAlphar_celOutlineColorr_celShadingWorldr_celShadingWorldWidthr_celShadingWorldAlphar_celShadingWorldDepthThreshold- OpenGL or GLx
r_bloom_blend_base - OpenGL or GLx
r_bloom_filter_size - OpenGL or GLx
r_bloom_reflection
If a live change does not seem to take effect immediately, vid_restart is the safe fallback.
Related Guides
- ASPECT_CORRECTION.md for HUD, menu, and cinematic presentation.
- VISUALS.md for player highlighting and other visual presentation controls.
- SCREENSHOTS.md for screenshot and capture output options.