Decompiled source of Shader Studio v1.1.0
plugins/ShaderStudio.dll
Decompiled 2 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using System.Text.RegularExpressions; using System.Threading; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Newtonsoft.Json; using UnityEngine; using UnityEngine.Rendering.PostProcessing; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyVersion("0.0.0.0")] namespace ShaderStudio; public enum CompileStatus { NotCompiled, Waiting, Compiling, Ok, Error } public class EffectAsset { public ShaderDef Def; public int[] Programs = new int[0]; public CompileStatus Status; public string Errors = ""; public string Warnings = ""; public int Version; public int CompiledVersion = -1; public bool Wanted; public readonly Texture2D[] Textures = (Texture2D[])(object)new Texture2D[4]; public readonly IntPtr[] TexturePtrs = new IntPtr[4]; public readonly string[] TextureFiles = new string[4]; public string Id => Def.Id; public bool Ready { get { if (Programs.Length == Def.Passes.Count && Programs.Length != 0) { return Programs.All((int p) => p > 0); } return false; } } } public class Library { private struct Job { public EffectAsset Asset; public int Version; public string[] Sources; public string File; } private struct Result { public EffectAsset Asset; public int Version; public int[] Programs; public string Errors; public string Warnings; } public readonly Dictionary<string, EffectAsset> Assets = new Dictionary<string, EffectAsset>(StringComparer.OrdinalIgnoreCase); public string BuiltInDir; public string UserDir; public string Prelude = ""; private float nextScan; private readonly Queue<Result> results = new Queue<Result>(); private readonly object resultLock = new object(); public IEnumerable<EffectAsset> Sorted => from a in Assets.Values orderby a.Def.Category, a.Def.Name select a; public void Init(string builtInDir, string userDir, string prelude) { BuiltInDir = builtInDir; UserDir = userDir; Prelude = prelude; Directory.CreateDirectory(UserDir); Scan(force: true); } public EffectAsset Get(string id) { if (id == null || !Assets.TryGetValue(id, out var value)) { return null; } return value; } public void Scan(bool force) { if (!force && Time.unscaledTime < nextScan) { return; } nextScan = Time.unscaledTime + 1f; HashSet<string> seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase); List<KeyValuePair<string, bool>> list = new List<KeyValuePair<string, bool>>(); try { if (Directory.Exists(BuiltInDir)) { string[] files = Directory.GetFiles(BuiltInDir, "*.hlsl"); foreach (string key in files) { list.Add(new KeyValuePair<string, bool>(key, value: true)); } } } catch { } try { if (Directory.Exists(UserDir)) { string[] files = Directory.GetFiles(UserDir, "*.hlsl"); foreach (string key2 in files) { list.Add(new KeyValuePair<string, bool>(key2, value: false)); } } } catch { } foreach (KeyValuePair<string, bool> item in list) { string key3 = item.Key; string fileName = Path.GetFileName(key3); if (fileName.StartsWith("_") || fileName.Equals("API_REFERENCE.hlsl", StringComparison.OrdinalIgnoreCase)) { continue; } string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(key3); seen.Add(fileNameWithoutExtension); DateTime lastWriteTimeUtc; try { lastWriteTimeUtc = File.GetLastWriteTimeUtc(key3); } catch { continue; } if (Assets.TryGetValue(fileNameWithoutExtension, out var value)) { bool flag = string.Equals(value.Def.Path, key3, StringComparison.OrdinalIgnoreCase); if ((flag && value.Def.LastWrite == lastWriteTimeUtc) || (!flag && !value.Def.BuiltIn && item.Value && File.Exists(value.Def.Path))) { continue; } } LoadFile(key3, item.Value, lastWriteTimeUtc); } foreach (string item2 in Assets.Keys.Where((string k) => !seen.Contains(k)).ToList()) { ReleasePrograms(Assets[item2]); Assets.Remove(item2); } } private void LoadFile(string path, bool builtIn, DateTime mt) { string src; try { src = File.ReadAllText(path); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not read " + path + ": " + ex.Message)); return; } SetSource(path, builtIn, src, mt); } public EffectAsset SetSource(string path, bool builtIn, string src, DateTime mt) { ShaderDef shaderDef = ShaderDef.Parse(src, path, builtIn); shaderDef.LastWrite = mt; if (!Assets.TryGetValue(shaderDef.Id, out var value)) { value = new EffectAsset(); Assets[shaderDef.Id] = value; } value.Def = shaderDef; value.Version++; value.Status = (value.Wanted ? CompileStatus.Waiting : CompileStatus.NotCompiled); LoadTextures(value); return value; } private void LoadTextures(EffectAsset a) { //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Expected O, but got Unknown foreach (UniformDef uniform in a.Def.Uniforms) { if (uniform.Type != UType.Texture) { continue; } string text = uniform.File ?? ""; string path = Path.GetDirectoryName(a.Def.Path) ?? ""; string text2 = (Path.IsPathRooted(text) ? text : Path.Combine(path, text)); if (!File.Exists(text2)) { string text3 = Path.Combine(UserDir, text); if (File.Exists(text3)) { text2 = text3; } } if (a.TextureFiles[uniform.Slot] == text2 && (Object)(object)a.Textures[uniform.Slot] != (Object)null) { continue; } a.TextureFiles[uniform.Slot] = text2; if ((Object)(object)a.Textures[uniform.Slot] != (Object)null) { Object.Destroy((Object)(object)a.Textures[uniform.Slot]); a.Textures[uniform.Slot] = null; a.TexturePtrs[uniform.Slot] = IntPtr.Zero; } if (!File.Exists(text2)) { continue; } try { Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, true); if (ImageConversion.LoadImage(val, File.ReadAllBytes(text2), false)) { ((Texture)val).wrapMode = (TextureWrapMode)0; ((Texture)val).filterMode = (FilterMode)1; val.Apply(false, false); a.Textures[uniform.Slot] = val; a.TexturePtrs[uniform.Slot] = ((Texture)val).GetNativeTexturePtr(); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Texture load failed " + text2 + ": " + ex.Message)); } } } private static void ReleasePrograms(EffectAsset a) { if (Native.Loaded) { int[] programs = a.Programs; foreach (int num in programs) { if (num > 0) { Native.SS_Release(num); } } } a.Programs = new int[0]; } public void Tick(bool nativeReady) { Scan(force: false); if (nativeReady) { foreach (EffectAsset value in Assets.Values) { if (!value.Wanted || value.CompiledVersion == value.Version || value.Status == CompileStatus.Compiling) { continue; } if (value.Def.ParseError != null) { value.Status = CompileStatus.Error; value.Errors = value.Def.ParseError; value.CompiledVersion = value.Version; continue; } Job job = new Job { Asset = value, Version = value.Version, File = value.Def.FileName, Sources = new string[value.Def.Passes.Count] }; for (int i = 0; i < job.Sources.Length; i++) { job.Sources[i] = value.Def.Generate(i, Prelude, lineDirectives: true); } value.Status = CompileStatus.Compiling; ThreadPool.QueueUserWorkItem(delegate { RunJob(job); }); } } lock (resultLock) { while (results.Count > 0) { Result result = results.Dequeue(); EffectAsset asset = result.Asset; bool flag = result.Programs.All((int p) => p > 0); int[] programs; if (result.Version != asset.Version || !Assets.ContainsValue(asset)) { programs = result.Programs; foreach (int num2 in programs) { if (num2 > 0) { Native.SS_Release(num2); } } continue; } asset.CompiledVersion = result.Version; asset.Warnings = result.Warnings; if (flag) { ReleasePrograms(asset); asset.Programs = result.Programs; asset.Status = CompileStatus.Ok; asset.Errors = ""; continue; } programs = result.Programs; foreach (int num3 in programs) { if (num3 > 0) { Native.SS_Release(num3); } } asset.Status = CompileStatus.Error; asset.Errors = result.Errors; Plugin.Log.LogWarning((object)("Shader '" + asset.Def.Name + "' failed to compile:\n" + result.Errors)); } } } private void RunJob(Job job) { int[] array = new int[job.Sources.Length]; StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder2 = new StringBuilder(); for (int i = 0; i < job.Sources.Length; i++) { string messages; try { array[i] = Native.Compile(job.Sources[i], job.File, out messages); } catch (Exception ex) { array[i] = 0; messages = ex.Message; } if (array[i] == 0) { stringBuilder.AppendLine("[pass " + job.Asset.Def.Passes[i].Entry + "]"); stringBuilder.AppendLine(messages); break; } if (!string.IsNullOrEmpty(messages) && i == 0) { stringBuilder2.AppendLine(messages); } } lock (resultLock) { results.Enqueue(new Result { Asset = job.Asset, Version = job.Version, Programs = array, Errors = stringBuilder.ToString(), Warnings = stringBuilder2.ToString() }); } } public void ForceRecompile(EffectAsset a) { a.Version++; a.Status = CompileStatus.Waiting; } public string UniqueUserPath(string baseId) { string text = SafeId(baseId); string text2 = Path.Combine(UserDir, text + ".hlsl"); int num = 2; while (File.Exists(text2) || (Assets.ContainsKey(Path.GetFileNameWithoutExtension(text2)) && !string.Equals(Assets[Path.GetFileNameWithoutExtension(text2)].Def.Path, text2, StringComparison.OrdinalIgnoreCase))) { text2 = Path.Combine(UserDir, text + "_" + num + ".hlsl"); num++; } return text2; } public static string SafeId(string s) { StringBuilder stringBuilder = new StringBuilder(); string text = (s ?? "shader").Trim().ToLowerInvariant(); foreach (char c in text) { stringBuilder.Append(char.IsLetterOrDigit(c) ? c : '_'); } string text2 = stringBuilder.ToString().Trim('_'); if (text2.Length != 0) { return text2; } return "shader"; } } public class EffectInstance { public string AssetId; public bool Enabled = true; public float Mix = 1f; public bool Expanded; public readonly Dictionary<string, float[]> Values = new Dictionary<string, float[]>(); public int Uid = ++uidCounter; private static int uidCounter; [NonSerialized] public float[] Packed = new float[128]; public float[] Get(UniformDef u) { if (!Values.TryGetValue(u.Name, out var value) || value == null || value.Length < 4) { value = (float[])u.Default.Clone(); Values[u.Name] = value; } return value; } public void ResetToDefaults(ShaderDef def) { Values.Clear(); foreach (UniformDef uniform in def.Uniforms) { Get(uniform); } } public float[] Pack(ShaderDef def) { Array.Clear(Packed, 0, Packed.Length); foreach (UniformDef uniform in def.Uniforms) { if (uniform.Type != UType.Texture) { float[] array = Get(uniform); int num = uniform.Slot * 4; for (int i = 0; i < 4; i++) { Packed[num + i] = array[i]; } } } return Packed; } public EffectInstance Clone() { EffectInstance effectInstance = new EffectInstance { AssetId = AssetId, Enabled = Enabled, Mix = Mix, Expanded = Expanded }; foreach (KeyValuePair<string, float[]> value in Values) { effectInstance.Values[value.Key] = (float[])value.Value.Clone(); } return effectInstance; } } internal static class Native { private const string Dll = "ShaderStudioNative"; public static bool Loaded { get; private set; } public static string LoadError { get; private set; } [DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)] private static extern IntPtr LoadLibraryW(string path); [DllImport("ShaderStudioNative")] public static extern int SS_Init(IntPtr unityTexture); [DllImport("ShaderStudioNative")] public static extern int SS_IsReady(); [DllImport("ShaderStudioNative")] private static extern int SS_Compile(byte[] source, byte[] entry, byte[] fileName, byte[] err, int errLen); [DllImport("ShaderStudioNative")] public static extern void SS_Release(int program); [DllImport("ShaderStudioNative")] public static extern void SS_BeginFrame(IntPtr src, IntPtr dst, IntPtr depth, int w, int h, float[] globals, int nGlobals); [DllImport("ShaderStudioNative")] public static extern void SS_SetUserTexture(int slot, IntPtr tex); [DllImport("ShaderStudioNative")] public static extern void SS_AddPass(int program, int w, int h, int isFinal, float mix, float[] parameters, int nParams); [DllImport("ShaderStudioNative")] public static extern void SS_EndFrame(int serial); [DllImport("ShaderStudioNative")] public static extern IntPtr SS_GetRenderEventFunc(); [DllImport("ShaderStudioNative")] private static extern int SS_PopLog(byte[] buf, int len); public static bool Load(string dir) { string text = Path.Combine(dir, "ShaderStudioNative.dll"); if (!File.Exists(text)) { LoadError = "ShaderStudioNative.dll not found next to the plugin (" + text + ")"; return false; } if (LoadLibraryW(text) == IntPtr.Zero) { LoadError = "Could not load ShaderStudioNative.dll (error " + Marshal.GetLastWin32Error() + ")"; return false; } try { SS_IsReady(); } catch (Exception ex) { LoadError = "Native entry points missing: " + ex.Message; return false; } Loaded = true; return true; } private static byte[] Z(string s) { return Encoding.UTF8.GetBytes(s + "\0"); } public static int Compile(string source, string fileName, out string messages) { byte[] array = new byte[16384]; int result = SS_Compile(Z(source), Z("_SS_Main"), Z(fileName), array, array.Length); int num = Array.IndexOf(array, (byte)0); if (num < 0) { num = array.Length; } messages = Encoding.UTF8.GetString(array, 0, num); return result; } public static string PopLog() { if (!Loaded) { return ""; } byte[] array = new byte[8192]; int num = SS_PopLog(array, array.Length); if (num <= 0) { return ""; } return Encoding.UTF8.GetString(array, 0, num); } } [BepInPlugin("com.burak.shaderstudio", "Shader Studio", "1.1.0")] public class Plugin : BaseUnityPlugin { public const string GUID = "com.burak.shaderstudio"; public const string NAME = "Shader Studio"; public const string VERSION = "1.1.0"; public static ManualLogSource Log; public static Plugin Instance; private void Awake() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) Instance = this; Log = ((BaseUnityPlugin)this).Logger; GameObject val = new GameObject("ShaderStudio") { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)val); Studio studio = val.AddComponent<Studio>(); studio.Setup(((BaseUnityPlugin)this).Config, Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location)); Log.LogInfo((object)("Shader Studio 1.1.0 loaded. Press " + ((object)studio.MenuKey.Value/*cast due to .constrained prefix*/).ToString() + " to open the menu.")); } } public class PresetEffect { public string shader; public bool enabled = true; public float mix = 1f; public Dictionary<string, float[]> values = new Dictionary<string, float[]>(); } public class FxParamData { public bool o; public float[] v; } public class FxEffectData { public bool enabled = true; public Dictionary<string, FxParamData> p = new Dictionary<string, FxParamData>(); } public class PresetData { public string name = ""; public string description = ""; public List<PresetEffect> effects = new List<PresetEffect>(); public RenderingSettings rendering; public bool unityFxEnabled; public float unityFxWeight = 1f; public Dictionary<string, FxEffectData> unityFx; [JsonIgnore] public string Path; [JsonIgnore] public bool BuiltIn; } public class Studio : MonoBehaviour { public static Studio I; public ConfigEntry<KeyCode> MenuKey; public ConfigEntry<KeyCode> ToggleKey; public ConfigEntry<float> UIScale; public ConfigEntry<bool> FlipY; public ConfigEntry<bool> EffectsOn; public ConfigEntry<bool> LockInputWhileOpen; public ConfigEntry<string> TargetCameraName; public ConfigEntry<int> EditorFontSize; public string PluginDir; public string ConfigDir; public string UserShaderDir; public string UserPresetDir; public string BuiltInShaderDir; public string BuiltInPresetDir; public string StatePath; public readonly Library Lib = new Library(); public readonly List<EffectInstance> Stack = new List<EffectInstance>(); public readonly List<PresetData> Presets = new List<PresetData>(); public RenderingTweaks Rendering; public UnityFxController UnityFx; public StudioUI UI; public bool MenuOpen; public bool Dirty; public string EditorAssetId; public string NativeStatus = "Waiting for the first frame..."; public bool NativeOk; public bool NativeFailed; public readonly List<string> NativeLog = new List<string>(); public Camera TargetCamera; public float LastFrameMs; private RenderTexture inRT; private RenderTexture outRT; private RenderTexture depthRT; private IntPtr inPtr; private IntPtr outPtr; private IntPtr depthPtr; private IntPtr renderFunc; private int serial = 1; private readonly float[] globals = new float[96]; private Matrix4x4 prevViewProj = Matrix4x4.identity; private bool havePrev; private Camera depthModeCam; private bool weAddedDepth; private Light sun; private float nextSunSearch; private float nextSave; private static readonly int DepthTexId = Shader.PropertyToID("_CameraDepthTexture"); private bool loggedProcessError; private FieldInfo gManField; private FieldInfo lockInputField; private PropertyInfo showCursorProp; private bool weLockedInput; private bool prevShowCursor; private CursorLockMode prevLock; private bool prevVisible; private bool menuKeyHeld; private bool toggleKeyHeld; public void Setup(ConfigFile cfg, string pluginDir) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown I = this; MenuKey = cfg.Bind<KeyCode>("Hotkeys", "OpenMenu", (KeyCode)289, "Opens / closes the Shader Studio menu."); ToggleKey = cfg.Bind<KeyCode>("Hotkeys", "ToggleEffects", (KeyCode)290, "Turns all custom shader effects on/off (quick before/after)."); UIScale = cfg.Bind<float>("Interface", "UIScale", 1f, new ConfigDescription("Menu size multiplier.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.6f, 2.5f), Array.Empty<object>())); EditorFontSize = cfg.Bind<int>("Interface", "EditorFontSize", 15, "Code editor font size."); LockInputWhileOpen = cfg.Bind<bool>("Interface", "LockPlayerWhileMenuOpen", true, "Stops the player from moving/looking around while the menu is open."); EffectsOn = cfg.Bind<bool>("Rendering", "EffectsEnabled", true, "Master switch for custom shader effects."); FlipY = cfg.Bind<bool>("Rendering", "FlipY", false, "Flip the vertical image axis for shaders (only if effects look upside down)."); TargetCameraName = cfg.Bind<string>("Rendering", "TargetCamera", "", "Camera to apply effects to. Empty = the main camera."); PluginDir = pluginDir; ConfigDir = Path.Combine(Paths.ConfigPath, "ShaderStudio"); UserShaderDir = Path.Combine(ConfigDir, "shaders"); UserPresetDir = Path.Combine(ConfigDir, "presets"); BuiltInShaderDir = Path.Combine(PluginDir, "shaders"); BuiltInPresetDir = Path.Combine(PluginDir, "presets"); StatePath = Path.Combine(ConfigDir, "current_setup.json"); Directory.CreateDirectory(UserShaderDir); Directory.CreateDirectory(UserPresetDir); string prelude = LoadPrelude(); WriteStarterFiles(prelude); if (!Native.Load(PluginDir)) { NativeFailed = true; NativeStatus = Native.LoadError; Plugin.Log.LogError((object)NativeStatus); } else { renderFunc = Native.SS_GetRenderEventFunc(); } Lib.Init(BuiltInShaderDir, UserShaderDir, prelude); Rendering = new RenderingTweaks(); UnityFx = new UnityFxController(); UI = new StudioUI(this); LoadPresetList(); LoadState(); Type type = Type.GetType("CL_GameManager, Assembly-CSharp"); if (type != null) { gManField = type.GetField("gMan", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); lockInputField = type.GetField("lockPlayerInput", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); showCursorProp = type.GetProperty("showCursor", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); } } private string LoadPrelude() { using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("ShaderStudio.Prelude.hlsl"); using StreamReader streamReader = new StreamReader(stream); return streamReader.ReadToEnd(); } private void WriteStarterFiles(string prelude) { try { File.WriteAllText(Path.Combine(UserShaderDir, "API_REFERENCE.hlsl"), "// This file is regenerated every launch. It shows everything your shaders can use.\n// (Files starting with _ and this file are not loaded as effects.)\n\n" + prelude); string path = Path.Combine(UserShaderDir, "my_first_shader.hlsl"); if (!File.Exists(path)) { File.WriteAllText(path, ShaderDef.NewShaderTemplate("My First Shader")); } string path2 = Path.Combine(ConfigDir, "README.txt"); if (!File.Exists(path2)) { File.WriteAllText(path2, "Shader Studio user folder\n\nshaders/ - your .hlsl effects (hot-reloaded while the game runs)\npresets/ - your saved presets (.json)\ncurrent_setup.json - the stack you had last time\n\nSee shaders/API_REFERENCE.hlsl for every function and value you can use.\n"); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not write starter files: " + ex.Message)); } } private void Update() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_001d: 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) if (!NativeFailed && (int)SystemInfo.graphicsDeviceType != 2) { NativeFailed = true; NativeStatus = "Custom shaders need DirectX 11, but the game is running on " + ((object)SystemInfo.graphicsDeviceType/*cast due to .constrained prefix*/).ToString() + ". Add -force-d3d11 to White Knuckle's Steam launch options. (Unity FX and Rendering tabs still work.)"; Plugin.Log.LogWarning((object)NativeStatus); } foreach (EffectAsset value in Lib.Assets.Values) { value.Wanted = false; } foreach (EffectInstance item in Stack) { EffectAsset effectAsset = Lib.Get(item.AssetId); if (effectAsset != null) { effectAsset.Wanted = true; } } EffectAsset effectAsset2 = Lib.Get(EditorAssetId); if (effectAsset2 != null) { effectAsset2.Wanted = true; } Lib.Tick(NativeOk); PumpNativeLog(); FindCamera(); Rendering.Tick(TargetCamera); UnityFx.Tick(TargetCamera); if (MenuOpen) { Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; } if (Dirty && Time.unscaledTime > nextSave) { SaveState(); Dirty = false; nextSave = Time.unscaledTime + 1.5f; } } private void LateUpdate() { if (MenuOpen) { Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; } } private void OnApplicationQuit() { SaveState(); } private void OnGUI() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Invalid comparison between Unknown and I4 //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001b: 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_0072: Invalid comparison between Unknown and I4 //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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) //IL_00be: Invalid comparison between Unknown and I4 //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) Event current = Event.current; if ((int)current.type == 4 && current.keyCode == MenuKey.Value) { if (!menuKeyHeld) { SetMenuOpen(!MenuOpen); } menuKeyHeld = true; current.Use(); } else if ((int)current.type == 5 && current.keyCode == MenuKey.Value) { menuKeyHeld = false; } if ((int)current.type == 4 && current.keyCode == ToggleKey.Value) { if (!toggleKeyHeld) { EffectsOn.Value = !EffectsOn.Value; } toggleKeyHeld = true; current.Use(); } else if ((int)current.type == 5 && current.keyCode == ToggleKey.Value) { toggleKeyHeld = false; } if (MenuOpen) { UI.Draw(); } } public void SetMenuOpen(bool open) { //IL_0155: Unknown result type (might be due to invalid IL or missing references) //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) if (open == MenuOpen) { return; } MenuOpen = open; object obj = null; try { obj = ((gManField != null) ? gManField.GetValue(null) : null); } catch { } if (open) { prevLock = Cursor.lockState; prevVisible = Cursor.visible; if (!LockInputWhileOpen.Value || obj == null || !(lockInputField != null)) { return; } try { if (!(bool)lockInputField.GetValue(obj)) { lockInputField.SetValue(obj, true); weLockedInput = true; } if (showCursorProp != null) { prevShowCursor = (bool)showCursorProp.GetValue(null, null); showCursorProp.SetValue(null, true, null); } return; } catch { return; } } try { if (weLockedInput && obj != null && lockInputField != null) { lockInputField.SetValue(obj, false); } if (showCursorProp != null && LockInputWhileOpen.Value) { showCursorProp.SetValue(null, prevShowCursor, null); } } catch { } weLockedInput = false; Cursor.lockState = prevLock; Cursor.visible = prevVisible; SaveState(); } private void PumpNativeLog() { if (!Native.Loaded) { return; } string text = Native.PopLog(); if (string.IsNullOrEmpty(text)) { return; } string[] array = text.Split('\n'); foreach (string text2 in array) { if (text2.Trim().Length != 0) { Plugin.Log.LogInfo((object)("[native] " + text2)); NativeLog.Add(text2); } } while (NativeLog.Count > 60) { NativeLog.RemoveAt(0); } } private void FindCamera() { //IL_0087: 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) Camera val = null; string value = TargetCameraName.Value; if (!string.IsNullOrEmpty(value)) { Camera[] allCameras = Camera.allCameras; foreach (Camera val2 in allCameras) { if (((Object)val2).name == value) { val = val2; break; } } } if ((Object)(object)val == (Object)null) { val = Camera.main; } if ((Object)(object)val == (Object)null) { return; } if ((Object)(object)val != (Object)(object)TargetCamera) { if ((Object)(object)depthModeCam != (Object)null && weAddedDepth) { Camera obj = depthModeCam; obj.depthTextureMode = (DepthTextureMode)(obj.depthTextureMode & -2); weAddedDepth = false; depthModeCam = null; } TargetCamera = val; havePrev = false; } if ((Object)(object)((Component)val).GetComponent<StudioCamera>() == (Object)null) { ((Component)val).gameObject.AddComponent<StudioCamera>(); } } public List<EffectInstance> ActiveInstances() { List<EffectInstance> list = new List<EffectInstance>(); if (!EffectsOn.Value) { return list; } foreach (EffectInstance item in Stack) { if (item.Enabled && !(item.Mix <= 0f)) { EffectAsset effectAsset = Lib.Get(item.AssetId); if (effectAsset != null && effectAsset.Ready) { list.Add(item); } } } return list; } private static void EnsureRT(ref RenderTexture rt, ref IntPtr ptr, int w, int h, RenderTextureFormat fmt, string name) { //IL_0044: 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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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_0071: Expected O, but got Unknown if (!((Object)(object)rt != (Object)null) || ((Texture)rt).width != w || ((Texture)rt).height != h || !rt.IsCreated()) { if ((Object)(object)rt != (Object)null) { rt.Release(); Object.Destroy((Object)(object)rt); } rt = new RenderTexture(w, h, 0, fmt, (RenderTextureReadWrite)1) { name = name, useMipMap = false, autoGenerateMips = false, filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; rt.Create(); ptr = ((Texture)rt).GetNativeTexturePtr(); } } public void Process(Camera cam, RenderTexture src, RenderTexture dst) { List<EffectInstance> list = (((Object)(object)cam == (Object)(object)TargetCamera && !NativeFailed && Native.Loaded) ? ActiveInstances() : null); bool flag = false; if (list != null) { foreach (EffectInstance item in list) { if (Lib.Get(item.AssetId).Def.UsesDepth) { flag = true; break; } } } UpdateDepthMode(cam, flag); if (!NativeOk && !NativeFailed && Native.Loaded && (Object)(object)cam == (Object)(object)TargetCamera) { EnsureRT(ref inRT, ref inPtr, ((Texture)src).width, ((Texture)src).height, (RenderTextureFormat)2, "SS_In"); if (Native.SS_Init(inPtr) == 1) { NativeOk = true; NativeStatus = "DirectX 11 shader compiler ready."; } else { NativeFailed = true; NativeStatus = "Native renderer failed to start: " + Native.PopLog(); Plugin.Log.LogError((object)NativeStatus); } } if (list == null || list.Count == 0 || !NativeOk) { Graphics.Blit((Texture)(object)src, dst); return; } float realtimeSinceStartup = Time.realtimeSinceStartup; int width = ((Texture)src).width; int height = ((Texture)src).height; EnsureRT(ref inRT, ref inPtr, width, height, (RenderTextureFormat)2, "SS_In"); EnsureRT(ref outRT, ref outPtr, width, height, (RenderTextureFormat)2, "SS_Out"); Graphics.Blit((Texture)(object)src, inRT); bool flag2 = false; if (flag) { Texture globalTexture = Shader.GetGlobalTexture(DepthTexId); if ((Object)(object)globalTexture != (Object)null) { EnsureRT(ref depthRT, ref depthPtr, width, height, (RenderTextureFormat)14, "SS_Depth"); Graphics.Blit(globalTexture, depthRT); flag2 = true; } } FillGlobals(cam, width, height, flag2); Native.SS_BeginFrame(inPtr, outPtr, flag2 ? depthPtr : IntPtr.Zero, width, height, globals, globals.Length); foreach (EffectInstance item2 in list) { EffectAsset effectAsset = Lib.Get(item2.AssetId); ShaderDef def = effectAsset.Def; for (int i = 0; i < 4; i++) { Native.SS_SetUserTexture(i, ((Object)(object)effectAsset.Textures[i] != (Object)null) ? effectAsset.TexturePtrs[i] : IntPtr.Zero); } float[] array = item2.Pack(def); for (int j = 0; j < def.Passes.Count; j++) { bool flag3 = def.IsFinalPass(j); float num = (flag3 ? 1f : def.Passes[j].Scale); int w = Mathf.Max(1, Mathf.RoundToInt((float)width * num)); int h = Mathf.Max(1, Mathf.RoundToInt((float)height * num)); Native.SS_AddPass(effectAsset.Programs[j], w, h, flag3 ? 1 : 0, Mathf.Clamp(item2.Mix, 0f, 1f), array, array.Length); } } Native.SS_EndFrame(serial); GL.IssuePluginEvent(renderFunc, serial); serial = ((serial >= 1073741824) ? 1 : (serial + 1)); Graphics.Blit((Texture)(object)outRT, dst); LastFrameMs = (Time.realtimeSinceStartup - realtimeSinceStartup) * 1000f; } private void UpdateDepthMode(Camera cam, bool need) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //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_0015: 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) //IL_004c: Unknown result type (might be due to invalid IL or missing references) if (need && (cam.depthTextureMode & 1) == 0) { cam.depthTextureMode = (DepthTextureMode)(cam.depthTextureMode | 1); weAddedDepth = true; depthModeCam = cam; } else if (!need && weAddedDepth && (Object)(object)depthModeCam == (Object)(object)cam) { cam.depthTextureMode = (DepthTextureMode)(cam.depthTextureMode & -2); weAddedDepth = false; depthModeCam = null; } } private static void PutMatrix(float[] g, int o, Matrix4x4 m) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { g[o + i * 4 + j] = ((Matrix4x4)(ref m))[j, i]; } } } private void FillGlobals(Camera cam, int w, int h, bool hasDepth) { //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0117: 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_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Invalid comparison between Unknown and I4 //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) float[] array = globals; array[0] = Time.unscaledTime; array[1] = Time.unscaledDeltaTime; array[2] = Time.frameCount; array[3] = Random.value; array[4] = w; array[5] = h; array[6] = 1f / (float)w; array[7] = 1f / (float)h; float nearClipPlane = cam.nearClipPlane; float farClipPlane = cam.farClipPlane; float num; float num2; if (SystemInfo.usesReversedZBuffer) { num = -1f + farClipPlane / nearClipPlane; num2 = 1f; } else { num = 1f - farClipPlane / nearClipPlane; num2 = farClipPlane / nearClipPlane; } array[8] = num; array[9] = num2; array[10] = num / farClipPlane; array[11] = num2 / farClipPlane; float num3 = Mathf.Tan(cam.fieldOfView * 0.5f * ((float)Math.PI / 180f)); array[12] = num3 * cam.aspect; array[13] = num3; array[14] = nearClipPlane; array[15] = farClipPlane; PutMatrix(array, 16, cam.cameraToWorldMatrix); PutMatrix(array, 32, cam.worldToCameraMatrix); Matrix4x4 val = cam.projectionMatrix * cam.worldToCameraMatrix; PutMatrix(array, 48, val); PutMatrix(array, 64, havePrev ? prevViewProj : val); prevViewProj = val; havePrev = true; Vector3 position = ((Component)cam).transform.position; array[80] = position.x; array[81] = position.y; array[82] = position.z; array[83] = 0f; array[84] = (hasDepth ? 1 : 0); array[85] = (((int)QualitySettings.activeColorSpace == 1) ? 1 : 0); array[86] = (FlipY.Value ? 1 : 0); array[87] = 0f; FindSun(); if ((Object)(object)sun != (Object)null) { Vector3 forward = ((Component)sun).transform.forward; Color val2 = sun.color * sun.intensity; array[88] = forward.x; array[89] = forward.y; array[90] = forward.z; array[91] = 1f; array[92] = val2.r; array[93] = val2.g; array[94] = val2.b; array[95] = 1f; } else { Vector3 val3 = new Vector3(-0.35f, -1f, -0.25f); Vector3 normalized = ((Vector3)(ref val3)).normalized; array[88] = normalized.x; array[89] = normalized.y; array[90] = normalized.z; array[91] = 0f; array[92] = (array[93] = (array[94] = 1f)); array[95] = 0f; } } private void FindSun() { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Invalid comparison between Unknown and I4 if (Time.unscaledTime < nextSunSearch && ((Object)(object)sun == (Object)null || ((Behaviour)sun).isActiveAndEnabled)) { return; } nextSunSearch = Time.unscaledTime + 2f; sun = null; float num = 0f; Light[] array = Object.FindObjectsByType<Light>((FindObjectsSortMode)0); foreach (Light val in array) { if ((int)val.type == 1 && ((Behaviour)val).isActiveAndEnabled && val.intensity > num) { num = val.intensity; sun = val; } } } public EffectInstance AddEffect(string assetId) { EffectAsset effectAsset = Lib.Get(assetId); if (effectAsset == null) { return null; } EffectInstance effectInstance = new EffectInstance { AssetId = assetId, Expanded = true }; effectInstance.ResetToDefaults(effectAsset.Def); Stack.Add(effectInstance); Dirty = true; return effectInstance; } public PresetData CaptureState(string name, bool includeRendering, bool includeUnityFx) { PresetData presetData = new PresetData { name = name }; foreach (EffectInstance item in Stack) { PresetEffect presetEffect = new PresetEffect { shader = item.AssetId, enabled = item.Enabled, mix = item.Mix }; foreach (KeyValuePair<string, float[]> value in item.Values) { presetEffect.values[value.Key] = (float[])value.Value.Clone(); } presetData.effects.Add(presetEffect); } if (includeRendering) { presetData.rendering = Rendering.Settings.Clone(); } if (includeUnityFx) { presetData.unityFxEnabled = UnityFx.Enabled; presetData.unityFxWeight = UnityFx.Weight; presetData.unityFx = UnityFx.Capture(); } return presetData; } public void ApplyPreset(PresetData p, bool append) { if (!append) { Stack.Clear(); } List<string> list = new List<string>(); foreach (PresetEffect effect in p.effects) { EffectAsset effectAsset = Lib.Get(effect.shader); if (effectAsset == null) { list.Add(effect.shader); continue; } EffectInstance effectInstance = new EffectInstance { AssetId = effect.shader, Enabled = effect.enabled, Mix = effect.mix }; effectInstance.ResetToDefaults(effectAsset.Def); if (effect.values != null) { foreach (KeyValuePair<string, float[]> value in effect.values) { if (value.Value != null && effectInstance.Values.ContainsKey(value.Key)) { float[] array = effectInstance.Values[value.Key]; for (int i = 0; i < Math.Min(4, value.Value.Length); i++) { array[i] = value.Value[i]; } } } } Stack.Add(effectInstance); } if (!append) { if (p.rendering != null) { Rendering.Settings = p.rendering.Clone(); } if (p.unityFx != null) { UnityFx.Enabled = p.unityFxEnabled; UnityFx.Weight = p.unityFxWeight; UnityFx.Restore(p.unityFx); } } if (list.Count > 0) { UI.Toast("Missing shaders: " + string.Join(", ", list.ToArray())); } Dirty = true; } public void LoadPresetList() { Presets.Clear(); string[] array = new string[2] { BuiltInPresetDir, UserPresetDir }; foreach (string text in array) { if (!Directory.Exists(text)) { continue; } foreach (string item in from x in Directory.GetFiles(text, "*.json") orderby x select x) { try { PresetData presetData = JsonConvert.DeserializeObject<PresetData>(File.ReadAllText(item)); if (presetData != null) { presetData.Path = item; presetData.BuiltIn = text == BuiltInPresetDir; if (string.IsNullOrEmpty(presetData.name)) { presetData.name = Path.GetFileNameWithoutExtension(item); } Presets.Add(presetData); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Bad preset " + item + ": " + ex.Message)); } } } } public string SavePreset(string name, string description, bool includeRendering, bool includeUnityFx) { PresetData presetData = CaptureState(name, includeRendering, includeUnityFx); presetData.description = description ?? ""; string text = Path.Combine(UserPresetDir, Library.SafeId(name) + ".json"); File.WriteAllText(text, JsonConvert.SerializeObject((object)presetData, (Formatting)1)); LoadPresetList(); return text; } public void SaveState() { try { PresetData presetData = CaptureState("current", includeRendering: true, includeUnityFx: true); File.WriteAllText(StatePath, JsonConvert.SerializeObject((object)presetData, (Formatting)1)); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not save state: " + ex.Message)); } } private void LoadState() { try { if (File.Exists(StatePath)) { PresetData presetData = JsonConvert.DeserializeObject<PresetData>(File.ReadAllText(StatePath)); if (presetData != null) { ApplyPreset(presetData, append: false); } Dirty = false; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not load last setup: " + ex.Message)); } } public void LogProcessError(Exception e) { if (!loggedProcessError) { loggedProcessError = true; Plugin.Log.LogError((object)("Shader Studio render error (effects bypassed this frame): " + e)); } } } public class StudioCamera : MonoBehaviour { private Camera cam; private void Awake() { cam = ((Component)this).GetComponent<Camera>(); } private void OnRenderImage(RenderTexture src, RenderTexture dst) { Studio i = Studio.I; if ((Object)(object)i == (Object)null) { Graphics.Blit((Texture)(object)src, dst); return; } try { i.Process(cam, src, dst); } catch (Exception e) { i.LogProcessError(e); Graphics.Blit((Texture)(object)src, dst); } } } public class RenderingSettings { public bool shadowsOverride; public int shadowQuality = 2; public int shadowResolution = 3; public float shadowDistance = 120f; public int shadowCascades = 4; public int lightShadowMode; public bool lightShadowStrengthOverride; public float lightShadowStrength = 1f; public bool lightsOverride; public float lightIntensity = 1f; public float lightRange = 1f; public float[] lightTint = new float[4] { 1f, 1f, 1f, 1f }; public bool ambientOverride; public float ambientMultiplier = 1f; public float[] ambientTint = new float[4] { 1f, 1f, 1f, 1f }; public bool fogOverride; public bool fogEnabled = true; public float[] fogColor = new float[4] { 0.5f, 0.55f, 0.6f, 1f }; public float fogDensity = 0.02f; public bool reflectionOverride; public float reflectionIntensity = 1f; public bool fovOverride; public float fov = 90f; public bool msaaOverride; public int msaa = 4; public bool hdrOverride; public bool hdr = true; public bool qualityOverride; public int pixelLightCount = 8; public int anisotropic = 2; public float lodBias = 2f; public RenderingSettings Clone() { RenderingSettings obj = (RenderingSettings)MemberwiseClone(); obj.lightTint = (float[])lightTint.Clone(); obj.ambientTint = (float[])ambientTint.Clone(); obj.fogColor = (float[])fogColor.Clone(); return obj; } } public class RenderingTweaks { private struct LightOrig { public float intensity; public float range; public float shadowStrength; public LightShadows shadows; public Color color; } public RenderingSettings Settings = new RenderingSettings(); private readonly Dictionary<Light, LightOrig> lights = new Dictionary<Light, LightOrig>(); private float nextLightScan; private bool qsCaptured; private ShadowQuality oShadows; private ShadowResolution oShadowRes; private float oShadowDist; private int oCascades; private int oPixelLights; private AnisotropicFiltering oAniso; private float oLodBias; private int oAA; private bool rsCaptured; private Color oAmbient; private Color oAmbSky; private Color oAmbEq; private Color oAmbGround; private float oAmbIntensity; private bool oFog; private Color oFogColor; private float oFogDensity; private FogMode oFogMode; private float oRefl; private Camera camCaptured; private float oFov; private bool oHdr; private bool oMsaa; private bool fovHooked; private bool hdrWas; private bool msaaWas; private bool lightsWas; private bool shadowModeWas; private bool strengthWas; private Camera fovCam; public RenderingTweaks() { SceneManager.sceneLoaded += delegate { rsCaptured = false; lights.Clear(); }; } private static Color C(float[] a) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) return new Color(a[0], a[1], a[2], (a.Length > 3) ? a[3] : 1f); } public void Tick(Camera cam) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016e: 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_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_0358: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_0363: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_038f: Unknown result type (might be due to invalid IL or missing references) //IL_03a0: Unknown result type (might be due to invalid IL or missing references) //IL_03a5: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_0444: Unknown result type (might be due to invalid IL or missing references) //IL_044f: Unknown result type (might be due to invalid IL or missing references) //IL_045a: Unknown result type (might be due to invalid IL or missing references) //IL_0465: 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_03e0: Unknown result type (might be due to invalid IL or missing references) //IL_03e5: Unknown result type (might be due to invalid IL or missing references) //IL_03e8: Unknown result type (might be due to invalid IL or missing references) //IL_03ed: Unknown result type (might be due to invalid IL or missing references) //IL_03ef: Unknown result type (might be due to invalid IL or missing references) //IL_03fa: Unknown result type (might be due to invalid IL or missing references) //IL_03ff: Unknown result type (might be due to invalid IL or missing references) //IL_0401: Unknown result type (might be due to invalid IL or missing references) //IL_040c: Unknown result type (might be due to invalid IL or missing references) //IL_0411: Unknown result type (might be due to invalid IL or missing references) //IL_0413: Unknown result type (might be due to invalid IL or missing references) //IL_041e: Unknown result type (might be due to invalid IL or missing references) //IL_0423: Unknown result type (might be due to invalid IL or missing references) //IL_0425: Unknown result type (might be due to invalid IL or missing references) //IL_04bc: Unknown result type (might be due to invalid IL or missing references) //IL_04d2: Unknown result type (might be due to invalid IL or missing references) //IL_0493: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_06df: Unknown result type (might be due to invalid IL or missing references) //IL_06e4: Unknown result type (might be due to invalid IL or missing references) //IL_06ed: Unknown result type (might be due to invalid IL or missing references) //IL_06f2: Unknown result type (might be due to invalid IL or missing references) //IL_05e5: Unknown result type (might be due to invalid IL or missing references) //IL_05ef: Expected O, but got Unknown //IL_05ef: Unknown result type (might be due to invalid IL or missing references) //IL_05f9: Expected O, but got Unknown //IL_061c: Unknown result type (might be due to invalid IL or missing references) //IL_0626: Expected O, but got Unknown //IL_0626: Unknown result type (might be due to invalid IL or missing references) //IL_0630: Expected O, but got Unknown RenderingSettings settings = Settings; bool flag = settings.shadowsOverride || settings.qualityOverride || settings.msaaOverride; if (flag && !qsCaptured) { oShadows = QualitySettings.shadows; oShadowRes = QualitySettings.shadowResolution; oShadowDist = QualitySettings.shadowDistance; oCascades = QualitySettings.shadowCascades; oPixelLights = QualitySettings.pixelLightCount; oAniso = QualitySettings.anisotropicFiltering; oLodBias = QualitySettings.lodBias; oAA = QualitySettings.antiAliasing; qsCaptured = true; } if (qsCaptured) { if (settings.shadowsOverride) { Set(QualitySettings.shadows, (ShadowQuality)((settings.shadowQuality != 0) ? ((settings.shadowQuality == 1) ? 1 : 2) : 0), delegate(ShadowQuality v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) QualitySettings.shadows = v; }); Set(QualitySettings.shadowResolution, (ShadowResolution)Mathf.Clamp(settings.shadowResolution, 0, 3), delegate(ShadowResolution v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) QualitySettings.shadowResolution = v; }); if (!Mathf.Approximately(QualitySettings.shadowDistance, settings.shadowDistance)) { QualitySettings.shadowDistance = settings.shadowDistance; } int num = ((settings.shadowCascades > 1) ? ((settings.shadowCascades <= 2) ? 2 : 4) : 0); if (QualitySettings.shadowCascades != num) { QualitySettings.shadowCascades = num; } } else { Set(QualitySettings.shadows, oShadows, delegate(ShadowQuality v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) QualitySettings.shadows = v; }); Set(QualitySettings.shadowResolution, oShadowRes, delegate(ShadowResolution v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) QualitySettings.shadowResolution = v; }); if (!Mathf.Approximately(QualitySettings.shadowDistance, oShadowDist)) { QualitySettings.shadowDistance = oShadowDist; } if (QualitySettings.shadowCascades != oCascades) { QualitySettings.shadowCascades = oCascades; } } if (settings.qualityOverride) { if (QualitySettings.pixelLightCount != settings.pixelLightCount) { QualitySettings.pixelLightCount = settings.pixelLightCount; } Set(QualitySettings.anisotropicFiltering, (AnisotropicFiltering)Mathf.Clamp(settings.anisotropic, 0, 2), delegate(AnisotropicFiltering v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) QualitySettings.anisotropicFiltering = v; }); if (!Mathf.Approximately(QualitySettings.lodBias, settings.lodBias)) { QualitySettings.lodBias = settings.lodBias; } } else { if (QualitySettings.pixelLightCount != oPixelLights) { QualitySettings.pixelLightCount = oPixelLights; } Set(QualitySettings.anisotropicFiltering, oAniso, delegate(AnisotropicFiltering v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) QualitySettings.anisotropicFiltering = v; }); if (!Mathf.Approximately(QualitySettings.lodBias, oLodBias)) { QualitySettings.lodBias = oLodBias; } } int num2 = ((!settings.msaaOverride) ? oAA : ((settings.msaa >= 8) ? 8 : ((settings.msaa >= 4) ? 4 : ((settings.msaa >= 2) ? 2 : 0)))); if (QualitySettings.antiAliasing != num2) { QualitySettings.antiAliasing = num2; } if (!flag) { qsCaptured = false; } } bool flag2 = settings.ambientOverride || settings.fogOverride || settings.reflectionOverride; if (flag2 && !rsCaptured) { oAmbient = RenderSettings.ambientLight; oAmbSky = RenderSettings.ambientSkyColor; oAmbEq = RenderSettings.ambientEquatorColor; oAmbGround = RenderSettings.ambientGroundColor; oAmbIntensity = RenderSettings.ambientIntensity; oFog = RenderSettings.fog; oFogColor = RenderSettings.fogColor; oFogDensity = RenderSettings.fogDensity; oFogMode = RenderSettings.fogMode; oRefl = RenderSettings.reflectionIntensity; rsCaptured = true; } if (rsCaptured) { if (settings.ambientOverride) { Color b = C(settings.ambientTint) * settings.ambientMultiplier; RenderSettings.ambientLight = Mul(oAmbient, b); RenderSettings.ambientSkyColor = Mul(oAmbSky, b); RenderSettings.ambientEquatorColor = Mul(oAmbEq, b); RenderSettings.ambientGroundColor = Mul(oAmbGround, b); RenderSettings.ambientIntensity = oAmbIntensity * settings.ambientMultiplier; } else { RenderSettings.ambientLight = oAmbient; RenderSettings.ambientSkyColor = oAmbSky; RenderSettings.ambientEquatorColor = oAmbEq; RenderSettings.ambientGroundColor = oAmbGround; RenderSettings.ambientIntensity = oAmbIntensity; } if (settings.fogOverride) { RenderSettings.fog = settings.fogEnabled; RenderSettings.fogColor = C(settings.fogColor); RenderSettings.fogMode = (FogMode)3; RenderSettings.fogDensity = settings.fogDensity; } else { RenderSettings.fog = oFog; RenderSettings.fogColor = oFogColor; RenderSettings.fogDensity = oFogDensity; RenderSettings.fogMode = oFogMode; } RenderSettings.reflectionIntensity = (settings.reflectionOverride ? settings.reflectionIntensity : oRefl); if (!flag2) { rsCaptured = false; } } if ((Object)(object)cam != (Object)null) { if ((Object)(object)camCaptured != (Object)(object)cam) { if ((Object)(object)camCaptured != (Object)null) { RestoreCam(); } camCaptured = cam; oFov = cam.fieldOfView; oHdr = cam.allowHDR; oMsaa = cam.allowMSAA; } if (settings.hdrOverride) { cam.allowHDR = settings.hdr; } else if (hdrWas) { cam.allowHDR = oHdr; } if (settings.msaaOverride) { cam.allowMSAA = settings.msaa > 0; } else if (msaaWas) { cam.allowMSAA = oMsaa; } hdrWas = settings.hdrOverride; msaaWas = settings.msaaOverride; if (settings.fovOverride && !fovHooked) { Camera.onPreCull = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(OnPreCull)); fovHooked = true; } if (!settings.fovOverride && fovHooked) { Camera.onPreCull = (CameraCallback)Delegate.Remove((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(OnPreCull)); fovHooked = false; if ((Object)(object)camCaptured != (Object)null) { camCaptured.fieldOfView = oFov; } } fovCam = cam; } if (Time.unscaledTime > nextLightScan) { nextLightScan = Time.unscaledTime + 1f; Light[] array = Object.FindObjectsByType<Light>((FindObjectsSortMode)0); foreach (Light val in array) { if (!lights.ContainsKey(val)) { lights[val] = new LightOrig { intensity = val.intensity, range = val.range, shadowStrength = val.shadowStrength, shadows = val.shadows, color = val.color }; } } List<Light> list = new List<Light>(); foreach (KeyValuePair<Light, LightOrig> light in lights) { if ((Object)(object)light.Key == (Object)null) { list.Add(light.Key); } } foreach (Light item in list) { lights.Remove(item); } } ApplyLights(); } private void OnPreCull(Camera c) { if ((Object)(object)c == (Object)(object)fovCam && Settings.fovOverride) { c.fieldOfView = Settings.fov; } } private void RestoreCam() { if (!((Object)(object)camCaptured == (Object)null)) { camCaptured.allowHDR = oHdr; camCaptured.allowMSAA = oMsaa; camCaptured.fieldOfView = oFov; } } private void ApplyLights() { //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) RenderingSettings settings = Settings; bool lightsOverride = settings.lightsOverride; bool flag = settings.lightShadowMode != 0; bool lightShadowStrengthOverride = settings.lightShadowStrengthOverride; if (!lightsOverride && !lightsWas && !flag && !shadowModeWas && !lightShadowStrengthOverride && !strengthWas) { return; } foreach (KeyValuePair<Light, LightOrig> light in lights) { Light key = light.Key; if ((Object)(object)key == (Object)null) { continue; } LightOrig value = light.Value; if (lightsOverride || lightsWas) { float num = (lightsOverride ? (value.intensity * settings.lightIntensity) : value.intensity); float num2 = (lightsOverride ? (value.range * settings.lightRange) : value.range); Color val = (lightsOverride ? Mul(value.color, C(settings.lightTint)) : value.color); if (!Mathf.Approximately(key.intensity, num)) { key.intensity = num; } if (!Mathf.Approximately(key.range, num2)) { key.range = num2; } if (key.color != val) { key.color = val; } } if (flag || shadowModeWas) { LightShadows val2 = (LightShadows)((settings.lightShadowMode == 1) ? 2 : ((settings.lightShadowMode == 2) ? 1 : ((settings.lightShadowMode != 3) ? ((int)value.shadows) : 0))); if (key.shadows != val2) { key.shadows = val2; } } if (lightShadowStrengthOverride || strengthWas) { float num3 = (lightShadowStrengthOverride ? settings.lightShadowStrength : value.shadowStrength); if (!Mathf.Approximately(key.shadowStrength, num3)) { key.shadowStrength = num3; } } } lightsWas = lightsOverride; shadowModeWas = flag; strengthWas = lightShadowStrengthOverride; } private static Color Mul(Color a, Color b) { //IL_0000: 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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) return new Color(a.r * b.r, a.g * b.g, a.b * b.b, a.a); } private static void Set<T>(T cur, T want, Action<T> set) { if (!EqualityComparer<T>.Default.Equals(cur, want)) { set(want); } } } public enum UType { Float, Float2, Float3, Float4, Int, Bool, Texture } public class UniformDef { public string Name; public UType Type; public bool IsColor; public bool HasRange; public float Min; public float Max = 1f; public float Step; public string[] EnumNames; public float[] Default = new float[4]; public string File; public string Tooltip; public int Slot; public int Components => Type switch { UType.Float2 => 2, UType.Float3 => 3, UType.Float4 => 4, UType.Texture => 0, _ => 1, }; } public class PassDef { public string Entry; public float Scale = 1f; } public class ShaderDef { public string Id; public string Name; public string Category = "Custom"; public string Description = ""; public string Author = ""; public string Path; public bool BuiltIn; public string Source = ""; public DateTime LastWrite; public readonly List<UniformDef> Uniforms = new List<UniformDef>(); public readonly List<PassDef> Passes = new List<PassDef>(); public bool UsesDepth; public string ParseError; public string Body = ""; public string FileName = "shader.hlsl"; private static readonly Regex RxUniform = new Regex("^\\s*uniform\\s+(\\w+)\\s+(\\w+)\\s*(?::\\s*(\\w+)\\s*(?:\\((.*?)\\))?)?\\s*(?:=\\s*(.*?))?\\s*;\\s*(?://\\s*(.*))?$", RegexOptions.Compiled); private static readonly Regex RxPass = new Regex("^\\s*#\\s*pass\\s+(\\w+)(?:\\s+(?:scale\\s*=\\s*)?([0-9]*\\.?[0-9]+))?", RegexOptions.Compiled); private static readonly Regex RxMeta = new Regex("^\\s*//\\s*@(\\w+)\\s+(.*)$", RegexOptions.Compiled); private static readonly Regex RxNumber = new Regex("[-+]?(\\d+\\.?\\d*|\\.\\d+)([eE][-+]?\\d+)?", RegexOptions.Compiled); private static readonly Regex RxDepth = new Regex("\\b(rawDepth|linearDepth|eyeDepth|isSky|viewPos|worldPos|viewNormal|worldNormal|_Depth)\\b", RegexOptions.Compiled); private static readonly Regex RxString = new Regex("\"([^\"]*)\"", RegexOptions.Compiled); public const int MaxUniformSlots = 32; public const int MaxTextures = 4; public const int MaxPasses = 17; private static float F(string s) { if (!float.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { return 0f; } return result; } public static ShaderDef Parse(string source, string path, bool builtIn) { ShaderDef shaderDef = new ShaderDef(); shaderDef.Path = path; shaderDef.BuiltIn = builtIn; shaderDef.Source = source ?? ""; shaderDef.FileName = ((path != null) ? System.IO.Path.GetFileName(path) : "shader.hlsl"); shaderDef.Id = ((path != null) ? System.IO.Path.GetFileNameWithoutExtension(path) : "shader"); shaderDef.Name = shaderDef.Id; StringBuilder stringBuilder = new StringBuilder(); string[] array = shaderDef.Source.Replace("\r\n", "\n").Replace('\r', '\n').Split('\n'); StringBuilder stringBuilder2 = new StringBuilder(); int num = 0; int num2 = 0; for (int i = 0; i < array.Length; i++) { string text = array[i]; Match match = RxMeta.Match(text); if (match.Success) { string text2 = match.Groups[1].Value.ToLowerInvariant(); string text3 = match.Groups[2].Value.Trim(); switch (text2) { case "name": shaderDef.Name = text3; break; case "category": shaderDef.Category = text3; break; case "description": shaderDef.Description = ((shaderDef.Description.Length > 0) ? (shaderDef.Description + " ") : "") + text3; break; case "author": shaderDef.Author = text3; break; } } Match match2 = RxPass.Match(text); if (match2.Success) { PassDef passDef = new PassDef { Entry = match2.Groups[1].Value }; if (match2.Groups[2].Success) { passDef.Scale = Math.Max(0.001f, Math.Min(4f, F(match2.Groups[2].Value))); } shaderDef.Passes.Add(passDef); stringBuilder2.Append('\n'); } else if (text.TrimStart().StartsWith("uniform ", StringComparison.Ordinal)) { Match match3 = RxUniform.Match(text); if (!match3.Success) { stringBuilder.AppendLine(shaderDef.FileName + "(" + (i + 1) + "): could not parse uniform declaration"); stringBuilder2.Append('\n'); continue; } UniformDef uniformDef = new UniformDef(); uniformDef.Name = match3.Groups[2].Value; string text4 = match3.Groups[1].Value.ToLowerInvariant(); string text5 = (match3.Groups[3].Success ? match3.Groups[3].Value.ToLowerInvariant() : ""); string text6 = (match3.Groups[4].Success ? match3.Groups[4].Value : ""); string text7 = (match3.Groups[5].Success ? match3.Groups[5].Value.Trim() : ""); uniformDef.Tooltip = (match3.Groups[6].Success ? match3.Groups[6].Value.Trim() : null); switch (text4) { case "float": case "half": uniformDef.Type = UType.Float; break; case "half2": case "vec2": case "float2": uniformDef.Type = UType.Float2; break; case "half3": case "vec3": case "float3": uniformDef.Type = UType.Float3; break; case "half4": case "vec4": case "float4": uniformDef.Type = UType.Float4; break; case "color": uniformDef.Type = UType.Float4; uniformDef.IsColor = true; break; case "uint": case "int": uniformDef.Type = UType.Int; break; case "bool": uniformDef.Type = UType.Bool; break; case "sampler2d": case "texture2d": case "texture": uniformDef.Type = UType.Texture; break; default: stringBuilder.AppendLine(shaderDef.FileName + "(" + (i + 1) + "): unsupported uniform type '" + text4 + "'"); stringBuilder2.Append('\n'); continue; } if (text5 == "color" || text5 == "source_color") { uniformDef.IsColor = true; } if (text5 == "range" || text5 == "hint_range") { MatchCollection matchCollection = RxNumber.Matches(text6); if (matchCollection.Count >= 2) { uniformDef.HasRange = true; uniformDef.Min = F(matchCollection[0].Value); uniformDef.Max = F(matchCollection[1].Value); } if (matchCollection.Count >= 3) { uniformDef.Step = F(matchCollection[2].Value); } } if (text5 == "enum") { List<string> list = new List<string>(); foreach (Match item in RxString.Matches(text6)) { list.Add(item.Groups[1].Value); } if (list.Count == 0) { string[] array2 = text6.Split(','); foreach (string text8 in array2) { if (text8.Trim().Length > 0) { list.Add(text8.Trim()); } } } uniformDef.EnumNames = list.ToArray(); uniformDef.Type = UType.Int; uniformDef.HasRange = true; uniformDef.Min = 0f; uniformDef.Max = Math.Max(0, list.Count - 1); } if (text5 == "file") { Match match5 = RxString.Match(text6); uniformDef.File = (match5.Success ? match5.Groups[1].Value : text6.Trim()); } if (uniformDef.Type == UType.Texture) { if (num2 >= 4) { stringBuilder.AppendLine(shaderDef.FileName + "(" + (i + 1) + "): too many textures (max 4)"); stringBuilder2.Append('\n'); continue; } uniformDef.Slot = num2++; } else { if (num >= 32) { stringBuilder.AppendLine(shaderDef.FileName + "(" + (i + 1) + "): too many uniforms (max 32)"); stringBuilder2.Append('\n'); continue; } uniformDef.Slot = num++; if (uniformDef.IsColor) { uniformDef.Default[0] = (uniformDef.Default[1] = (uniformDef.Default[2] = (uniformDef.Default[3] = 1f))); } if (uniformDef.Type == UType.Bool) { uniformDef.Default[0] = ((text7.Trim().ToLowerInvariant() == "true" || text7.Trim() == "1") ? 1f : 0f); } else if (text7.Length > 0) { MatchCollection matchCollection2 = RxNumber.Matches(text7); string text9 = text7; int num3 = text7.IndexOf('('); if (num3 >= 0) { text9 = text7.Substring(num3 + 1); matchCollection2 = RxNumber.Matches(text9); } int num4 = Math.Min(4, matchCollection2.Count); for (int k = 0; k < num4; k++) { uniformDef.Default[k] = F(matchCollection2[k].Value); } if (num4 == 1 && uniformDef.Components > 1 && !uniformDef.IsColor) { for (int l = 1; l < 4; l++) { uniformDef.Default[l] = uniformDef.Default[0]; } } if (num4 == 1 && uniformDef.IsColor) { uniformDef.Default[1] = (uniformDef.Default[2] = uniformDef.Default[0]); } if (num4 == 3 && uniformDef.IsColor) { uniformDef.Default[3] = 1f; } } if (!uniformDef.HasRange && uniformDef.Type == UType.Int) { uniformDef.Min = 0f; uniformDef.Max = 10f; } if (!uniformDef.HasRange && (uniformDef.Type == UType.Float || uniformDef.Type == UType.Float2 || uniformDef.Type == UType.Float3 || uniformDef.Type == UType.Float4) && !uniformDef.IsColor) { float num5 = 0f; for (int m = 0; m < uniformDef.Components; m++) { num5 = Math.Max(num5, Math.Abs(uniformDef.Default[m])); } uniformDef.Min = 0f; uniformDef.Max = ((num5 > 0f) ? (num5 * 2f) : 1f); for (int n = 0; n < uniformDef.Components; n++) { if (uniformDef.Default[n] < 0f) { uniformDef.Min = 0f - uniformDef.Max; } } } } shaderDef.Uniforms.Add(uniformDef); stringBuilder2.Append('\n'); } else { stringBuilder2.Append(text).Append('\n'); } } shaderDef.Body = stringBuilder2.ToString(); if (shaderDef.Passes.Count == 0) { shaderDef.Passes.Add(new PassDef { Entry = "effect" }); } if (shaderDef.Passes.Count > 17) { stringBuilder.AppendLine(shaderDef.FileName + ": too many passes (max " + 17 + ")"); } shaderDef.UsesDepth = RxDepth.IsMatch(shaderDef.Body); shaderDef.ParseError = ((stringBuilder.Length > 0) ? stringBuilder.ToString() : null); return shaderDef; } public bool IsFinalPass(int i) { return i == Passes.Count - 1; } public string Generate(int passIndex, string prelude, bool lineDirectives) { StringBuilder stringBuilder = new StringBuilder(prelude.Length + Body.Length + 2048); stringBuilder.Append(prelude).Append('\n'); foreach (UniformDef uniform in Uniforms) { switch (uniform.Type) { case UType.Float: stringBuilder.Append("static float ").Append(uniform.Name).Append(";\n"); break; case UType.Float2: stringBuilder.Append("static float2 ").Append(uniform.Name).Append(";\n"); break; case UType.Float3: stringBuilder.Append("static float3 ").Append(uniform.Name).Append(";\n"); break; case UType.Float4: stringBuilder.Append("static float4 ").Append(uniform.Name).Append(";\n"); break; case UType.Int: stringBuilder.Append("static int ").Append(uniform.Name).Append(";\n"); break; case UType.Bool: stringBuilder.Append("static bool ").Append(uniform.Name).Append(";\n"); break; case UType.Texture: stringBuilder.Append("#define ").Append(uniform.Name).Append(" _Tex") .Append(uniform.Slot) .Append('\n'); break; } } if (lineDirectives) { stringBuilder.Append("#line 1 \"").Append(FileName.Replace("\"", "")).Append("\"\n"); } stringBuilder.Append(Body); stringBuilder.Append("\nfloat4 _SS_Main(float4 _ss_pos : SV_Position) : SV_Target\n{\n"); stringBuilder.Append(" float2 _ss_uv = _ss_pos.xy * _OutSize.zw;\n"); stringBuilder.Append(" if (_Flags.z > 0.5) _ss_uv.y = 1.0 - _ss_uv.y;\n"); stringBuilder.Append(" PIXEL = _ss_uv * _OutSize.xy;\n"); foreach (UniformDef uniform2 in Uniforms) { string value = "P[" + uniform2.Slot + "]"; switch (uniform2.Type) { case UType.Float: stringBuilder.Append(" ").Append(uniform2.Name).Append(" = ") .Append(value) .Append(".x;\n"); break; case UType.Float2: stringBuilder.Append(" ").Append(uniform2.Name).Append(" = ") .Append(value) .Append(".xy;\n"); break; case UType.Float3: stringBuilder.Append(" ").Append(uniform2.Name).Append(" = ") .Append(value) .Append(".xyz;\n"); break; case UType.Float4: stringBuilder.Append(" ").Append(uniform2.Name).Append(" = ") .Append(value) .Append(";\n"); break; case UType.Int: stringBuilder.Append(" ").Append(uniform2.Name).Append(" = (int)round(") .Append(value) .Append(".x);\n"); break; case UType.Bool: stringBuilder.Append(" ").Append(uniform2.Name).Append(" = ") .Append(value) .Append(".x > 0.5;\n"); break; } } stringBuilder.Append(" float4 _ss_c = _SS_ToF4(").Append(Passes[passIndex].Entry).Append("(_ss_uv));\n"); if (IsFinalPass(passIndex)) { stringBuilder.Append(" _ss_c = lerp(scene(_ss_uv), _ss_c, _Mix.x);\n"); } stringBuilder.Append(" return _ss_c;\n}\n"); return stringBuilder.ToString(); } public static string NewShaderTemplate(string name) { return "// @name " + name + "\n// @category Custom\n// @description My own effect. Edit me, then press Save & Compile (Ctrl+S).\n\nuniform float strength : range(0, 1) = 0.5; // how strong the effect is\nuniform float3 tint : color = float3(1.0, 0.7, 0.4);\nuniform float speed : range(0, 5) = 1.0;\n\nfloat4 effect(float2 uv)\n{\n // wobble the image a little\n float2 offset = float2(sin(uv.y * 30.0 + TIME * speed), cos(uv.x * 30.0 + TIME * speed)) * 0.003 * strength;\n float3 col = scene(uv + offset).rgb;\n\n // tint the shadows\n float l = luma(col);\n col = lerp(col, col * tint, strength * (1.0 - l));\n\n return float4(col, 1.0);\n}\n"; } } public class StudioUI { private readonly Studio S; private Rect win = new Rect(60f, 60f, 1000f, 700f); private int tab; private static readonly string[] Tabs = new string[7] { "Effects", "Library", "Code Editor", "Presets", "Unity FX", "Rendering", "Settings & Help" }; private GUISkin skin; private GUIStyle hStyle; private GUIStyle h2Style; private GUIStyle smallStyle; private GUIStyle dimStyle; private GUIStyle codeStyle; private GUIStyle lineNoStyle; private GUIStyle errStyle; private GUIStyle okStyle; private GUIStyle warnStyle; private GUIStyle tabOn; private GUIStyle tabOff; private GUIStyle panel; private GUIStyle card; private GUIStyle toastStyle; private GUIStyle titleStyle; private GUIStyle chipStyle; private Texture2D white; private Font mono; private int monoSize; private string toastText; private float toastUntil; private readonly Dictionary<string, string> numBuf = new Dictionary<string, string>(); private Vector2 scStack; private Vector2 scLib; private Vector2 scEdit; private Vector2 scErr; private Vector2 scPresets; private Vector2 scFx; private Vector2 scRender; private Vector2 scHelp; private Vector2 scPick; private bool resizing; private Vector2 resizeStart; private Rect resizeWin; private string search = ""; private string category = "All"; private string newShaderName = "My Shader"; private string confirmDelete; private float confirmUntil; private string edId; private string edText = ""; private string edLineNumbers = ""; private bool edDirty; private bool edPicker; private int edLineCount = -1; private float edMaxWidth = 600f; private string presetName = "My Preset"; private string presetDesc = ""; private bool presetIncRendering = true; private bool presetIncUnity = true; private readonly HashSet<string> fxExpanded = new HashSet<string>(); private static readonly Regex RxErr = new Regex("^.*?\\((\\d+),(\\d+)(?:-\\d+)?\\):\\s*(error|warning)\\s*(\\w+)?:\\s*(.*)$", RegexOptions.Multiline); private const string HelpText = "Every effect is a plain HLSL file (DirectX shader code) - the same idea as Godot's shader language.\nWrite a function that returns the new color of a pixel:\n\n float4 effect(float2 uv) { return scene(uv) * float4(1, 0.5, 0.5, 1); }\n\nuv goes from (0,0) bottom-left to (1,1) top-right. scene(uv) reads the game image.\n\nSliders come from uniforms:\n uniform float strength : range(0, 2) = 1.0; // tooltip\n uniform float3 tint : color = float3(1, 0.5, 0.2);\n uniform int mode : enum(\"Soft\", \"Hard\") = 0;\n uniform bool invert = false;\n uniform texture2D lut : file(\"lut.png\"); then tex(lut, uv)\n\nUseful built-ins: TIME, RES, TEXEL, PIXEL, scene(), history() (last frame), eyeDepth(uv), worldPos(uv), worldNormal(uv),\nviewNormal(uv), isSky(uv), luma(), rgb2hsv(), hsv2rgb(), valueNoise(), fbm(), voronoi(), hash12(), bayer8(), discBlur(), rot2().\n\nMulti-pass: #pass Name 0.5 declares a pass at half resolution (function float4 Name(float2 uv)). The last #pass is the output.\nRead earlier passes with samplePass(index, uv).\n\nYour shaders live in BepInEx/config/ShaderStudio/shaders and hot-reload when you save them in any editor.\nBuilt-in shaders can be viewed; saving one creates your own copy.\nAvoid naming uniforms like built-in functions (scene, contrast, saturation, luma...) or HLSL keywords (line, point, sample, linear)."; public StudioUI(Studio s) { //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) S = s; } public void Toast(string msg) { toastText = msg; toastUntil = Time.unscaledTime + 4f; Plugin.Log.LogInfo((object)msg); } private static Texture2D Tex(Color c) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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) //IL_0014: 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) //IL_0021: Expected O, but got Unknown Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false) { hideFlags = (HideFlags)61 }; val.SetPixel(0, 0, c); val.Apply(); return val; } private void InitStyles() { //IL_08eb: Unknown result type (might be due to invalid IL or missing references) //IL_08f0: Unknown result type (might be due to invalid IL or missing references) //IL_08fc: Unknown result type (might be due to invalid IL or missing references) //IL_0908: Unknown result type (might be due to invalid IL or missing references) //IL_090f: Unknown result type (might be due to invalid IL or missing references) //IL_0916: Unknown result type (might be due to invalid IL or missing references) //IL_091b: Unknown result type (might be due to invalid IL or missing references) //IL_0925: Expected O, but got Unknown //IL_092a: Expected O, but got Unknown //IL_0944: Unknown result type (might be due to invalid IL or missing references) //IL_0968: Unknown result type (might be due to invalid IL or missing references) //IL_097e: Unknown result type (might be due to invalid IL or missing references) //IL_0983: Unknown result type (might be due to invalid IL or missing references) //IL_098f: Unknown result type (might be due to invalid IL or missing references) //IL_099b: Unknown result type (might be due to invalid IL or missing references) //IL_09a2: Unknown result type (might be due to invalid IL or missing references) //IL_09a7: Unknown result type (might be due to invalid IL or missing references) //IL_09b1: Expected O, but got Unknown //IL_09b1: Unknown result type (might be due to invalid IL or missing references) //IL_09bd: Expected O, but got Unknown //IL_09d7: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0123: 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_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Expected O, but got Unknown //IL_01cd: 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_022a: Unknown result type (might be due to invalid IL or missing references) //IL_023a: 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_025a: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Expected O, but got Unknown //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_0381: Unknown result type (might be due to invalid IL or missing references) //IL_03ef: Unknown result type (might be due to invalid IL or missing references) //IL_0409: Unknown result type (might be due to invalid IL or missing references) //IL_0432: Unknown result type (might be due to invalid IL or missing references) //IL_04c3: Unknown result type (might be due to invalid IL or missing references) //IL_0538: Unknown result type (might be due to invalid IL or missing references) //IL_053d: Unknown result type (might be due to invalid IL or missing references) //IL_0545: Unknown result type (might be due to invalid IL or missing references) //IL_0551: Expected O, but got Unknown //IL_056b: Unknown result type (might be due to invalid IL or missing references) //IL_0581: Unknown result type (might be due to invalid IL or missing references) //IL_0586: Unknown result type (might be due to invalid IL or missing references) //IL_058e: Unknown result type (might be due to invalid IL or missing references) //IL_059a: Expected O, but got Unknown //IL_05a5: Unknown result type (might be due to invalid IL or missing references) //IL_05bb: Unknown result type (might be due to invalid IL or missing references) //IL_05c0: Unknown result type (might be due to invalid IL or missing references) //IL_05c8: Unknown result type (might be due to invalid IL or missing references) //IL_05d4: Expected O, but got Unknown //IL_05ee: Unknown result type (might be due to invalid IL or missing references) //IL_0604: Unknown result type (might be due to invalid IL or missing references) //IL_0609: Unknown result type (might be due to invalid IL or missing references) //IL_0611: Unknown result type (might be due to invalid IL or missing references) //IL_061d: Expected O, but got Unknown //IL_0637: Unknown result type (might be due to invalid IL or missing references) //IL_0648: Unknown result type (might be due to invalid IL or missing references) //IL_064d: Unknown result type (might be due to invalid IL or missing references) //IL_0659: Expected O, but got Unknown //IL_0673: Unknown result type (might be due to invalid IL or missing references) //IL_0684: Unknown result type (might be due to invalid IL or missing references) //IL_068e: Expected O, but got Unknown //IL_06a8: Unknown result type (might be due to invalid IL or missing references) //IL_06b9: Unknown result type (might be due to invalid IL or missing references) //IL_06c3: Expected O, but got Unknown //IL_06dd: Unknown result type (might be due to invalid IL or missing references) //IL_06ee: Unknown result type (might be due to invalid IL or missing references) //IL_06f8: Expected O, but got Unknown //IL_0712: Unknown result type (might be due to invalid IL or missing references) //IL_0728: Unknown result type (might be due to invalid IL or missing references) //IL_072d: Unknown result type (might be due to invalid IL or missing references) //IL_0735: Unknown result type (might be due to invalid IL or missing references) //IL_0745: Expected O, but got Unknown //IL_074c: Unknown result type (might be due to invalid IL or missing references) //IL_0756: Expected O, but got Unknown //IL_0785: Unknown result type (might be due to invalid IL or missing references) //IL_079b: Unknown result type (might be due to invalid IL or missing references) //IL_07a0: Unknown result type (might be due to invalid IL or missing references) //IL_07a5: Unknown result type (might be due to invalid IL or missing references) //IL_07af: Expected O, but got Unknown //IL_07af: Unknown result type (might be due to invalid IL or missing references) //IL_07b4: Unknown result type (might be due to invalid IL or missing references) //IL_07be: Expected O, but got Unknown //IL_07c3: Expected O, but got Unknown //IL_07cf: Unknown result type (might be due to invalid IL or missing references) //IL_07d4: Unknown result type (might be due to invalid IL or missing references) //IL_07d9: Unknown result type (might be due to invalid IL or missing references) //IL_07e3: Expected O, but got Unknown //IL_07e3: Unknown result type (might be due to invalid IL or missing references) //IL_07e8: Unknown result type (might be due to invalid IL or missing references) //IL_07f2: Expected O, but got Unknown //IL_07f7: Expected O, but got Unknown //IL_07fe: Unknown result type (might be due to invalid IL or missing references) //IL_0803: Unknown result type (might be due to invalid IL or missing references) //IL_0810: Expected O, but got Unknown //IL_082a: Unknown result type (might be due to invalid IL or missing references) //IL_0840: Unknown result type (might be due to invalid IL or missing references) //IL_0845: Unknown result type (might be due to invalid IL or missing references) //IL_084d: Unknown result type (might be due to invalid IL or missing references) //IL_0854: Unknown result type (might be due to invalid IL or missing references) //IL_085b: Unknown result type (might be due to invalid IL or missing references) //IL_0865: Expected O, but got Unknown //IL_0865: Unknown result type (might be due to invalid IL or missing references) //IL_0871: Expected O, but got Unknown //IL_087c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)skin != (Object)null && (Object)(object)mono != (Object)null && monoSize == S.EditorFontSize.Value) { return; } if ((Object)(object)skin == (Object)null) { skin = Object.Instantiate<GUISkin>(GUI.skin); ((Object)skin).hideFlags = (HideFlags)61; white = Tex(Color.white); Texture2D background = Tex(new Color(0.08f, 0.085f, 0.1f, 0.97f)); Texture2D background2 = Tex(new Color(0.13f, 0.135f, 0.16f, 1f)); Texture2D background3 = Tex(new Color(0.2f, 0.21f, 0.25f, 1f)); Texture2D background4 = Tex(new Color(0.27f, 0.29f, 0.35f, 1f)); Texture2D background5 = Tex(new Color(0.18f, 0.45f, 0.75f, 1f)); Texture2D background6 = Tex(new Color(0.05f, 0.055f, 0.065f, 1f)); Texture2D background7 = Tex(new Color(0.22f, 0.55f, 0.95f, 1f)); skin.window.normal.background = background; skin.window.onNormal.background = background; skin.window.padding = new RectOffset(10, 10, 30, 10); skin.box.normal.background = background2; skin.box.normal.textColor = new Color(0.85f, 0.87f, 0.9f); GUIStyle[] array = (GUIStyle[])(object)new GUIStyle[2] { skin.button, skin.toggle }; foreach (GUIStyle obj in array) { obj.normal.textColor = new Color(0.88f, 0.9f, 0.94f); obj.hover.textColor = Color.white; obj.active.textColor = Color.white; obj.onNormal.textColor = Color.white; obj.onHover.textColor = Color.white; obj.fontSize = 13; } skin.button.normal.background = background3; skin.button.hover.background = background4; skin.button.active.background = background5; skin.button.onNormal.background = background5; skin.button.onHover.background = background5; skin.button.border = new RectOffset(2, 2, 2, 2); skin.textField.normal.background = background6; skin.textField.focused.background = background6; skin.textField.hover.background = background6; skin.textField.normal.textColor = new Color(0.9f, 0.92f, 0.95f); skin.textField.focused.textColor = Color.white; skin.textArea.normal.background = background6; skin.textArea.focused.background = background6; skin.textArea.hover.background = background6; skin.textArea.normal.textColor = new Color(0.9f, 0.92f, 0.95f); skin.textArea.focused.textColor = Color.white; skin.label.normal.textColor = new Color(0.85f, 0.87f, 0.9f); skin.label.fontSize = 13; skin.label.wordWrap = false; skin.horizontalSlider.normal.background = background6; skin.horizontalSliderThumb.normal.background = background7; skin.horizontalSliderThumb.hover.background = background5; skin.horizontalSliderThumb.active.background = Tex(new Color(0.5f, 0.75f, 1f)); skin.verticalScrollbar.normal.background = background6; skin.verticalScrollbarThumb.normal.background = background4; skin.horizontalScrollbar.normal.background = background6; skin.horizontalScrollbarThumb.normal.background = background4; titleStyle = new GUIStyle(skin.label) { fontSize = 15, fontStyle = (FontStyle)1 }; titleStyle.normal.textColor = new Color(0.55f, 0.8f, 1f); hStyle = new GUIStyle(skin.label) { fontSize = 14, fontStyle = (FontStyle)1 }; hStyle.normal.textColor = Color.white; h2Style = new GUIStyle(skin.label) { fontSize = 13, fontStyle = (FontStyle)1 }; h2Style.normal.textColor = new Color(0.75f, 0.85f, 1f); smallStyle = new GUIStyle(skin.label) { fontSize = 12, wordWrap = true }; smallStyle.normal.textColor = new Color(0.7f, 0.72f, 0.76f); dimStyle = new GUIStyle(smallStyle) { wordWrap = false }; dimStyle.normal.textColor = new Color(0.55f, 0.57f, 0.62f); errStyle = new GUIStyle(smallStyle); errStyle.normal.textColor = new Color(1f, 0.45f, 0.4f); okStyle = new GUIStyle(dimStyle); okStyle.normal.textColor = new Color(0.45f, 0.9f, 0.5f); warnStyle = new GUIStyle(smallStyle); warnStyle.normal.textColor = new Color(1f, 0.8f, 0.35f); tabOff = new GUIStyle(skin.button) { fontSize = 13, fixedHeight = 28f }; tabOn = new GUIStyle(tabOff); tabOn.normal.background = background5; tabOn.hover.background = background5; tabOn.normal.textColor = Color.white; panel = new GUIStyle(skin.box) { padding = new RectOffset(8, 8, 6, 6), margin = new RectOffset(2, 2, 2, 4) }; card = new GUIStyle(skin.box) { padding = new RectOffset(8, 8, 6, 8), margin = new RectOffset(0, 4, 2, 6) }; chipStyle = new GUIStyle(dimStyle) { fontSize = 11 }; chipStyle.normal.textColor = new Color(0.6f, 0.75f, 0.95f); toastStyle = new GUIStyle(skin.box) { fontSize = 14, alignment = (TextAnchor)4, padding = new RectOffset(14, 14, 8, 8), wordWrap = true }; toastStyle.normal.textColor = Color.white; } monoSize = S.EditorFontSize.Value; try { mono = Font.CreateDynamicFontFromOSFont(new string[4] { "Consolas", "Cascadia Mono", "Courier New", "Lucida Console" }, monoSize); } catch { mono = null; } codeStyle = new GUIStyle(skin.textArea) { font = mono, fontSize = monoSize, wordWrap = false, richText = false, padding = new RectOffset(6, 6, 4, 4) }; codeStyle.normal.textColor = new Color(0.86f, 0.9f, 0.86f); codeStyle.focused.textColor = new Color(0.9f, 0.95f, 0.9f); lineNoStyle = new GUIStyle(skin.label) { font = mono, fontSize = monoSize, alignment = (TextAnchor)2, padding = new RectOffset(0, 6, 4, 4), wordWrap = false }; lineNoStyle.normal.textColor = new Color(0.4f, 0.43f, 0.5f); } public void Draw() { //IL_000b: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0106: 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_0121: Expected O, but got Unknown //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Expected O, but got Unknown //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) InitStyles(); GUISkin obj = GUI.skin; Matrix4x4 matrix = GUI.matrix; GUI.skin = skin; float num = Mathf.Clamp(S.UIScale.Value, 0.6f, 2.5f); GUI.matrix = Matrix4x4.Scale(new Vector3(num, num, 1f)); float num2 = (float)Screen.width / num; float num3 = (float)Screen.height / num; ((Rect)(ref win)).width = Mathf.Clamp(((Rect)(ref win)).width, 640f, num2); ((Rect)(ref win)).height = Mathf.Clamp(((Rect)(ref win)).height, 400f, num3); ((Rect)(ref win)).x = Mathf.Clamp(((Rect)(ref win)).x, 0f, num2 - ((Rect)(ref win)).width); ((Rect)(ref win)).y = Mathf.Clamp(((Rect)(ref win)).y, 0f, num3 - ((Rect)(ref win)).height); win = GUI.Window(23251, win, new WindowFunction(DrawWindow), ""); if (!string.IsNullOrEmpty(GUI.tooltip)) { Vector2 mousePosition = Event.current.mousePosition; GUIContent val = new GUIContent(GUI.tooltip); Vector2 val2 = toastStyle.CalcSize(val); val2.x = Mathf.Min(val2.x, 420f); float num4 = toastStyle.CalcHeight(val, val2.x); GUI.Box(new Rect(Mathf.Min(mousePosition.x + 16f, num2 - val2.x - 4f), mousePosition.y + 18f, val2.x, num4), val, toastStyle); } if (toastText != null && Time.unscaledTime < toastUntil) { GUI.Box(new Rect(num2 * 0.5f - 260f, num3 - 70f, 520f, 44f), toastText, toastStyle); } GUI.matrix = matrix; GUI.skin = obj; } private void DrawWindow(int id) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Invalid comparison between Unknown and I4 //IL_022a: Unknown result type (might be due to invalid IL or missing refe