using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.Json;
using System.Text.Json.Serialization;
using GBRTX;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppSystem.Collections.Generic;
using MelonLoader;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Mod), "GB RTX", "1.0.0", "GBMods", null)]
[assembly: MelonGame("Boneloaf", "Gang Beasts")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("GBRTX")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("GBRTX")]
[assembly: AssemblyTitle("GBRTX")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace GBRTX
{
public class Mod : MelonMod
{
private const string HostName = "[Mod] RTX";
private GameObject host;
private bool registered;
public static Instance Logger => Melon<Mod>.Logger;
public override void OnInitializeMelon()
{
try
{
ClassInjector.RegisterTypeInIl2Cpp<RTXController>();
registered = true;
}
catch (Exception ex)
{
((MelonBase)this).LoggerInstance.Error("Couldn't register RTXController: " + ex);
return;
}
((MelonBase)this).LoggerInstance.Msg("GB RTX 1.0.0 loaded. F10 toggles, F11 hides the bar.");
}
public override void OnSceneWasInitialized(int buildIndex, string sceneName)
{
SpawnHost();
}
public override void OnUpdate()
{
if (registered && (Object)(object)host == (Object)null)
{
SpawnHost();
}
}
private void SpawnHost()
{
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Expected O, but got Unknown
if (registered && !((Object)(object)host != (Object)null))
{
GameObject val = GameObject.Find("[Mod] RTX");
if ((Object)(object)val != (Object)null && (Object)(object)val.GetComponent<RTXController>() != (Object)null)
{
host = val;
return;
}
host = new GameObject("[Mod] RTX")
{
hideFlags = (HideFlags)32
};
Object.DontDestroyOnLoad((Object)(object)host);
host.AddComponent<RTXController>();
}
}
}
public class RTXController : MonoBehaviour
{
private const float Row = 24f;
private const float PanelWidth = 440f;
private const float LabelWidth = 160f;
private const float ValueWidth = 54f;
private RTXSettings settings;
private RTXSlots slots;
private RTXRenderer rtx;
private bool ready;
private bool panelOpen;
private bool helpOpen;
private bool barHidden;
private int helpTab;
private Vector2 scroll;
private Vector2 helpScroll;
private float contentHeight = 1600f;
private string lastScene;
private bool dirty;
private bool slotsDirty;
private float saveAt;
private float slotSaveAt;
private int loadedSlot = -1;
private string status;
private float statusUntil;
private bool cursorSaved;
private bool oldCursorVisible;
private CursorLockMode oldCursorLock;
private bool stylesReady;
private GUIStyle barStyle;
private GUIStyle panelStyle;
private GUIStyle titleStyle;
private GUIStyle onBtn;
private GUIStyle offBtn;
private GUIStyle btn;
private GUIStyle activeBtn;
private GUIStyle header;
private GUIStyle label;
private GUIStyle valueLabel;
private GUIStyle toggle;
private GUIStyle textField;
private GUIStyle dimLabel;
private GUIStyle statusLabel;
private GUIStyle helpTitle;
private GUIStyle helpBody;
public RTXController(IntPtr ptr)
: base(ptr)
{
}
private void Init()
{
if (!ready)
{
settings = RTXSettings.Load();
slots = RTXSlots.Load();
rtx = new RTXRenderer();
ready = true;
}
}
public void Update()
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
Init();
Hotkeys();
Scene activeScene = SceneManager.GetActiveScene();
string name = ((Scene)(ref activeScene)).name;
if (name != lastScene)
{
lastScene = name;
rtx.OnSceneChanged();
}
if (settings.Enabled)
{
try
{
rtx.Apply(settings);
}
catch (Exception ex)
{
Mod.Logger.Error("Apply failed, turning RTX off: " + ex);
SetEnabled(on: false);
}
}
else if (rtx.Active)
{
rtx.Restore();
}
if (panelOpen || helpOpen)
{
Cursor.visible = true;
Cursor.lockState = (CursorLockMode)0;
}
if (slotsDirty && Time.unscaledTime >= slotSaveAt)
{
slots.Save();
slotsDirty = false;
}
if (dirty && Time.unscaledTime >= saveAt)
{
settings.Save();
dirty = false;
}
}
public void OnDestroy()
{
if (ready)
{
ClosePanel();
CloseHelp();
rtx.Destroy();
settings.Save();
if (slotsDirty)
{
slots.Save();
}
}
}
private void Hotkeys()
{
Keyboard current = Keyboard.current;
if (current == null)
{
return;
}
if (((ButtonControl)current.f10Key).wasPressedThisFrame)
{
SetEnabled(!settings.Enabled);
}
if (((ButtonControl)current.f11Key).wasPressedThisFrame)
{
barHidden = !barHidden;
if (barHidden)
{
ClosePanel();
CloseHelp();
}
}
}
private void SetEnabled(bool on)
{
settings.Enabled = on;
if (!on)
{
rtx.Restore();
}
MarkDirty();
Mod.Logger.Msg(on ? "RTX on" : "RTX off");
}
private void MarkDirty()
{
dirty = true;
saveAt = Time.unscaledTime + 1f;
}
private void UsePreset(RTXSettings.Preset preset)
{
bool enabled = settings.Enabled;
settings = RTXSettings.FromPreset(preset);
settings.Enabled = enabled;
loadedSlot = -1;
MarkDirty();
}
private void OpenPanel()
{
if (!panelOpen)
{
GrabCursor();
helpOpen = false;
panelOpen = true;
}
}
private void ClosePanel()
{
if (panelOpen)
{
panelOpen = false;
ReleaseCursor();
}
}
private void OpenHelp()
{
if (!helpOpen)
{
GrabCursor();
panelOpen = false;
helpOpen = true;
}
}
private void CloseHelp()
{
if (helpOpen)
{
helpOpen = false;
ReleaseCursor();
}
}
private void GrabCursor()
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
if (!cursorSaved)
{
oldCursorVisible = Cursor.visible;
oldCursorLock = Cursor.lockState;
cursorSaved = true;
}
}
private void ReleaseCursor()
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
if (!panelOpen && !helpOpen && cursorSaved)
{
Cursor.visible = oldCursorVisible;
Cursor.lockState = oldCursorLock;
cursorSaved = false;
}
}
public void OnGUI()
{
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
//IL_015a: Unknown result type (might be due to invalid IL or missing references)
//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
//IL_0200: Unknown result type (might be due to invalid IL or missing references)
//IL_020f: Unknown result type (might be due to invalid IL or missing references)
if (!ready || barHidden)
{
return;
}
Styles();
GUI.depth = -1000;
Rect val = default(Rect);
((Rect)(ref val))..ctor(((float)Screen.width - 360f) * 0.5f, 6f, 360f, 36f);
GUI.Box(val, "", barStyle);
GUI.Label(new Rect(((Rect)(ref val)).x + 12f, ((Rect)(ref val)).y + 6f, 60f, 24f), "RTX", titleStyle);
string text = (settings.Enabled ? $"ON · {settings.CurrentPreset}" : "OFF");
if (GUI.Button(new Rect(((Rect)(ref val)).x + 70f, ((Rect)(ref val)).y + 6f, 150f, 24f), text, settings.Enabled ? onBtn : offBtn))
{
SetEnabled(!settings.Enabled);
}
if (GUI.Button(new Rect(((Rect)(ref val)).xMax - 122f, ((Rect)(ref val)).y + 6f, 52f, 24f), "Help", helpOpen ? activeBtn : btn))
{
if (helpOpen)
{
CloseHelp();
}
else
{
OpenHelp();
}
}
if (GUI.Button(new Rect(((Rect)(ref val)).xMax - 64f, ((Rect)(ref val)).y + 6f, 52f, 24f), panelOpen ? "▲" : "▼", btn))
{
if (panelOpen)
{
ClosePanel();
}
else
{
OpenPanel();
}
}
if (panelOpen)
{
DrawPanel(val);
}
if (helpOpen)
{
DrawHelp(val);
}
}
private void DrawPanel(Rect bar)
{
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_0148: Unknown result type (might be due to invalid IL or missing references)
//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
//IL_025b: Unknown result type (might be due to invalid IL or missing references)
//IL_0bda: Unknown result type (might be due to invalid IL or missing references)
//IL_0c0a: Unknown result type (might be due to invalid IL or missing references)
//IL_0c3f: Unknown result type (might be due to invalid IL or missing references)
float num = Mathf.Min(640f, (float)Screen.height - ((Rect)(ref bar)).yMax - 20f);
Rect val = default(Rect);
((Rect)(ref val))..ctor(((float)Screen.width - 440f) * 0.5f, ((Rect)(ref bar)).yMax + 4f, 440f, num);
GUI.Box(val, "", panelStyle);
Rect val2 = default(Rect);
((Rect)(ref val2))..ctor(((Rect)(ref val)).x + 10f, ((Rect)(ref val)).y + 8f, ((Rect)(ref val)).width - 20f, ((Rect)(ref val)).height - 16f);
float num2 = ((Rect)(ref val2)).width - 18f;
scroll = GUI.BeginScrollView(val2, scroll, new Rect(0f, 0f, num2, contentHeight));
float y = 0f;
bool flag = false;
RTXSettings.Preset? preset = null;
Header(ref y, num2, "Preset");
RTXSettings.Preset[] array = new RTXSettings.Preset[6]
{
RTXSettings.Preset.Shitty,
RTXSettings.Preset.Low,
RTXSettings.Preset.Medium,
RTXSettings.Preset.High,
RTXSettings.Preset.Ultra,
RTXSettings.Preset.Photoreal
};
float num3 = (num2 - 8f) / 3f;
for (int i = 0; i < array.Length; i++)
{
if (GUI.Button(new Rect((float)(i % 3) * (num3 + 4f), y + (float)(i / 3) * 28f, num3, 24f), array[i].ToString(), (settings.CurrentPreset == array[i]) ? activeBtn : btn))
{
preset = array[i];
}
}
y += (float)((array.Length + 2) / 3) * 28f;
if (settings.CurrentPreset == RTXSettings.Preset.Custom)
{
GUI.Label(new Rect(0f, y, num2, 24f), "Custom", label);
}
y += 24f;
DrawSlots(ref y, num2);
Header(ref y, num2, "Image Quality");
RTXSettings.Upscaler[] array2 = (RTXSettings.Upscaler[])Enum.GetValues(typeof(RTXSettings.Upscaler));
float num4 = (num2 - 8f) / 3f;
for (int j = 0; j < array2.Length; j++)
{
if (GUI.Button(new Rect((float)(j % 3) * (num4 + 4f), y + (float)(j / 3) * 28f, num4, 24f), RTXSettings.UpscalerLabel(array2[j]), (settings.UpscaleMode == array2[j]) ? activeBtn : btn) && settings.UpscaleMode != array2[j])
{
settings.UpscaleMode = array2[j];
flag = true;
}
}
y += (float)((array2.Length + 2) / 3) * 28f;
float pct = settings.RenderScale * 100f;
if (Slider(ref y, num2, "Screen %", pct, 10f, 200f, "0'%'", delegate(float v)
{
pct = v;
}))
{
settings.ScreenPercent = Mathf.RoundToInt(pct);
settings.UpscaleMode = RTXSettings.Upscaler.Custom;
flag = true;
}
flag |= Toggle(ref y, num2, "Pixelated upscaling", settings.PixelatedUpscale, delegate(bool v)
{
settings.PixelatedUpscale = v;
});
flag |= Slider(ref y, num2, "FSR sharpness", settings.FsrSharpness, 0f, 1f, "0.00", delegate(float v)
{
settings.FsrSharpness = v;
});
flag |= Toggle(ref y, num2, "Anti-aliasing (SMAA)", settings.Antialiasing, delegate(bool v)
{
settings.Antialiasing = v;
});
Header(ref y, num2, "Ambient Occlusion");
flag |= Toggle(ref y, num2, "Enabled", settings.Ssao, delegate(bool v)
{
settings.Ssao = v;
});
flag |= Slider(ref y, num2, "Intensity", settings.SsaoIntensity, 0f, 4f, "0.00", delegate(float v)
{
settings.SsaoIntensity = v;
});
flag |= Slider(ref y, num2, "Radius", settings.SsaoRadius, 0.05f, 1.5f, "0.00", delegate(float v)
{
settings.SsaoRadius = v;
});
flag |= Slider(ref y, num2, "Direct light", settings.SsaoDirectLighting, 0f, 1f, "0.00", delegate(float v)
{
settings.SsaoDirectLighting = v;
});
flag |= IntSlider(ref y, num2, "Samples", settings.SsaoSamples, 2, 20, delegate(int v)
{
settings.SsaoSamples = v;
});
flag |= Toggle(ref y, num2, "Full resolution", settings.SsaoFullResolution, delegate(bool v)
{
settings.SsaoFullResolution = v;
});
Header(ref y, num2, "Bloom");
flag |= Toggle(ref y, num2, "Enabled", settings.Bloom, delegate(bool v)
{
settings.Bloom = v;
});
flag |= Slider(ref y, num2, "Intensity", settings.BloomIntensity, 0f, 10f, "0.00", delegate(float v)
{
settings.BloomIntensity = v;
});
flag |= Slider(ref y, num2, "Threshold", settings.BloomThreshold, 0f, 2f, "0.00", delegate(float v)
{
settings.BloomThreshold = v;
});
flag |= Slider(ref y, num2, "Scatter", settings.BloomScatter, 0f, 1f, "0.00", delegate(float v)
{
settings.BloomScatter = v;
});
Header(ref y, num2, "Colour");
flag |= Toggle(ref y, num2, "ACES tonemapping", settings.AcesTonemapping, delegate(bool v)
{
settings.AcesTonemapping = v;
});
flag |= Slider(ref y, num2, "Exposure", settings.Exposure, -2f, 3f, "0.00", delegate(float v)
{
settings.Exposure = v;
});
flag |= Slider(ref y, num2, "Contrast", settings.Contrast, -100f, 100f, "0", delegate(float v)
{
settings.Contrast = v;
});
flag |= Slider(ref y, num2, "Saturation", settings.Saturation, -100f, 100f, "0", delegate(float v)
{
settings.Saturation = v;
});
flag |= Slider(ref y, num2, "Temperature", settings.Temperature, -100f, 100f, "0", delegate(float v)
{
settings.Temperature = v;
});
flag |= Slider(ref y, num2, "Cinematic grade", settings.CinematicGrade, 0f, 1f, "0.00", delegate(float v)
{
settings.CinematicGrade = v;
});
Header(ref y, num2, "Camera");
flag |= Toggle(ref y, num2, "Depth of field", settings.DepthOfField, delegate(bool v)
{
settings.DepthOfField = v;
});
flag |= Toggle(ref y, num2, "Auto focus", settings.DofAutoFocus, delegate(bool v)
{
settings.DofAutoFocus = v;
});
flag |= Slider(ref y, num2, "Aperture (f)", settings.DofAperture, 1f, 16f, "0.0", delegate(float v)
{
settings.DofAperture = v;
});
flag |= Slider(ref y, num2, "Focal length (mm)", settings.DofFocalLength, 20f, 300f, "0", delegate(float v)
{
settings.DofFocalLength = v;
});
flag |= Slider(ref y, num2, "Manual focus (m)", settings.DofManualDistance, 0.5f, 60f, "0.0", delegate(float v)
{
settings.DofManualDistance = v;
});
flag |= Toggle(ref y, num2, "Motion blur", settings.MotionBlur, delegate(bool v)
{
settings.MotionBlur = v;
});
flag |= Slider(ref y, num2, "Blur amount", settings.MotionBlurIntensity, 0f, 1f, "0.00", delegate(float v)
{
settings.MotionBlurIntensity = v;
});
Header(ref y, num2, "Lens");
flag |= Slider(ref y, num2, "Vignette", settings.Vignette, 0f, 1f, "0.00", delegate(float v)
{
settings.Vignette = v;
});
flag |= Slider(ref y, num2, "Vignette softness", settings.VignetteSmoothness, 0.01f, 1f, "0.00", delegate(float v)
{
settings.VignetteSmoothness = v;
});
flag |= Slider(ref y, num2, "Chromatic aberration", settings.ChromaticAberration, 0f, 1f, "0.00", delegate(float v)
{
settings.ChromaticAberration = v;
});
flag |= Slider(ref y, num2, "Lens distortion", settings.LensDistortion, -1f, 1f, "0.00", delegate(float v)
{
settings.LensDistortion = v;
});
flag |= Slider(ref y, num2, "Film grain", settings.FilmGrain, 0f, 1f, "0.00", delegate(float v)
{
settings.FilmGrain = v;
});
Header(ref y, num2, "Atmosphere");
flag |= Toggle(ref y, num2, "Fog", settings.Fog, delegate(bool v)
{
settings.Fog = v;
});
flag |= Slider(ref y, num2, "Fog density", settings.FogDensity, 0f, 0.08f, "0.0000", delegate(float v)
{
settings.FogDensity = v;
});
Header(ref y, num2, "Shadows");
flag |= Toggle(ref y, num2, "Soft shadows", settings.EnhancedShadows, delegate(bool v)
{
settings.EnhancedShadows = v;
});
flag |= Slider(ref y, num2, "Shadow distance", settings.ShadowDistance, 30f, 300f, "0", delegate(float v)
{
settings.ShadowDistance = v;
});
flag |= Toggle(ref y, num2, "No shadows", settings.NoShadows, delegate(bool v)
{
settings.NoShadows = v;
});
Header(ref y, num2, "Performance / Potato");
flag |= IntSlider(ref y, num2, "Texture blur (0 = off)", settings.TextureMipLimit, 0, 4, delegate(int v)
{
settings.TextureMipLimit = v;
});
flag |= Toggle(ref y, num2, "Low detail models", settings.LowDetailModels, delegate(bool v)
{
settings.LowDetailModels = v;
});
flag |= IntSlider(ref y, num2, "FPS cap (0 = off)", settings.FpsCap, 0, 144, delegate(int v)
{
settings.FpsCap = v;
});
y += 8f;
float num5 = (num2 - 6f) * 0.5f;
if (GUI.Button(new Rect(0f, y, num5, 24f), "Reset", btn))
{
preset = RTXSettings.Preset.High;
}
if (GUI.Button(new Rect(num5 + 6f, y, num5, 24f), "Close", btn))
{
ClosePanel();
}
y += 30f;
GUI.Label(new Rect(0f, y, num2, 24f), "F10 toggle · F11 hide bar", label);
y += 24f;
contentHeight = y + 8f;
GUI.EndScrollView();
if (preset.HasValue)
{
UsePreset(preset.Value);
}
else if (flag)
{
settings.CurrentPreset = RTXSettings.Preset.Custom;
loadedSlot = -1;
MarkDirty();
}
}
private void DrawHelp(Rect bar)
{
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
//IL_0141: Unknown result type (might be due to invalid IL or missing references)
//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
//IL_01fb: Expected O, but got Unknown
//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0201: Unknown result type (might be due to invalid IL or missing references)
//IL_021a: Unknown result type (might be due to invalid IL or missing references)
//IL_021f: Unknown result type (might be due to invalid IL or missing references)
//IL_0224: Unknown result type (might be due to invalid IL or missing references)
//IL_0237: Unknown result type (might be due to invalid IL or missing references)
//IL_017c: Unknown result type (might be due to invalid IL or missing references)
//IL_0181: Unknown result type (might be due to invalid IL or missing references)
float num = Mathf.Min(580f, (float)Screen.width - 20f);
float num2 = Mathf.Min(600f, (float)Screen.height - ((Rect)(ref bar)).yMax - 20f);
Rect val = default(Rect);
((Rect)(ref val))..ctor(((float)Screen.width - num) * 0.5f, ((Rect)(ref bar)).yMax + 4f, num, num2);
GUI.Box(val, "", panelStyle);
GUI.Label(new Rect(((Rect)(ref val)).x + 14f, ((Rect)(ref val)).y + 10f, num - 70f, 26f), "GB RTX Help", helpTitle);
if (GUI.Button(new Rect(((Rect)(ref val)).xMax - 42f, ((Rect)(ref val)).y + 10f, 30f, 24f), "X", btn))
{
CloseHelp();
return;
}
string[] array = new string[2] { "What is this mod?", "How do I use it?" };
float num3 = (num - 34f) * 0.5f;
for (int i = 0; i < array.Length; i++)
{
if (GUI.Button(new Rect(((Rect)(ref val)).x + 14f + (float)i * (num3 + 6f), ((Rect)(ref val)).y + 44f, num3, 28f), array[i], (helpTab == i) ? activeBtn : btn) && helpTab != i)
{
helpTab = i;
helpScroll = Vector2.zero;
}
}
Rect val2 = default(Rect);
((Rect)(ref val2))..ctor(((Rect)(ref val)).x + 14f, ((Rect)(ref val)).y + 82f, num - 22f, num2 - 94f);
string text = ((helpTab == 0) ? "<size=15><b><color=#8CD91A>So what is this?</color></b></size>\nGB RTX is a graphics mod for Gang Beasts. It makes the game look a lot more realistic, or a lot more cinematic, depending on how far you push it. You get proper contact shadows in corners and under the beasts, glow on bright lights, film-style colours, a camera that can blur the background like a real lens, motion blur, nicer shadows, fog, and better anti-aliasing. Everything lives in the little bar at the top of the screen, so you can keep it subtle or go all out. Customize it to your liking!\n\n<size=15><b><color=#8CD91A>How it works</color></b></size>\nGang Beasts runs on Unity's URP renderer, and URP already ships with a bunch of high end effects that the game just doesn't use. This mod switches those on and tunes them while you play. It adds a post-processing volume for the camera effects, plugs URP's ambient occlusion into the renderer, bumps up the shadow settings, and lets you change the render resolution with AMD FSR or supersampling. Since it's all stuff the engine already supports, it works on every map and doesn't mess with the game's own shaders.\n\n<size=15><b><color=#8CD91A>Is it actually RTX?</color></b></size>\nNope, the name is a bit of a joke. Real ray tracing have to be built into the game with NVIDIA's tools, and URP doesn't support either, so no mod can add them. What you're getting is about as realistic as this engine can look. Upside: it works on any GPU, not just NVIDIA cards.\n\n<size=15><b><color=#8CD91A>Will it break anything?</color></b></size>\nIt shouldn't. It only changes how the game is drawn. Gameplay, physics, saves and online stuff aren't touched. Turn it off and everything it changed goes back to how the game had it. If something does go wrong while it's applying the effects, it logs the error and turns itself off instead of crashing.\n\n<size=15><b><color=#8CD91A>Where's my stuff saved?</color></b></size>\nYour settings go in UserData\\GBRTX.json and your save slots in UserData\\GBRTX_Slots.json, both inside the game folder. In-game the mod makes two objects, \"[Mod] RTX\" and \"[Mod] RTX Volume\", and they stick around between maps." : "<size=15><b><color=#8CD91A>Getting started</color></b></size>\nHit F10 (or click the OFF/ON button at the top) to turn it on. You can do this mid-match, it's fine. The arrow opens the settings and Help opens this window. F11 hides the bar if you want clean screenshots or recordings. Your mouse shows up while a window is open and goes back to normal when you close it.\n\n<size=15><b><color=#8CD91A>Presets</color></b></size>\nEasiest way to start. Low is for weaker PCs. Medium and High are a good middle ground. Ultra cranks most things up. Photoreal turns literally everything on, depth of field and motion blur included, so it looks the best but it's also the heaviest. Touch any slider and it switches to Custom, so feel free to pick a preset and tweak from there.\n\nAnd then there's Shitty. It does the exact opposite: the game renders at 10% of your screen and gets blown back up into chunky pixels, textures turn to mush, models drop to their lowest detail, and shadows, anti-aliasing and every post effect are switched off, the game's own ones included. It's a joke preset, have fun with it. Pick any other preset to get the game back.\n\n<size=15><b><color=#8CD91A>Save slots</color></b></size>\nYou've got 10 of them at the top of the settings. Click a name to rename it, Save stores what you've got right now, Load brings it back, and Clear empties it. The green Load button is the slot you're currently on. Loading a slot won't turn the mod on or off, it just swaps the look.\n\n<size=15><b><color=#8CD91A>Image quality</color></b></size>\nNative is your normal resolution. The FSR modes render lower and upscale with AMD FSR. Quality looks almost the same as native, Balanced and Performance trade more detail for more FPS. FSR sharpness is up to you. SSAA 1.5x and 2x go the other way and render above your resolution, which looks super clean but is really expensive. SMAA smooths out jagged edges. Native + SMAA is good for most PCs.\n\n<size=15><b><color=#8CD91A>Ambient occlusion</color></b></size>\nThis is the one that makes the biggest difference. It darkens spots light can't really reach, like corners, the floor under a beast, or where two things touch. Intensity is how dark, Radius is how far it spreads, Direct light controls how much it shows up in sunlight, and Samples smooths it out. Full resolution looks sharper but costs FPS.\n\n<size=15><b><color=#8CD91A>Bloom and colour</color></b></size>\nBloom makes bright stuff glow. Intensity is how strong, Threshold is how bright something has to be before it glows, Scatter is how wide the glow spreads. ACES tonemapping makes bright and dark areas look more like a film camera and stops highlights from blowing out. Exposure, Contrast, Saturation and Temperature do what you'd expect. Cinematic grade gives it that movie look with bluish shadows and warm highlights.\n\n<size=15><b><color=#8CD91A>Camera</color></b></size>\nDepth of field blurs whatever's out of focus. With Auto focus on, it focuses on whatever's in the middle of the screen and slowly pulls focus as things move around. Lower Aperture numbers mean a blurrier background, and Focal length changes how strong it is. Turn Auto focus off and you can set the distance yourself with Manual focus. Motion blur smears fast camera moves. Keep it low if it gets hard to see what's going on.\n\n<size=15><b><color=#8CD91A>Lens, fog and shadows</color></b></size>\nVignette darkens the corners of the screen and Vignette softness makes that more or less gradual. Chromatic aberration adds a bit of colour fringing like a cheap lens, Lens distortion bends the image, and Film grain adds some noise. Fog adds haze so big maps feel deeper. Turn the density down if a map looks washed out. Soft shadows makes shadows smoother and sharper, and Shadow distance is how far away they still get drawn.\n\n<size=15><b><color=#8CD91A>Low FPS?</color></b></size>\nTry these roughly in this order: switch to an FSR mode, turn off Full resolution on ambient occlusion, turn off depth of field and motion blur, lower Shadow distance, or just drop to a lower preset. SSAA is the most expensive thing in here.\n\n<size=15><b><color=#8CD91A>Something looks off</color></b></size>\nToggle it off and on with F10, or click a preset to reset everything. If ambient occlusion is acting weird, just untick it. Errors end up in MelonLoader\\Latest.log, look for lines from GB RTX. Deleting UserData\\GBRTX.json resets your settings but keeps your save slots.");
float num4 = ((Rect)(ref val2)).width - 22f;
float num5 = helpBody.CalcHeight(new GUIContent(text), num4);
helpScroll = GUI.BeginScrollView(val2, helpScroll, new Rect(0f, 0f, num4, num5 + 12f));
GUI.Label(new Rect(0f, 0f, num4, num5), text, helpBody);
GUI.EndScrollView();
}
private void DrawSlots(ref float y, float w)
{
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_0201: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_0111: Unknown result type (might be due to invalid IL or missing references)
//IL_015e: Unknown result type (might be due to invalid IL or missing references)
//IL_019f: Unknown result type (might be due to invalid IL or missing references)
Header(ref y, w, "Save Slots");
for (int i = 0; i < 10; i++)
{
RTXSlots.Slot slot = slots[i];
string text = GUI.TextField(new Rect(0f, y + 1f, 120f, 22f), slot.Name ?? "", 24, textField);
if (text != slot.Name)
{
slot.Name = text;
slotsDirty = true;
slotSaveAt = Time.unscaledTime + 1f;
}
float num = 0f + 124f;
string text2 = (slot.IsEmpty ? "empty" : (slot.SavedAt?.ToString("MM-dd HH:mm") ?? "saved"));
GUI.Label(new Rect(num, y, 96f, 24f), text2, slot.IsEmpty ? dimLabel : label);
float num2 = num + 100f;
if (GUI.Button(new Rect(num2, y, 50f, 24f), "Save", btn))
{
SaveSlot(i);
}
float num3 = num2 + 54f;
bool enabled = GUI.enabled;
GUI.enabled = enabled && !slot.IsEmpty;
if (GUI.Button(new Rect(num3, y, 50f, 24f), "Load", (loadedSlot == i) ? activeBtn : btn))
{
LoadSlot(i);
}
if (GUI.Button(new Rect(num3 + 54f, y, 50f, 24f), "Clear", btn))
{
ClearSlot(i);
}
GUI.enabled = enabled;
y += 26f;
}
if (!string.IsNullOrEmpty(status) && Time.unscaledTime < statusUntil)
{
GUI.Label(new Rect(0f, y, w, 24f), status, statusLabel);
}
y += 24f;
}
private void SaveSlot(int i)
{
slotsDirty = false;
slots.SaveTo(i, settings);
loadedSlot = i;
Status("Saved to \"" + slots[i].Name + "\"");
}
private void LoadSlot(int i)
{
RTXSettings rTXSettings = slots.LoadFrom(i);
if (rTXSettings != null)
{
rTXSettings.Enabled = settings.Enabled;
settings = rTXSettings;
loadedSlot = i;
MarkDirty();
Status("Loaded \"" + slots[i].Name + "\"");
}
}
private void ClearSlot(int i)
{
string name = slots[i].Name;
slots.Clear(i);
if (loadedSlot == i)
{
loadedSlot = -1;
}
Status("Cleared \"" + name + "\"");
}
private void Status(string text)
{
status = text;
statusUntil = Time.unscaledTime + 3f;
}
private void Header(ref float y, float w, string text)
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
y += 6f;
GUI.Label(new Rect(0f, y, w, 24f), text, header);
y += 24f;
}
private bool Toggle(ref float y, float w, string text, bool value, Action<bool> set)
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
bool flag = GUI.Toggle(new Rect(4f, y, w - 4f, 24f), value, " " + text, toggle);
y += 24f;
if (flag == value)
{
return false;
}
set(flag);
return true;
}
private bool Slider(ref float y, float w, string text, float value, float min, float max, string fmt, Action<float> set)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
GUI.Label(new Rect(4f, y, 160f, 24f), text, label);
float num = GUI.HorizontalSlider(new Rect(164f, y + 7f, w - 160f - 54f - 8f, 24f), value, min, max);
GUI.Label(new Rect(w - 54f, y, 54f, 24f), num.ToString(fmt), valueLabel);
y += 24f;
if (Mathf.Approximately(num, value))
{
return false;
}
set(num);
return true;
}
private bool IntSlider(ref float y, float w, string text, int value, int min, int max, Action<int> set)
{
int v = value;
Slider(ref y, w, text, value, min, max, "0", delegate(float f)
{
v = Mathf.RoundToInt(f);
});
if (v == value)
{
return false;
}
set(v);
return true;
}
private void Styles()
{
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Expected O, but got Unknown
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_00e6: Expected O, but got Unknown
//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
//IL_010a: Unknown result type (might be due to invalid IL or missing references)
//IL_010f: Unknown result type (might be due to invalid IL or missing references)
//IL_012f: Unknown result type (might be due to invalid IL or missing references)
//IL_0143: Unknown result type (might be due to invalid IL or missing references)
//IL_0148: Unknown result type (might be due to invalid IL or missing references)
//IL_0168: Unknown result type (might be due to invalid IL or missing references)
//IL_017c: Unknown result type (might be due to invalid IL or missing references)
//IL_0181: Unknown result type (might be due to invalid IL or missing references)
//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
//IL_01df: Unknown result type (might be due to invalid IL or missing references)
//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
//IL_01f8: Expected O, but got Unknown
//IL_0203: Unknown result type (might be due to invalid IL or missing references)
//IL_0214: Unknown result type (might be due to invalid IL or missing references)
//IL_0219: Unknown result type (might be due to invalid IL or missing references)
//IL_0221: Unknown result type (might be due to invalid IL or missing references)
//IL_022d: Expected O, but got Unknown
//IL_0238: Unknown result type (might be due to invalid IL or missing references)
//IL_0245: Unknown result type (might be due to invalid IL or missing references)
//IL_024a: Unknown result type (might be due to invalid IL or missing references)
//IL_0256: Expected O, but got Unknown
//IL_025d: Unknown result type (might be due to invalid IL or missing references)
//IL_0267: Expected O, but got Unknown
//IL_0281: Unknown result type (might be due to invalid IL or missing references)
//IL_0292: Unknown result type (might be due to invalid IL or missing references)
//IL_0297: Unknown result type (might be due to invalid IL or missing references)
//IL_02a3: Expected O, but got Unknown
//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
//IL_02d1: Expected O, but got Unknown
//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
//IL_0302: Unknown result type (might be due to invalid IL or missing references)
//IL_0317: Unknown result type (might be due to invalid IL or missing references)
//IL_032c: Unknown result type (might be due to invalid IL or missing references)
//IL_0331: Unknown result type (might be due to invalid IL or missing references)
//IL_0339: Unknown result type (might be due to invalid IL or missing references)
//IL_0345: Expected O, but got Unknown
//IL_035f: Unknown result type (might be due to invalid IL or missing references)
//IL_0388: Unknown result type (might be due to invalid IL or missing references)
//IL_03a2: Unknown result type (might be due to invalid IL or missing references)
//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
//IL_03d5: Unknown result type (might be due to invalid IL or missing references)
//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
//IL_03e3: Unknown result type (might be due to invalid IL or missing references)
//IL_03ef: Expected O, but got Unknown
//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
if (!stylesReady)
{
Color textColor = default(Color);
((Color)(ref textColor))..ctor(0.55f, 0.85f, 0.1f);
Color textColor2 = default(Color);
((Color)(ref textColor2))..ctor(0.85f, 0.87f, 0.9f);
barStyle = Bg(GUI.skin.box, new Color(0.06f, 0.07f, 0.09f, 0.88f));
panelStyle = Bg(GUI.skin.box, new Color(0.06f, 0.07f, 0.09f, 0.94f));
titleStyle = new GUIStyle(GUI.skin.label)
{
fontSize = 16,
fontStyle = (FontStyle)1,
alignment = (TextAnchor)3
};
titleStyle.normal.textColor = textColor;
helpTitle = new GUIStyle(titleStyle)
{
fontSize = 17
};
onBtn = Btn(new Color(0.46f, 0.73f, 0f), new Color(0.52f, 0.8f, 0.05f), Color.black, (FontStyle)1);
offBtn = Btn(new Color(0.25f, 0.27f, 0.3f), new Color(0.32f, 0.35f, 0.39f), Color.white, (FontStyle)1);
btn = Btn(new Color(0.18f, 0.2f, 0.23f), new Color(0.26f, 0.29f, 0.33f), Color.white, (FontStyle)0);
activeBtn = Btn(new Color(0.46f, 0.73f, 0f, 0.85f), new Color(0.46f, 0.73f, 0f, 0.95f), Color.black, (FontStyle)1);
header = new GUIStyle(GUI.skin.label)
{
fontSize = 13,
fontStyle = (FontStyle)1
};
header.normal.textColor = textColor;
label = new GUIStyle(GUI.skin.label)
{
fontSize = 12,
alignment = (TextAnchor)3
};
label.normal.textColor = textColor2;
valueLabel = new GUIStyle(label)
{
alignment = (TextAnchor)5
};
dimLabel = new GUIStyle(label);
dimLabel.normal.textColor = new Color(0.5f, 0.52f, 0.55f);
statusLabel = new GUIStyle(label)
{
fontStyle = (FontStyle)1
};
statusLabel.normal.textColor = textColor;
toggle = new GUIStyle(GUI.skin.toggle)
{
fontSize = 12
};
toggle.normal.textColor = textColor2;
toggle.onNormal.textColor = Color.white;
toggle.hover.textColor = Color.white;
toggle.onHover.textColor = Color.white;
textField = new GUIStyle(GUI.skin.textField)
{
fontSize = 12,
alignment = (TextAnchor)3
};
textField.normal.background = Tex(new Color(0.12f, 0.13f, 0.15f));
textField.focused.background = Tex(new Color(0.16f, 0.18f, 0.21f));
textField.normal.textColor = textColor2;
textField.focused.textColor = Color.white;
helpBody = new GUIStyle(GUI.skin.label)
{
fontSize = 13,
wordWrap = true,
richText = true,
alignment = (TextAnchor)0
};
helpBody.normal.textColor = textColor2;
stylesReady = true;
}
}
private static GUIStyle Bg(GUIStyle source, Color c)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Expected O, but got Unknown
GUIStyle val = new GUIStyle(source);
val.normal.background = Tex(c);
return val;
}
private static GUIStyle Btn(Color normal, Color hover, Color textColor, FontStyle font)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Expected O, but got Unknown
GUIStyle val = new GUIStyle(GUI.skin.button)
{
fontSize = 12,
fontStyle = font,
alignment = (TextAnchor)4
};
Texture2D background = Tex(normal);
Texture2D background2 = Tex(hover);
val.normal.background = background;
val.hover.background = background2;
val.active.background = background2;
val.focused.background = background;
val.normal.textColor = textColor;
val.hover.textColor = textColor;
val.active.textColor = textColor;
val.focused.textColor = textColor;
return val;
}
private static Texture2D Tex(Color c)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Expected O, but got Unknown
Texture2D val = new Texture2D(1, 1)
{
hideFlags = (HideFlags)32
};
val.SetPixel(0, 0, c);
val.Apply();
return val;
}
}
internal static class RTXHelpText
{
private const string H = "<size=15><b><color=#8CD91A>";
private const string E = "</color></b></size>\n";
public const string About = "<size=15><b><color=#8CD91A>So what is this?</color></b></size>\nGB RTX is a graphics mod for Gang Beasts. It makes the game look a lot more realistic, or a lot more cinematic, depending on how far you push it. You get proper contact shadows in corners and under the beasts, glow on bright lights, film-style colours, a camera that can blur the background like a real lens, motion blur, nicer shadows, fog, and better anti-aliasing. Everything lives in the little bar at the top of the screen, so you can keep it subtle or go all out. Customize it to your liking!\n\n<size=15><b><color=#8CD91A>How it works</color></b></size>\nGang Beasts runs on Unity's URP renderer, and URP already ships with a bunch of high end effects that the game just doesn't use. This mod switches those on and tunes them while you play. It adds a post-processing volume for the camera effects, plugs URP's ambient occlusion into the renderer, bumps up the shadow settings, and lets you change the render resolution with AMD FSR or supersampling. Since it's all stuff the engine already supports, it works on every map and doesn't mess with the game's own shaders.\n\n<size=15><b><color=#8CD91A>Is it actually RTX?</color></b></size>\nNope, the name is a bit of a joke. Real ray tracing have to be built into the game with NVIDIA's tools, and URP doesn't support either, so no mod can add them. What you're getting is about as realistic as this engine can look. Upside: it works on any GPU, not just NVIDIA cards.\n\n<size=15><b><color=#8CD91A>Will it break anything?</color></b></size>\nIt shouldn't. It only changes how the game is drawn. Gameplay, physics, saves and online stuff aren't touched. Turn it off and everything it changed goes back to how the game had it. If something does go wrong while it's applying the effects, it logs the error and turns itself off instead of crashing.\n\n<size=15><b><color=#8CD91A>Where's my stuff saved?</color></b></size>\nYour settings go in UserData\\GBRTX.json and your save slots in UserData\\GBRTX_Slots.json, both inside the game folder. In-game the mod makes two objects, \"[Mod] RTX\" and \"[Mod] RTX Volume\", and they stick around between maps.";
public const string Usage = "<size=15><b><color=#8CD91A>Getting started</color></b></size>\nHit F10 (or click the OFF/ON button at the top) to turn it on. You can do this mid-match, it's fine. The arrow opens the settings and Help opens this window. F11 hides the bar if you want clean screenshots or recordings. Your mouse shows up while a window is open and goes back to normal when you close it.\n\n<size=15><b><color=#8CD91A>Presets</color></b></size>\nEasiest way to start. Low is for weaker PCs. Medium and High are a good middle ground. Ultra cranks most things up. Photoreal turns literally everything on, depth of field and motion blur included, so it looks the best but it's also the heaviest. Touch any slider and it switches to Custom, so feel free to pick a preset and tweak from there.\n\nAnd then there's Shitty. It does the exact opposite: the game renders at 10% of your screen and gets blown back up into chunky pixels, textures turn to mush, models drop to their lowest detail, and shadows, anti-aliasing and every post effect are switched off, the game's own ones included. It's a joke preset, have fun with it. Pick any other preset to get the game back.\n\n<size=15><b><color=#8CD91A>Save slots</color></b></size>\nYou've got 10 of them at the top of the settings. Click a name to rename it, Save stores what you've got right now, Load brings it back, and Clear empties it. The green Load button is the slot you're currently on. Loading a slot won't turn the mod on or off, it just swaps the look.\n\n<size=15><b><color=#8CD91A>Image quality</color></b></size>\nNative is your normal resolution. The FSR modes render lower and upscale with AMD FSR. Quality looks almost the same as native, Balanced and Performance trade more detail for more FPS. FSR sharpness is up to you. SSAA 1.5x and 2x go the other way and render above your resolution, which looks super clean but is really expensive. SMAA smooths out jagged edges. Native + SMAA is good for most PCs.\n\n<size=15><b><color=#8CD91A>Ambient occlusion</color></b></size>\nThis is the one that makes the biggest difference. It darkens spots light can't really reach, like corners, the floor under a beast, or where two things touch. Intensity is how dark, Radius is how far it spreads, Direct light controls how much it shows up in sunlight, and Samples smooths it out. Full resolution looks sharper but costs FPS.\n\n<size=15><b><color=#8CD91A>Bloom and colour</color></b></size>\nBloom makes bright stuff glow. Intensity is how strong, Threshold is how bright something has to be before it glows, Scatter is how wide the glow spreads. ACES tonemapping makes bright and dark areas look more like a film camera and stops highlights from blowing out. Exposure, Contrast, Saturation and Temperature do what you'd expect. Cinematic grade gives it that movie look with bluish shadows and warm highlights.\n\n<size=15><b><color=#8CD91A>Camera</color></b></size>\nDepth of field blurs whatever's out of focus. With Auto focus on, it focuses on whatever's in the middle of the screen and slowly pulls focus as things move around. Lower Aperture numbers mean a blurrier background, and Focal length changes how strong it is. Turn Auto focus off and you can set the distance yourself with Manual focus. Motion blur smears fast camera moves. Keep it low if it gets hard to see what's going on.\n\n<size=15><b><color=#8CD91A>Lens, fog and shadows</color></b></size>\nVignette darkens the corners of the screen and Vignette softness makes that more or less gradual. Chromatic aberration adds a bit of colour fringing like a cheap lens, Lens distortion bends the image, and Film grain adds some noise. Fog adds haze so big maps feel deeper. Turn the density down if a map looks washed out. Soft shadows makes shadows smoother and sharper, and Shadow distance is how far away they still get drawn.\n\n<size=15><b><color=#8CD91A>Low FPS?</color></b></size>\nTry these roughly in this order: switch to an FSR mode, turn off Full resolution on ambient occlusion, turn off depth of field and motion blur, lower Shadow distance, or just drop to a lower preset. SSAA is the most expensive thing in here.\n\n<size=15><b><color=#8CD91A>Something looks off</color></b></size>\nToggle it off and on with F10, or click a preset to reset everything. If ambient occlusion is acting weird, just untick it. Errors end up in MelonLoader\\Latest.log, look for lines from GB RTX. Deleting UserData\\GBRTX.json resets your settings but keeps your save slots.";
}
public class RTXRenderer
{
private GameObject volumeGo;
private Volume volume;
private VolumeProfile profile;
private Bloom bloom;
private Tonemapping tonemap;
private ColorAdjustments color;
private WhiteBalance whiteBalance;
private SplitToning split;
private LiftGammaGain lgg;
private ShadowsMidtonesHighlights smh;
private DepthOfField dof;
private MotionBlur motionBlur;
private Vignette vignette;
private ChromaticAberration chroma;
private LensDistortion lens;
private FilmGrain grain;
private float focus = 10f;
private Camera cam;
private IntPtr camPtr;
private UniversalAdditionalCameraData camData;
private bool oldPost;
private bool oldNeedsDepth;
private AntialiasingMode oldAa;
private AntialiasingQuality oldAaQuality;
private UniversalRenderPipelineAsset urp;
private bool urpSaved;
private float oldShadowDist;
private float oldRenderScale;
private float oldFsrSharpness;
private int oldCascades;
private int oldShadowRes;
private bool oldSoftShadows;
private bool oldHdr;
private bool oldFsrOverride;
private bool oldDepthTex;
private UpscalingFilterSelection oldUpscaler;
private ScriptableRendererData rendererData;
private ScreenSpaceAmbientOcclusion ssao;
private bool ssaoIsOurs;
private bool ssaoSaved;
private bool oldSsaoActive;
private bool oldSsaoDownsample;
private float oldSsaoIntensity;
private float oldSsaoRadius;
private float oldSsaoDirect;
private int oldSsaoSamples;
private DepthSource oldSsaoSource;
private NormalQuality oldSsaoNormals;
private bool fogSaved;
private bool oldFog;
private FogMode oldFogMode;
private float oldFogDensity;
private Color oldFogColor;
private bool qualitySaved;
private int oldMipLimit;
private int oldMaxLod;
private int oldFrameRate;
private int oldVSync;
private float oldLodBias;
private AnisotropicFiltering oldAniso;
private readonly Dictionary<IntPtr, (Light light, LightShadows shadows)> lights = new Dictionary<IntPtr, (Light, LightShadows)>();
private float nextLightScan;
public bool Active { get; private set; }
public void Apply(RTXSettings s)
{
Active = true;
SetupVolume();
UpdateUrp(s);
UpdateCamera(s);
UpdateVolume(s);
UpdateSsao(s);
UpdateFog(s);
UpdateQuality(s);
if (Time.unscaledTime >= nextLightScan)
{
nextLightScan = Time.unscaledTime + 1f;
UpdateLights(s);
}
}
public void Restore()
{
if (Active)
{
Active = false;
if ((Object)(object)volume != (Object)null)
{
((Behaviour)volume).enabled = false;
}
RestoreSsao();
RestoreCamera();
RestoreUrp();
RestoreFog();
RestoreLights();
RestoreQuality();
}
}
public void Destroy()
{
Restore();
if ((Object)(object)volumeGo != (Object)null)
{
Object.Destroy((Object)(object)volumeGo);
}
volumeGo = null;
volume = null;
profile = null;
}
public void OnSceneChanged()
{
fogSaved = false;
lights.Clear();
}
private void SetupVolume()
{
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Expected O, but got Unknown
if ((Object)(object)volumeGo != (Object)null && (Object)(object)volume != (Object)null && (Object)(object)profile != (Object)null)
{
((Behaviour)volume).enabled = true;
return;
}
volumeGo = new GameObject("[Mod] RTX Volume")
{
hideFlags = (HideFlags)32
};
Object.DontDestroyOnLoad((Object)(object)volumeGo);
volume = volumeGo.AddComponent<Volume>();
volume.isGlobal = true;
volume.priority = 1000f;
volume.weight = 1f;
profile = ((Il2CppObjectBase)ScriptableObject.CreateInstance(Il2CppType.Of<VolumeProfile>())).Cast<VolumeProfile>();
((Object)profile).hideFlags = (HideFlags)32;
volume.sharedProfile = profile;
bloom = Add<Bloom>();
tonemap = Add<Tonemapping>();
color = Add<ColorAdjustments>();
whiteBalance = Add<WhiteBalance>();
split = Add<SplitToning>();
lgg = Add<LiftGammaGain>();
smh = Add<ShadowsMidtonesHighlights>();
dof = Add<DepthOfField>();
motionBlur = Add<MotionBlur>();
vignette = Add<Vignette>();
chroma = Add<ChromaticAberration>();
lens = Add<LensDistortion>();
grain = Add<FilmGrain>();
}
private T Add<T>() where T : VolumeComponent
{
return ((Il2CppObjectBase)profile.Add(Il2CppType.Of<T>(), false)).Cast<T>();
}
private void UpdateVolume(RTXSettings s)
{
((VolumeComponent)bloom).active = s.Bloom && s.BloomIntensity > 0f;
Set((VolumeParameter<float>)(object)bloom.intensity, Mathf.Max(0f, s.BloomIntensity));
Set((VolumeParameter<float>)(object)bloom.threshold, Mathf.Max(0f, s.BloomThreshold));
Set((VolumeParameter<float>)(object)bloom.scatter, Mathf.Clamp01(s.BloomScatter));
Set((VolumeParameter<bool>)(object)bloom.highQualityFiltering, v: true);
((VolumeComponent)tonemap).active = s.AcesTonemapping;
((VolumeParameter)tonemap.mode).overrideState = true;
((VolumeParameter<TonemappingMode>)(object)tonemap.mode).value = (TonemappingMode)2;
((VolumeComponent)color).active = s.Exposure != 0f || s.Contrast != 0f || s.Saturation != 0f;
Set((VolumeParameter<float>)(object)color.postExposure, s.Exposure);
Set((VolumeParameter<float>)(object)color.contrast, Mathf.Clamp(s.Contrast, -100f, 100f));
Set((VolumeParameter<float>)(object)color.saturation, Mathf.Clamp(s.Saturation, -100f, 100f));
((VolumeComponent)whiteBalance).active = Mathf.Abs(s.Temperature) > 0.01f;
Set((VolumeParameter<float>)(object)whiteBalance.temperature, Mathf.Clamp(s.Temperature, -100f, 100f));
Grade(Mathf.Clamp01(s.CinematicGrade));
UpdateDof(s);
((VolumeComponent)motionBlur).active = s.MotionBlur && s.MotionBlurIntensity > 0f;
((VolumeParameter)motionBlur.mode).overrideState = true;
((VolumeParameter<MotionBlurMode>)(object)motionBlur.mode).value = (MotionBlurMode)0;
((VolumeParameter)motionBlur.quality).overrideState = true;
((VolumeParameter<MotionBlurQuality>)(object)motionBlur.quality).value = (MotionBlurQuality)2;
Set((VolumeParameter<float>)(object)motionBlur.intensity, Mathf.Clamp01(s.MotionBlurIntensity));
Set((VolumeParameter<float>)(object)motionBlur.clamp, 0.05f);
((VolumeComponent)vignette).active = s.Vignette > 0f;
Set((VolumeParameter<float>)(object)vignette.intensity, Mathf.Clamp01(s.Vignette));
Set((VolumeParameter<float>)(object)vignette.smoothness, Mathf.Clamp(s.VignetteSmoothness, 0.01f, 1f));
((VolumeComponent)chroma).active = s.ChromaticAberration > 0f;
Set((VolumeParameter<float>)(object)chroma.intensity, Mathf.Clamp01(s.ChromaticAberration));
((VolumeComponent)lens).active = Mathf.Abs(s.LensDistortion) > 0.001f;
Set((VolumeParameter<float>)(object)lens.intensity, Mathf.Clamp(s.LensDistortion, -1f, 1f));
Set((VolumeParameter<float>)(object)lens.scale, 1f - Mathf.Abs(s.LensDistortion) * 0.15f);
((VolumeComponent)grain).active = s.FilmGrain > 0f;
Set((VolumeParameter<float>)(object)grain.intensity, Mathf.Clamp01(s.FilmGrain));
}
private void Grade(float g)
{
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
//IL_0112: Unknown result type (might be due to invalid IL or missing references)
//IL_0153: Unknown result type (might be due to invalid IL or missing references)
//IL_017e: Unknown result type (might be due to invalid IL or missing references)
//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
bool flag = g > 0.001f;
SplitToning obj = split;
LiftGammaGain obj2 = lgg;
bool flag2 = (((VolumeComponent)smh).active = flag);
bool active = (((VolumeComponent)obj2).active = flag2);
((VolumeComponent)obj).active = active;
if (flag)
{
Color val = default(Color);
((Color)(ref val))..ctor(0.5f, 0.5f, 0.5f);
Set((VolumeParameter<Color>)(object)split.shadows, Color.Lerp(val, new Color(0.36f, 0.5f, 0.62f), g));
Set((VolumeParameter<Color>)(object)split.highlights, Color.Lerp(val, new Color(0.66f, 0.53f, 0.4f), g));
Set((VolumeParameter<float>)(object)split.balance, -10f * g);
Set((VolumeParameter<Vector4>)(object)lgg.lift, new Vector4(1f - 0.02f * g, 1f, 1f + 0.03f * g, -0.02f * g));
Set((VolumeParameter<Vector4>)(object)lgg.gamma, new Vector4(1f, 1f, 1f, 0f));
Set((VolumeParameter<Vector4>)(object)lgg.gain, new Vector4(1f + 0.03f * g, 1f + 0.01f * g, 1f - 0.02f * g, 0f));
Set((VolumeParameter<Vector4>)(object)smh.shadows, new Vector4(1f, 1f, 1f, -0.08f * g));
Set((VolumeParameter<Vector4>)(object)smh.midtones, new Vector4(1f, 1f, 1f, 0f));
Set((VolumeParameter<Vector4>)(object)smh.highlights, new Vector4(1f, 1f, 1f, 0.03f * g));
}
}
private void UpdateDof(RTXSettings s)
{
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
((VolumeComponent)dof).active = s.DepthOfField;
if (s.DepthOfField)
{
float num = s.DofManualDistance;
if (s.DofAutoFocus && (Object)(object)cam != (Object)null)
{
RaycastHit val = default(RaycastHit);
num = ((Physics.Raycast(cam.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0f)), ref val, 1000f, -1, (QueryTriggerInteraction)1) && ((RaycastHit)(ref val)).distance > 0.3f) ? ((RaycastHit)(ref val)).distance : focus);
}
focus = Mathf.Lerp(focus, Mathf.Max(0.1f, num), 1f - Mathf.Exp(-6f * Time.unscaledDeltaTime));
((VolumeParameter)dof.mode).overrideState = true;
((VolumeParameter<DepthOfFieldMode>)(object)dof.mode).value = (DepthOfFieldMode)2;
Set((VolumeParameter<float>)(object)dof.focusDistance, focus);
Set((VolumeParameter<float>)(object)dof.aperture, Mathf.Clamp(s.DofAperture, 1f, 32f));
Set((VolumeParameter<float>)(object)dof.focalLength, Mathf.Clamp(s.DofFocalLength, 1f, 300f));
((VolumeParameter)dof.bladeCount).overrideState = true;
((VolumeParameter<int>)(object)dof.bladeCount).value = 7;
Set((VolumeParameter<float>)(object)dof.bladeCurvature, 0.85f);
}
}
private static void Set(VolumeParameter<float> p, float v)
{
((VolumeParameter)p).overrideState = true;
p.value = v;
}
private static void Set(VolumeParameter<bool> p, bool v)
{
((VolumeParameter)p).overrideState = true;
p.value = v;
}
private static void Set(VolumeParameter<Color> p, Color v)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
((VolumeParameter)p).overrideState = true;
p.value = v;
}
private static void Set(VolumeParameter<Vector4> p, Vector4 v)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
((VolumeParameter)p).overrideState = true;
p.value = v;
}
private void UpdateCamera(RTXSettings s)
{
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: Unknown result type (might be due to invalid IL or missing references)
Camera main = Camera.main;
if ((Object)(object)main == (Object)null)
{
return;
}
if ((Object)(object)cam == (Object)null || ((Il2CppObjectBase)main).Pointer != camPtr)
{
RestoreCamera();
camData = ((Component)main).GetComponent<UniversalAdditionalCameraData>();
if ((Object)(object)camData == (Object)null)
{
return;
}
cam = main;
camPtr = ((Il2CppObjectBase)main).Pointer;
oldPost = camData.renderPostProcessing;
oldAa = camData.antialiasing;
oldAaQuality = camData.antialiasingQuality;
oldNeedsDepth = camData.requiresDepthTexture;
}
camData.renderPostProcessing = AnyPost(s);
camData.requiresDepthTexture = s.DepthOfField || oldNeedsDepth;
camData.antialiasing = (AntialiasingMode)(s.Antialiasing ? 2 : ((int)oldAa));
camData.antialiasingQuality = (AntialiasingQuality)(s.Antialiasing ? 2 : ((int)oldAaQuality));
}
private static bool AnyPost(RTXSettings s)
{
if ((!s.Bloom || !(s.BloomIntensity > 0f)) && !s.AcesTonemapping && s.Exposure == 0f && s.Contrast == 0f && s.Saturation == 0f && !(Mathf.Abs(s.Temperature) > 0.01f) && !(s.CinematicGrade > 0.001f) && !s.DepthOfField && (!s.MotionBlur || !(s.MotionBlurIntensity > 0f)) && !(s.Vignette > 0f) && !(s.ChromaticAberration > 0f) && !(Mathf.Abs(s.LensDistortion) > 0.001f))
{
return s.FilmGrain > 0f;
}
return true;
}
private void RestoreCamera()
{
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)cam != (Object)null && (Object)(object)camData != (Object)null)
{
camData.renderPostProcessing = oldPost;
camData.antialiasing = oldAa;
camData.antialiasingQuality = oldAaQuality;
camData.requiresDepthTexture = oldNeedsDepth;
}
cam = null;
camData = null;
camPtr = IntPtr.Zero;
}
private void UpdateUrp(RTXSettings s)
{
//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)urp == (Object)null)
{
RenderPipelineAsset currentRenderPipeline = GraphicsSettings.currentRenderPipeline;
urp = ((currentRenderPipeline != null) ? ((Il2CppObjectBase)currentRenderPipeline).TryCast<UniversalRenderPipelineAsset>() : null);
urpSaved = false;
if ((Object)(object)urp == (Object)null)
{
return;
}
}
if (!urpSaved)
{
oldShadowDist = urp.shadowDistance;
oldCascades = urp.shadowCascadeCount;
oldShadowRes = urp.mainLightShadowmapResolution;
oldSoftShadows = urp.supportsSoftShadows;
oldHdr = urp.supportsHDR;
oldRenderScale = urp.renderScale;
oldUpscaler = urp.upscalingFilter;
oldFsrOverride = urp.fsrOverrideSharpness;
oldFsrSharpness = urp.fsrSharpness;
oldDepthTex = urp.supportsCameraDepthTexture;
urpSaved = true;
}
bool flag = s.UpscaleMode == RTXSettings.Upscaler.Potato;
urp.supportsHDR = !flag;
urp.supportsCameraDepthTexture = s.DepthOfField || oldDepthTex;
float renderScale = s.RenderScale;
urp.renderScale = renderScale;
urp.upscalingFilter = (UpscalingFilterSelection)((flag || (s.PixelatedUpscale && renderScale < 0.999f)) ? 2 : ((renderScale < 0.999f) ? 3 : 0));
urp.fsrOverrideSharpness = true;
urp.fsrSharpness = Mathf.Clamp01(s.FsrSharpness);
if (s.NoShadows)
{
urp.supportsSoftShadows = false;
urp.mainLightShadowmapResolution = 256;
urp.shadowCascadeCount = 1;
urp.shadowDistance = 0f;
}
else if (s.EnhancedShadows)
{
urp.supportsSoftShadows = true;
urp.mainLightShadowmapResolution = 4096;
urp.shadowCascadeCount = 4;
urp.shadowDistance = Mathf.Max(oldShadowDist, s.ShadowDistance);
}
else
{
urp.supportsSoftShadows = oldSoftShadows;
urp.mainLightShadowmapResolution = oldShadowRes;
urp.shadowCascadeCount = oldCascades;
urp.shadowDistance = oldShadowDist;
}
}
private void RestoreUrp()
{
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)urp != (Object)null && urpSaved)
{
urp.shadowDistance = oldShadowDist;
urp.shadowCascadeCount = oldCascades;
urp.mainLightShadowmapResolution = oldShadowRes;
urp.supportsSoftShadows = oldSoftShadows;
urp.supportsHDR = oldHdr;
urp.renderScale = oldRenderScale;
urp.upscalingFilter = oldUpscaler;
urp.fsrOverrideSharpness = oldFsrOverride;
urp.fsrSharpness = oldFsrSharpness;
urp.supportsCameraDepthTexture = oldDepthTex;
}
urpSaved = false;
urp = null;
}
private void UpdateSsao(RTXSettings s)
{
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)urp == (Object)null)
{
return;
}
if (rendererData == null)
{
rendererData = urp.scriptableRendererData;
}
if ((Object)(object)rendererData == (Object)null)
{
return;
}
if ((Object)(object)ssao == (Object)null)
{
ssao = FindSsao(rendererData);
if ((Object)(object)ssao != (Object)null && !ssaoSaved)
{
ScreenSpaceAmbientOcclusionSettings settings = ssao.m_Settings;
oldSsaoActive = ((ScriptableRendererFeature)ssao).isActive;
oldSsaoIntensity = settings.Intensity;
oldSsaoRadius = settings.Radius;
oldSsaoDirect = settings.DirectLightingStrength;
oldSsaoSamples = settings.SampleCount;
oldSsaoDownsample = settings.Downsample;
oldSsaoSource = settings.Source;
oldSsaoNormals = settings.NormalSamples;
ssaoSaved = true;
ssaoIsOurs = false;
}
else if ((Object)(object)ssao == (Object)null && s.Ssao)
{
ssao = ((Il2CppObjectBase)ScriptableObject.CreateInstance(Il2CppType.Of<ScreenSpaceAmbientOcclusion>())).Cast<ScreenSpaceAmbientOcclusion>();
((Object)ssao).name = "GBRTX SSAO";
((Object)ssao).hideFlags = (HideFlags)32;
SsaoSettings(s);
rendererData.rendererFeatures.Add((ScriptableRendererFeature)(object)ssao);
rendererData.SetDirty();
ssaoIsOurs = true;
}
}
if (!((Object)(object)ssao == (Object)null))
{
SsaoSettings(s);
if (((ScriptableRendererFeature)ssao).isActive != s.Ssao)
{
((ScriptableRendererFeature)ssao).SetActive(s.Ssao);
}
}
}
private void SsaoSettings(RTXSettings s)
{
ScreenSpaceAmbientOcclusionSettings settings = ssao.m_Settings;
if (settings != null)
{
settings.Intensity = Mathf.Clamp(s.SsaoIntensity, 0f, 4f);
settings.Radius = Mathf.Clamp(s.SsaoRadius, 0.05f, 2f);
settings.DirectLightingStrength = Mathf.Clamp01(s.SsaoDirectLighting);
settings.SampleCount = Mathf.Clamp(s.SsaoSamples, 2, 20);
settings.Downsample = !s.SsaoFullResolution;
settings.Source = (DepthSource)1;
settings.NormalSamples = (NormalQuality)2;
}
}
private static ScreenSpaceAmbientOcclusion FindSsao(ScriptableRendererData data)
{
List<ScriptableRendererFeature> rendererFeatures = data.rendererFeatures;
if (rendererFeatures == null)
{
return null;
}
for (int i = 0; i < rendererFeatures.Count; i++)
{
ScriptableRendererFeature obj = rendererFeatures[i];
ScreenSpaceAmbientOcclusion val = ((obj != null) ? ((Il2CppObjectBase)obj).TryCast<ScreenSpaceAmbientOcclusion>() : null);
if ((Object)(object)val != (Object)null)
{
return val;
}
}
return null;
}
private void RestoreSsao()
{
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)ssao != (Object)null)
{
if (ssaoIsOurs)
{
if ((Object)(object)rendererData != (Object)null)
{
rendererData.rendererFeatures.Remove((ScriptableRendererFeature)(object)ssao);
rendererData.SetDirty();
}
Object.Destroy((Object)(object)ssao);
}
else if (ssaoSaved)
{
ScreenSpaceAmbientOcclusionSettings settings = ssao.m_Settings;
if (settings != null)
{
settings.Intensity = oldSsaoIntensity;
settings.Radius = oldSsaoRadius;
settings.DirectLightingStrength = oldSsaoDirect;
settings.SampleCount = oldSsaoSamples;
settings.Downsample = oldSsaoDownsample;
settings.Source = oldSsaoSource;
settings.NormalSamples = oldSsaoNormals;
}
((ScriptableRendererFeature)ssao).SetActive(oldSsaoActive);
}
}
ssao = null;
ssaoIsOurs = false;
ssaoSaved = false;
rendererData = null;
}
private void UpdateFog(RTXSettings s)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
if (!fogSaved)
{
oldFog = RenderSettings.fog;
oldFogMode = RenderSettings.fogMode;
oldFogDensity = RenderSettings.fogDensity;
oldFogColor = RenderSettings.fogColor;
fogSaved = true;
}
if (!s.Fog)
{
PutFogBack();
return;
}
RenderSettings.fog = true;
RenderSettings.fogMode = (FogMode)3;
RenderSettings.fogDensity = Mathf.Max(0f, s.FogDensity);
RenderSettings.fogColor = new Color(s.FogR, s.FogG, s.FogB);
}
private void RestoreFog()
{
if (fogSaved)
{
PutFogBack();
}
fogSaved = false;
}
private void PutFogBack()
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
RenderSettings.fog = oldFog;
RenderSettings.fogMode = oldFogMode;
RenderSettings.fogDensity = oldFogDensity;
RenderSettings.fogColor = oldFogColor;
}
private void UpdateQuality(RTXSettings s)
{
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
if (!qualitySaved)
{
oldMipLimit = QualitySettings.masterTextureLimit;
oldLodBias = QualitySettings.lodBias;
oldMaxLod = QualitySettings.maximumLODLevel;
oldAniso = QualitySettings.anisotropicFiltering;
oldFrameRate = Application.targetFrameRate;
oldVSync = QualitySettings.vSyncCount;
qualitySaved = true;
}
QualitySettings.masterTextureLimit = ((s.TextureMipLimit > 0) ? Mathf.Clamp(s.TextureMipLimit, 0, 4) : oldMipLimit);
if (s.LowDetailModels)
{
QualitySettings.lodBias = 0.01f;
QualitySettings.anisotropicFiltering = (AnisotropicFiltering)0;
}
else
{
QualitySettings.lodBias = oldLodBias;
QualitySettings.maximumLODLevel = oldMaxLod;
QualitySettings.anisotropicFiltering = oldAniso;
}
if (s.FpsCap > 0)
{
QualitySettings.vSyncCount = 0;
Application.targetFrameRate = Mathf.Max(5, s.FpsCap);
}
else
{
QualitySettings.vSyncCount = oldVSync;
Application.targetFrameRate = oldFrameRate;
}
}
private void RestoreQuality()
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
if (qualitySaved)
{
QualitySettings.masterTextureLimit = oldMipLimit;
QualitySettings.lodBias = oldLodBias;
QualitySettings.maximumLODLevel = oldMaxLod;
QualitySettings.anisotropicFiltering = oldAniso;
QualitySettings.vSyncCount = oldVSync;
Application.targetFrameRate = oldFrameRate;
qualitySaved = false;
}
}
private void UpdateLights(RTXSettings s)
{
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Invalid comparison between Unknown and I4
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Invalid comparison between Unknown and I4
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
if (!s.EnhancedShadows)
{
RestoreLights();
return;
}
foreach (Light item in Object.FindObjectsOfType<Light>())
{
if (!((Object)(object)item == (Object)null) && (int)item.type == 1 && (int)item.shadows == 1 && !lights.ContainsKey(((Il2CppObjectBase)item).Pointer))
{
lights[((Il2CppObjectBase)item).Pointer] = (item, item.shadows);
item.shadows = (LightShadows)2;
}
}
}
private void RestoreLights()
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
foreach (var (val, shadows) in lights.Values)
{
if ((Object)(object)val != (Object)null)
{
val.shadows = shadows;
}
}
lights.Clear();
}
}
public class RTXSettings
{
public enum Preset
{
Shitty,
Low,
Medium,
High,
Ultra,
Photoreal,
Custom
}
public enum Upscaler
{
Native,
FsrQuality,
FsrBalanced,
FsrPerformance,
Supersample15,
Supersample2,
Potato,
Custom
}
internal static readonly JsonSerializerOptions Json = new JsonSerializerOptions
{
WriteIndented = true,
Converters = { (JsonConverter)new JsonStringEnumConverter() }
};
public bool Enabled { get; set; }
public Preset CurrentPreset { get; set; } = Preset.High;
public Upscaler UpscaleMode { get; set; }
public float FsrSharpness { get; set; } = 0.8f;
public bool Antialiasing { get; set; } = true;
public int ScreenPercent { get; set; } = 100;
public bool PixelatedUpscale { get; set; }
public bool Ssao { get; set; } = true;
public float SsaoIntensity { get; set; } = 1.2f;
public float SsaoRadius { get; set; } = 0.35f;
public float SsaoDirectLighting { get; set; } = 0.35f;
public int SsaoSamples { get; set; } = 8;
public bool SsaoFullResolution { get; set; }
public bool Bloom { get; set; } = true;
public float BloomIntensity { get; set; } = 0.8f;
public float BloomThreshold { get; set; } = 0.95f;
public float BloomScatter { get; set; } = 0.7f;
public bool AcesTonemapping { get; set; } = true;
public float Exposure { get; set; } = 0.15f;
public float Contrast { get; set; } = 12f;
public float Saturation { get; set; } = 8f;
public float Temperature { get; set; } = 6f;
public float CinematicGrade { get; set; } = 0.35f;
public bool DepthOfField { get; set; }
public bool DofAutoFocus { get; set; } = true;
public float DofAperture { get; set; } = 4f;
public float DofFocalLength { get; set; } = 50f;
public float DofManualDistance { get; set; } = 12f;
public bool MotionBlur { get; set; }
public float MotionBlurIntensity { get; set; } = 0.35f;
public float Vignette { get; set; } = 0.3f;
public float VignetteSmoothness { get; set; } = 0.45f;
public float ChromaticAberration { get; set; } = 0.12f;
public float LensDistortion { get; set; }
public float FilmGrain { get; set; } = 0.15f;
public bool Fog { get; set; } = true;
public float FogDensity { get; set; } = 0.004f;
public float FogR { get; set; } = 0.62f;
public float FogG { get; set; } = 0.7f;
public float FogB { get; set; } = 0.8f;
public bool EnhancedShadows { get; set; } = true;
public float ShadowDistance { get; set; } = 120f;
public bool NoShadows { get; set; }
public int TextureMipLimit { get; set; }
public bool LowDetailModels { get; set; }
public int FpsCap { get; set; }
[JsonIgnore]
public float RenderScale => UpscaleMode switch
{
Upscaler.FsrQuality => 0.77f,
Upscaler.FsrBalanced => 0.67f,
Upscaler.FsrPerformance => 0.5f,
Upscaler.Supersample15 => 1.5f,
Upscaler.Supersample2 => 2f,
Upscaler.Potato => 0.1f,
Upscaler.Custom => (float)Mathf.Clamp(ScreenPercent, 10, 200) / 100f,
_ => 1f,
};
private static string FilePath => Path.Combine(MelonEnvironment.UserDataDirectory, "GBRTX.json");
public static string UpscalerLabel(Upscaler u)
{
return u switch
{
Upscaler.FsrQuality => "FSR Quality",
Upscaler.FsrBalanced => "FSR Balanced",
Upscaler.FsrPerformance => "FSR Perf.",
Upscaler.Supersample15 => "SSAA 1.5x",
Upscaler.Supersample2 => "SSAA 2x",
Upscaler.Potato => "Potato",
Upscaler.Custom => "Custom",
_ => "Native",
};
}
public static RTXSettings FromPreset(Preset preset)
{
RTXSettings rTXSettings = new RTXSettings
{
CurrentPreset = preset
};
switch (preset)
{
case Preset.Shitty:
rTXSettings.UpscaleMode = Upscaler.Potato;
rTXSettings.FsrSharpness = 0f;
rTXSettings.Antialiasing = false;
rTXSettings.Ssao = false;
rTXSettings.Bloom = false;
rTXSettings.AcesTonemapping = false;
rTXSettings.Exposure = 0f;
rTXSettings.Contrast = 0f;
rTXSettings.Saturation = 0f;
rTXSettings.Temperature = 0f;
rTXSettings.CinematicGrade = 0f;
rTXSettings.DepthOfField = false;
rTXSettings.MotionBlur = false;
rTXSettings.Vignette = 0f;
rTXSettings.ChromaticAberration = 0f;
rTXSettings.LensDistortion = 0f;
rTXSettings.FilmGrain = 0f;
rTXSettings.Fog = false;
rTXSettings.EnhancedShadows = false;
rTXSettings.NoShadows = true;
rTXSettings.TextureMipLimit = 4;
rTXSettings.LowDetailModels = true;
break;
case Preset.Low:
rTXSettings.UpscaleMode = Upscaler.FsrBalanced;
rTXSettings.Ssao = false;
rTXSettings.BloomIntensity = 0.5f;
rTXSettings.Contrast = 6f;
rTXSettings.Saturation = 4f;
rTXSettings.CinematicGrade = 0f;
rTXSettings.Vignette = 0.2f;
rTXSettings.ChromaticAberration = 0f;
rTXSettings.FilmGrain = 0f;
rTXSettings.Fog = false;
rTXSettings.EnhancedShadows = false;
break;
case Preset.Medium:
rTXSettings.UpscaleMode = Upscaler.FsrQuality;
rTXSettings.SsaoIntensity = 0.9f;
rTXSettings.SsaoSamples = 6;
rTXSettings.BloomIntensity = 0.65f;
rTXSettings.Contrast = 9f;
rTXSettings.CinematicGrade = 0.2f;
rTXSettings.ChromaticAberration = 0.06f;
rTXSettings.FilmGrain = 0.08f;
rTXSettings.FogDensity = 0.003f;
rTXSettings.ShadowDistance = 90f;
break;
case Preset.Ultra:
rTXSettings.SsaoIntensity = 1.5f;
rTXSettings.SsaoSamples = 12;
rTXSettings.SsaoFullResolution = true;
rTXSettings.BloomIntensity = 1f;
rTXSettings.BloomThreshold = 0.9f;
rTXSettings.Contrast = 16f;
rTXSettings.Saturation = 12f;
rTXSettings.CinematicGrade = 0.5f;
rTXSettings.Vignette = 0.35f;
rTXSettings.ChromaticAberration = 0.18f;
rTXSettings.FilmGrain = 0.2f;
rTXSettings.FogDensity = 0.005f;
rTXSettings.ShadowDistance = 160f;
break;
case Preset.Photoreal:
rTXSettings.SsaoIntensity = 1.8f;
rTXSettings.SsaoRadius = 0.45f;
rTXSettings.SsaoDirectLighting = 0.5f;
rTXSettings.SsaoSamples = 16;
rTXSettings.SsaoFullResolution = true;
rTXSettings.BloomIntensity = 1.1f;
rTXSettings.BloomThreshold = 0.85f;
rTXSettings.BloomScatter = 0.75f;
rTXSettings.Exposure = 0.1f;
rTXSettings.Contrast = 18f;
rTXSettings.Saturation = 6f;
rTXSettings.Temperature = 8f;
rTXSettings.CinematicGrade = 0.65f;
rTXSettings.DepthOfField = true;
rTXSettings.DofAperture = 2.8f;
rTXSettings.MotionBlur = true;
rTXSettings.MotionBlurIntensity = 0.3f;
rTXSettings.Vignette = 0.38f;
rTXSettings.ChromaticAberration = 0.2f;
rTXSettings.LensDistortion = -0.06f;
rTXSettings.FilmGrain = 0.22f;
rTXSettings.FogDensity = 0.006f;
rTXSettings.ShadowDistance = 200f;
break;
}
return rTXSettings;
}
public static RTXSettings Load()
{
try
{
if (File.Exists(FilePath))
{
return JsonSerializer.Deserialize<RTXSettings>(File.ReadAllText(FilePath), Json) ?? new RTXSettings();
}
}
catch (Exception ex)
{
Mod.Logger.Warning($"Couldn't read {FilePath}, using defaults ({ex.Message})");
}
return new RTXSettings();
}
public void Save()
{
try
{
Directory.CreateDirectory(MelonEnvironment.UserDataDirectory);
File.WriteAllText(FilePath, JsonSerializer.Serialize(this, Json));
}
catch (Exception ex)
{
Mod.Logger.Warning($"Couldn't save {FilePath} ({ex.Message})");
}
}
public RTXSettings Clone()
{
return JsonSerializer.Deserialize<RTXSettings>(JsonSerializer.Serialize(this, Json), Json);
}
}
public class RTXSlots
{
public class Slot
{
public string Name { get; set; }
public DateTime? SavedAt { get; set; }
public RTXSettings Settings { get; set; }
[JsonIgnore]
public bool IsEmpty => Settings == null;
}
public const int SlotCount = 10;
public List<Slot> Slots { get; set; } = new List<Slot>();
public Slot this[int i] => Slots[i];
private static string FilePath => Path.Combine(MelonEnvironment.UserDataDirectory, "GBRTX_Slots.json");
private static string DefaultName(int i)
{
return "Slot " + (i + 1);
}
public void SaveTo(int i, RTXSettings current)
{
Slot slot = Slots[i];
slot.Settings = current.Clone();
slot.Settings.Enabled = false;
slot.SavedAt = DateTime.Now;
if (string.IsNullOrWhiteSpace(slot.Name))
{
slot.Name = DefaultName(i);
}
Save();
}
public RTXSettings LoadFrom(int i)
{
return Slots[i].Settings?.Clone();
}
public void Clear(int i)
{
Slots[i] = new Slot
{
Name = DefaultName(i)
};
Save();
}
public static RTXSlots Load()
{
RTXSlots rTXSlots = null;
try
{
if (File.Exists(FilePath))
{
rTXSlots = JsonSerializer.Deserialize<RTXSlots>(File.ReadAllText(FilePath), RTXSettings.Json);
}
}
catch (Exception ex)
{
Mod.Logger.Warning($"Couldn't read {FilePath}, starting with empty slots ({ex.Message})");
}
if (rTXSlots == null)
{
rTXSlots = new RTXSlots();
}
RTXSlots rTXSlots2 = rTXSlots;
if (rTXSlots2.Slots == null)
{
List<Slot> list = (rTXSlots2.Slots = new List<Slot>());
}
while (rTXSlots.Slots.Count < 10)
{
rTXSlots.Slots.Add(new Slot());
}
if (rTXSlots.Slots.Count > 10)
{
rTXSlots.Slots.RemoveRange(10, rTXSlots.Slots.Count - 10);
}
for (int i = 0; i < 10; i++)
{
List<Slot> list = rTXSlots.Slots;
int index = i;
if (list[index] == null)
{
Slot slot = (list[index] = new Slot());
}
if (string.IsNullOrWhiteSpace(rTXSlots.Slots[i].Name))
{
rTXSlots.Slots[i].Name = DefaultName(i);
}
}
return rTXSlots;
}
public void Save()
{
try
{
Directory.CreateDirectory(MelonEnvironment.UserDataDirectory);
File.WriteAllText(FilePath, JsonSerializer.Serialize(this, RTXSettings.Json));
}
catch (Exception ex)
{
Mod.Logger.Warning($"Couldn't save {FilePath} ({ex.Message})");
}
}
}
internal static class MyModInfo
{
public const string Author = "GBMods";
public const string Name = "GB RTX";
public const string Version = "1.0.0";
}
}