-- LocalScript: RTX Ultra Shader Studio v6.0 (Pro Lighting Engine, Config Manager & EN/RU UI) -- Place in: StarterPlayer -> StarterPlayerScripts local Players = game:GetService("Players") local Lighting = game:GetService("Lighting") local TweenService = game:GetService("TweenService") local RunService = game:GetService("RunService") local UserInputService = game:GetService("UserInputService") local HttpService = game:GetService("HttpService") local Debris = game:GetService("Debris") local player = Players.LocalPlayer local camera = workspace.CurrentCamera -------------------------------------------------------------------- -- 1. ЯЗЫКОВАЯ СИСТЕМА (DEFAULT: EN, SWITCHABLE: EN / RU) -------------------------------------------------------------------- local currentLang = "EN" local i18nListeners = {} local I18N = { EN = { appTitle = "✨ RTX SHADER STUDIO v6.0", searchPlaceholder = "🔍 Search settings (e.g. bloom, shadow, fog, kelvin)...", btnResetAll = "🔄 Reset All", btnHideUI = "👁️ Hide [H]", stateOn = "ON", stateOff = "OFF", -- Tabs tab_SkyWeather = "☀️ Sky & Weather", tab_LightShadows = "💡 Light & Shadows", tab_StudioRig = "🔦 3-Point Studio", tab_AtmoWorld = "🌫️ Atmo & World", tab_PostFX = "🎨 Color & PostFX", tab_Camera = "📸 Camera & Optics", tab_Configs = "💾 Configs", -- Sections sec_Sunset = "🌅 SUNSET & SKY REALISM", sec_TimeCelestial = "🕒 TIME OF DAY & CELESTIAL BODIES", sec_Weather = "🌦️ WEATHER & PARTICLES", sec_LightMode = "⚙️ LIGHTING ENGINE MODE & PRESETS", sec_DirectShadows = "💡 DIRECT LIGHT, KELVIN & SHADOWS", sec_AmbientPBR = "🏙️ AMBIENT, PBR & COLOR SHIFTS", sec_ManualRGB = "🎨 MANUAL RGB LIGHT OVERRIDES", sec_StudioRig = "🔦 3-POINT STUDIO LIGHTING RIG", sec_Atmosphere = "🌫️ AERIAL ATMOSPHERE", sec_ClassicFog = "🌁 CLASSIC ROBLOX FOG (WHEN ATMOSPHERE OFF)", sec_CloudsWind = "☁️ 3D VOLUMETRIC CLOUDS & WIND", sec_Water = "🌊 TERRAIN WATER", sec_LUTs = "🎬 COLOR GRADING PRESETS (LUTS)", sec_ColorCorrection = "🌈 COLOR CORRECTION & TONING", sec_BloomRaysBlur = "✨ BLOOM, SUN RAYS & MOTION BLUR", sec_DoF = "📷 DEPTH OF FIELD (DOF)", sec_LensCinema = "🎞️ LENS, BOKEH, VIGNETTE & LETTERBOX", sec_Freecam = "🦅 FREECAM & PLAYER PHYSICS", sec_BuiltInPresets = "⭐ BUILT-IN LIGHTING PRESETS", sec_CustomConfigs = "💾 CREATE & MANAGE CUSTOM CONFIGS", sec_ImportExport = "📋 IMPORT / EXPORT CONFIG JSON", -- Sunset Styles style_Realistic = "Realistic", style_PastelPink = "Pastel Pink", style_ColdNordic = "Cold Nordic", style_WarmCinema = "Warm Cinema", -- Weather Names w_Clear = "☀️ Clear", w_Cloudy = "⛅ Cloudy", w_Overcast = "☁️ Overcast", w_Rain = "🌧️ Rain & Storm", w_Snow = "❄️ Snow", w_Fog = "🌫️ Dense Fog", w_Cyberpunk = "🔮 Cyberpunk", -- Quick Times qt_Dawn = "🌄 Dawn (05:10)", qt_Sunrise = "🌅 Sunrise (06:20)", qt_Noon = "☀️ Noon (12:00)", qt_Sunset = "🌇 Sunset (17:50)", qt_Dusk = "🌆 Afterglow (18:35)", qt_Midnight = "🌌 Midnight (00:00)", -- Controls: Sky & Weather sunsetWarmth = "Horizon Sunset Warmth", clockTime = "Clock Time (Hours)", autoTime = "⏳ Dynamic Time Progression", timeSpeed = "Seconds per Game Minute", latitude = "Geographic Latitude (Sun Orbit)", sunSize = "Sun Disk Size (SunAngularSize)", moonSize = "Moon Disk Size (MoonAngularSize)", starCount = "Night Star Count", celestialShown = "Show Sun & Moon", rainRate = "Rain Intensity Multiplier", wetReflectance = "Wet Surface Reflectance (Rain)", rainVolume = "Rain Audio Volume", rainSplashes = "💧 3D Ground Rain Splashes", dustRate = "Atmospheric Sun Dust Particles", btnLightning = "⚡ Trigger Lightning Strike Now", -- Controls: Light & Shadows sp_SharpRTX = "💎 Sharp RTX", sp_SoftReal = "🎬 Soft Realistic", sp_HighContrast = "⚡ High Contrast", sp_SoftDiffused = "☁️ Soft Diffused", sp_DarkCinema = "🎭 Dark Cinema", sp_MaxFPS = "🚀 Shadows OFF (FPS)", fullManualMode = "🎛️ Full Manual Studio Mode (Ignore Time Colors)", globalShadows = "🌑 Global Shadows", rtxReflections = "✨ RTX Specular & Wet Reflections", colorTemp = "Color Temperature (Kelvin)", tempTint = "Green / Magenta Tint Shift", brightnessMult = "Sun Brightness Multiplier", manualBrightness = "Manual Base Brightness (Studio Mode)", exposure = "Camera Exposure (EV)", shadowSoftness = "Shadow Edge Softness", outdoorBoost = "Outdoor Ambient Shadow Boost", ambientBoost = "Indoor Ambient Boost", specularScale = "PBR Specular Scale", diffuseScale = "PBR Diffuse Scale", manualLightColors = "🎨 Enable Manual RGB Light Colors", col_Top = "☀️ Direct Top Light (ColorShift_Top)", col_Bot = "🌤️ Bottom Bounce (ColorShift_Bottom)", col_Outdoor = "🏙️ Outdoor Shadows (OutdoorAmbient)", col_Ambient = "🏠 Indoor Base Ambient (Ambient)", -- Controls: 3-Point Studio Rig rigEnabled = "🔦 Enable 3-Point Studio Lighting Rig", rigMode_Camera = "📹 Attach to Camera", rigMode_Char = "🧍 Attach to Character", rigMode_World = "📍 Lock in World Here", rigShadows = "Cast Studio Rig Shadows", rigDistance = "Rig Distance from Subject", keyBright = "Key Light Brightness (Main)", keyRange = "Key Light Range", col_Key = "Key Light Color", fillBright = "Fill Light Brightness (Soft)", fillRange = "Fill Light Range", col_Fill = "Fill Light Color", rimBright = "Rim / Back Light Brightness", rimRange = "Rim Light Range", col_Rim = "Rim Light Color", -- Controls: Atmo & World atmoEnabled = "🌫️ Enable Aerial Atmosphere (Off = Classic Fog)", atmoDensity = "Atmosphere Density Multiplier", atmoOffset = "Atmosphere Horizon Offset", atmoHaze = "Additional Horizon Haze", atmoGlare = "Sun Atmospheric Glare Multiplier", manualAtmoColors = "🎨 Custom RGB Atmosphere Colors", col_Atmo = "🌫️ Atmosphere Main Color", col_Decay = "🌇 Atmosphere Horizon Decay", fogStart = "Classic Fog Start Distance", fogEnd = "Classic Fog End Distance", col_Fog = "🌁 Classic Fog Color", cloudsEnabled = "☁️ Enable 3D Volumetric Clouds", cloudCover = "Cloud Cover (-0.05 = Weather Auto)", cloudDensity = "Cloud Density (-0.05 = Weather Auto)", manualCloudColor = "🎨 Custom RGB Cloud Color", col_Cloud = "☁️ 3D Clouds Color", windSpeed = "Global Wind Speed", windAngle = "Wind Direction (Degrees)", waterWaveSize = "Water Wave Height", waterWaveSpeed = "Water Wave Speed", waterReflect = "Water Reflectance", waterTrans = "Water Transparency", col_Water = "🌊 Water Color", -- Controls: Color & PostFX lut_Natural = "✨ Natural Realism", lut_Clean = "📷 Clean Neutral", lut_Film = "🎬 Soft Film", lut_Blockbuster = "🍿 Blockbuster", lut_Pastel = "🌅 Pastel Vintage", lut_Nordic = "❄️ Nordic Cold", lut_Cyber = "🔮 Neon Cyber", lut_Noir = "🎞️ B&W Noir", ccEnabled = "Enable Color Correction", ccBrightness = "Frame Brightness Shift", ccSaturation = "Saturation Offset", ccContrast = "Contrast Offset", col_Tint = "🎨 Color Grading Filter (TintColor)", bloomEnabled = "Enable Bloom Glow", bloomIntensity = "Bloom Intensity", bloomSize = "Bloom Radius Size", bloomThreshold = "Bloom Threshold", sunRaysEnabled = "Enable Sun Rays (Godrays)", sunRaysMult = "Sun Rays Intensity Multiplier", sunRaysSpread = "Sun Rays Spread Width", blurSize = "Static Screen Blur Size", motionBlur = "💨 Dynamic Camera Motion Blur", motionBlurStrength = "Motion Blur Sensitivity", -- Controls: Camera & Optics dofEnabled = "📷 Enable Depth of Field (DoF)", dofAuto = "🎯 Smart Raycast Auto-Focus", dofFar = "Far Background Blur Intensity", dofNear = "Near Foreground Blur Intensity", dofDist = "Manual Focus Distance", dofRadius = "In-Focus Sharpness Radius", fov = "Camera Field of View (FOV)", camRoll = "Camera Horizon Roll (°)", cinemaBars = "🎬 Cinematic Letterbox Bars", cinemaHeight = "Letterbox Bar Height", vignette = "🌑 Soft Screen Vignette", vignetteOpacity = "Vignette Darkness", lensFlare = "☀️ Optical Sun Bokeh & Lens Flare", flareIntensity = "Lens Flare Intensity", freecam = "🦅 Freecam Mode (WASD + Q/E + Hold RMB)", freecamSpeed = "Freecam Flight Speed", walkSpeed = "Character WalkSpeed", gravity = "World Gravity", -- Controls: Configs cfgNamePlaceholder = "Enter new config name...", btnSaveCfg = "➕ Save Current as New Config", btnExportCurrent = "📤 Export Current to Box", btnImportBox = "📥 Apply JSON from Box", jsonPlaceholder = "Paste config JSON here to import, or click Export...", cfgSavedMsg = "Saved!", cfgLoadedMsg = "Loaded!", cfgInvalidMsg = "Invalid JSON!", btnLoad = "Load", btnDelete = "✕", }, RU = { appTitle = "✨ RTX SHADER STUDIO v6.0", searchPlaceholder = "🔍 Поиск настроек (напр. bloom, тени, туман, закат)...", btnResetAll = "🔄 Сбросить всё", btnHideUI = "👁️ Скрыть [H]", stateOn = "ВКЛ", stateOff = "ВЫКЛ", -- Tabs tab_SkyWeather = "☀️ Небо и Погода", tab_LightShadows = "💡 Свет и Тени", tab_StudioRig = "🔦 3-Точ. Студия", tab_AtmoWorld = "🌫️ Атмосфера", tab_PostFX = "🎨 Цвет и FX", tab_Camera = "📸 Камера", tab_Configs = "💾 Конфиги", -- Sections sec_Sunset = "🌅 РЕАЛИЗМ ЗАКАТА И НЕБА", sec_TimeCelestial = "🕒 ВРЕМЯ СУТОК И НЕБЕСНЫЕ ТЕЛА", sec_Weather = "🌦️ ПОГОДА И ЧАСТИЦЫ", sec_LightMode = "⚙️ РЕЖИМ ОСВЕЩЕНИЯ И ПРЕСЕТЫ ТЕНЕЙ", sec_DirectShadows = "💡 ПРЯМОЙ СВЕТ, КЕЛЬВИНЫ И ТЕНИ", sec_AmbientPBR = "🏙️ ОКРУЖЕНИЕ, PBR И ПОЛУТОНА", sec_ManualRGB = "🎨 РУЧНОЙ RGB-ПЕРЕХВАТ СВЕТА", sec_StudioRig = "🔦 3-ТОЧЕЧНЫЙ СТУДИЙНЫЙ СВЕТ (RIG)", sec_Atmosphere = "🌫️ ВОЗДУШНАЯ АТМОСФЕРА", sec_ClassicFog = "🌁 КЛАССИЧЕСКИЙ ТУМАН (КОГДА АТМОСФЕРА ВЫКЛ)", sec_CloudsWind = "☁️ ОБЪЁМНЫЕ 3D-ОБЛАКА И ВЕТЕР", sec_Water = "🌊 ВОДА (TERRAIN WATER)", sec_LUTs = "🎬 ПРЕСЕТЫ ЦВЕТОКОРРЕКЦИИ (LUT)", sec_ColorCorrection = "🌈 ТОНКАЯ ЦВЕТОКОРРЕКЦИЯ", sec_BloomRaysBlur = "✨ СВЕЧЕНИЕ (BLOOM), ЛУЧИ И РАЗМЫТИЕ", sec_DoF = "📷 ГЛУБИНА РЕЗКОСТИ (DOF)", sec_LensCinema = "🎞️ ОПТИКА, БЛИКИ, ВИНЬЕТКА И КИНО", sec_Freecam = "🦅 СВОБОДНАЯ КАМЕРА И ФИЗИКА", sec_BuiltInPresets = "⭐ ГОТОВЫЕ СТУДИЙНЫЕ ПРЕСЕТЫ", sec_CustomConfigs = "💾 СОЗДАНИЕ И СПИСОК СВОИХ КОНФИГОВ", sec_ImportExport = "📋 ИМПОРТ / ЭКСПОРТ КОНФИГА (JSON-КОД)", -- Sunset Styles style_Realistic = "Реалистичный", style_PastelPink = "Пастельный розовый", style_ColdNordic = "Холодный северный", style_WarmCinema = "Тёплый кино", -- Weather Names w_Clear = "☀️ Ясно", w_Cloudy = "⛅ Облачно", w_Overcast = "☁️ Пасмурно", w_Rain = "🌧️ Дождь и Гроза", w_Snow = "❄️ Снег", w_Fog = "🌫️ Густой туман", w_Cyberpunk = "🔮 Киберпанк", -- Quick Times qt_Dawn = "🌄 Сумерки (05:10)", qt_Sunrise = "🌅 Рассвет (06:20)", qt_Noon = "☀️ Полдень (12:00)", qt_Sunset = "🌇 Закат (17:50)", qt_Dusk = "🌆 Зарево (18:35)", qt_Midnight = "🌌 Полночь (00:00)", -- Controls: Sky & Weather sunsetWarmth = "Теплота горизонта на закате", clockTime = "Время суток (Часы)", autoTime = "⏳ Автоматический ход времени", timeSpeed = "Секунд на 1 игровую минуту", latitude = "Географическая широта (Орбита)", sunSize = "Размер диска Солнца", moonSize = "Размер диска Луны", starCount = "Количество звёзд ночью", celestialShown = "Показывать Солнце и Луну", rainRate = "Интенсивность ливня", wetReflectance = "Зеркальность мокрой земли", rainVolume = "Громкость звука дождя", rainSplashes = "💧 3D-круги капель на земле", dustRate = "Солнечная пыльца в воздухе", btnLightning = "⚡ Ударить молнией сейчас", -- Controls: Light & Shadows sp_SharpRTX = "💎 Чёткие RTX", sp_SoftReal = "🎬 Мягкий реализм", sp_HighContrast = "⚡ Контрастные", sp_SoftDiffused = "☁️ Рассеянные", sp_DarkCinema = "🎭 Кино-Драма", sp_MaxFPS = "🚀 Без теней (FPS)", fullManualMode = "🎛️ Полный ручной режим (Откл. цвета суток)", globalShadows = "🌑 Глобальные тени (GlobalShadows)", rtxReflections = "✨ RTX Отражения и блики", colorTemp = "Температура света (Кельвины)", tempTint = "Сдвиг оттенка (Зелёный / Пурпурный)", brightnessMult = "Множитель яркости солнца", manualBrightness = "Базовая яркость (В ручном режиме)", exposure = "Экспозиция камеры (Exposure)", shadowSoftness = "Мягкость краёв теней", outdoorBoost = "Яркость уличных теней (Outdoor)", ambientBoost = "Яркость в помещениях (Ambient)", specularScale = "Зеркальность PBR (Specular)", diffuseScale = "Рассеянный PBR-свет (Diffuse)", manualLightColors = "🎨 Ручной RGB-перехват цветов света", col_Top = "☀️ Прямой свет сверху (ColorShift_Top)", col_Bot = "🌤️ Рефлекс снизу (ColorShift_Bottom)", col_Outdoor = "🏙️ Уличные тени (OutdoorAmbient)", col_Ambient = "🏠 Фоновый свет (Ambient)", -- Controls: 3-Point Studio Rig rigEnabled = "🔦 Включить 3-точечный студийный свет", rigMode_Camera = "📹 На камере", rigMode_Char = "🧍 Вокруг игрока", rigMode_World = "📍 Зафиксировать тут", rigShadows = "Тени от студийного света", rigDistance = "Дистанция источников от центра", keyBright = "Яркость Key Light (Рисующий)", keyRange = "Дальность Key Light", col_Key = "Цвет Key Light", fillBright = "Яркость Fill Light (Мягкий)", fillRange = "Дальность Fill Light", col_Fill = "Цвет Fill Light", rimBright = "Яркость Rim Light (Контровой)", rimRange = "Дальность Rim Light", col_Rim = "Цвет Rim Light", -- Controls: Atmo & World atmoEnabled = "🌫️ Воздушная атмосфера (Выкл = Классич. туман)", atmoDensity = "Плотность атмосферы (Density)", atmoOffset = "Смещение горизонта (Offset)", atmoHaze = "Добавочная дымка (Haze)", atmoGlare = "Солнечный ореол в дымке (Glare)", manualAtmoColors = "🎨 Свой RGB-цвет атмосферы", col_Atmo = "🌫️ Основной цвет атмосферы", col_Decay = "🌇 Цвет затухания горизонта (Decay)", fogStart = "Начало классического тумана (FogStart)", fogEnd = "Конец классического тумана (FogEnd)", col_Fog = "🌁 Цвет классического тумана (FogColor)", cloudsEnabled = "☁️ Объёмные 3D-облака (Clouds)", cloudCover = "Покрытие облаками (-0.05 = Авто)", cloudDensity = "Плотность облаков (-0.05 = Авто)", manualCloudColor = "🎨 Свой RGB-цвет облаков", col_Cloud = "☁️ Цвет 3D-облаков", windSpeed = "Скорость глобального ветра", windAngle = "Направление ветра (Градусы)", waterWaveSize = "Высота волн воды", waterWaveSpeed = "Скорость волн воды", waterReflect = "Отражения воды", waterTrans = "Прозрачность воды", col_Water = "🌊 Цвет воды", -- Controls: Color & PostFX lut_Natural = "✨ Натуральный", lut_Clean = "📷 Чистый", lut_Film = "🎬 Киноплёнка", lut_Blockbuster = "🍿 Блокбастер", lut_Pastel = "🌅 Пастельный", lut_Nordic = "❄️ Северный холод", lut_Cyber = "🔮 Кибер-Неон", lut_Noir = "🎞️ Ч/Б Нуар", ccEnabled = "Включить цветокоррекцию", ccBrightness = "Сдвиг яркости кадра", ccSaturation = "Коррекция насыщенности", ccContrast = "Коррекция контраста", col_Tint = "🎨 Цветовой фильтр (TintColor)", bloomEnabled = "Включить свечение (Bloom)", bloomIntensity = "Интенсивность свечения", bloomSize = "Радиус свечения", bloomThreshold = "Порог свечения", sunRaysEnabled = "Включить солнечные лучи (SunRays)", sunRaysMult = "Сила солнечных лучей", sunRaysSpread = "Ширина расхождения лучей", blurSize = "Статичное размытие экрана", motionBlur = "💨 Динамическое размытие в движении (Motion Blur)", motionBlurStrength = "Сила Motion Blur при повороте", -- Controls: Camera & Optics dofEnabled = "📷 Глубина резкости (Depth of Field)", dofAuto = "🎯 Умный Авто-Фокус по лучу", dofFar = "Размытие дальнего фона", dofNear = "Размытие ближнего плана", dofDist = "Ручная дистанция фокуса", dofRadius = "Радиус зоны резкости", fov = "Угол обзора (Camera FOV)", camRoll = "Наклон горизонта (Roll °)", cinemaBars = "🎬 Кинематографические полосы", cinemaHeight = "Высота чёрных полос", vignette = "🌑 Мягкая виньетка по краям", vignetteOpacity = "Затемнение виньетки", lensFlare = "☀️ Оптические блики солнца (Bokeh)", flareIntensity = "Яркость бликов объектива", freecam = "🦅 Свободная камера (WASD + Q/E + ПКМ)", freecamSpeed = "Скорость полёта Freecam", walkSpeed = "Скорость бега (WalkSpeed)", gravity = "Гравитация мира", -- Controls: Configs cfgNamePlaceholder = "Введите название конфига...", btnSaveCfg = "➕ Сохранить текущие настройки", btnExportCurrent = "📤 Экспорт текущего в поле", btnImportBox = "📥 Применить JSON-код из поля", jsonPlaceholder = "Вставьте JSON-код конфига сюда или нажмите Экспорт...", cfgSavedMsg = "Сохранено!", cfgLoadedMsg = "Загружено!", cfgInvalidMsg = "Ошибка JSON!", btnLoad = "Загрузить", btnDelete = "✕", } } local function tr(key) local dict = I18N[currentLang] or I18N.EN return dict[key] or I18N.EN[key] or key end local function onLangChanged(fn) table.insert(i18nListeners, fn) fn() end -------------------------------------------------------------------- -- 2. ГЛОБАЛЬНАЯ КОНФИГУРАЦИЯ («НАСТРОЙКА ВСЕГО») -------------------------------------------------------------------- local internalWrite = false local currentClockTime = 17.85 local currentWeather = "Clear" -- "Clear", "Cloudy", "Overcast", "Rain", "Snow", "Fog", "Cyberpunk" local rtxEnabled = true local autoTimeEnabled = false local secondsPerGameMinute = 1.0 local isLightningActive = false local baseSunRays = 0.28 local defaultConfig = { -- Режим и Закат fullManualMode = false, sunsetStyle = "Realistic", -- "Realistic", "PastelPink", "ColdNordic", "WarmCinema" sunsetWarmth = 1.0, geographicLatitude = 42, sunAngularSize = 16, moonAngularSize = 11, starCount = 3000, celestialShown = true, -- Свет и Тени globalShadows = true, shadowSoftness = 0.12, exposure = 0.05, brightnessMult = 1.0, manualBrightness = 2.2, diffuseScale = 1.0, specularScale = 1.0, colorTempKelvin = 6500, tempTintShift = 0.0, -- -1 (Green) .. +1 (Magenta) ambientBoost = 1.0, outdoorAmbientBoost = 1.0, -- Ручной RGB-перехват света manualLightColors = false, manualTopColor = Color3.fromRGB(255, 205, 170), manualBotColor = Color3.fromRGB(130, 125, 135), manualOutdoorColor = Color3.fromRGB(115, 125, 148), manualAmbientColor = Color3.fromRGB(52, 56, 68), -- 3-Точечный Студийный Свет (Key, Fill, Rim) rigEnabled = false, rigAttachMode = "Camera", -- "Camera", "Character", "World" rigShadows = true, rigDistance = 10, keyBrightness = 1.8, keyRange = 38, keyColor = Color3.fromRGB(255, 235, 210), fillBrightness = 0.85, fillRange = 32, fillColor = Color3.fromRGB(185, 210, 255), rimBrightness = 1.4, rimRange = 28, rimColor = Color3.fromRGB(255, 195, 150), -- Атмосфера и Классический Туман atmoEnabled = true, atmoDensityMult = 1.0, atmoOffset = 0.18, atmoHazeOffset = 0.0, atmoGlareMult = 1.0, manualAtmoColors = false, manualAtmoColor = Color3.fromRGB(205, 180, 175), manualAtmoDecay = Color3.fromRGB(135, 115, 135), fogStart = 20, fogEnd = 650, fogColor = Color3.fromRGB(175, 185, 200), -- 3D Облака и Ветер cloudsEnabled = true, cloudCoverOverride = -1, cloudDensityOverride = -1, manualCloudColor = false, cloudCustomColor = Color3.fromRGB(245, 235, 230), windSpeed = 12, windAngle = 45, -- Погодные частицы rainRateMult = 1.0, rainSplashes = true, wetReflectanceMax = 0.35, rainVolumeMult = 1.0, dustRate = 35, -- Вода waterWaveSize = 0.15, waterWaveSpeed = 14, waterReflectance = 0.9, waterTransparency = 0.7, waterColor = Color3.fromRGB(32, 78, 95), -- Пост-обработка ccEnabled = true, brightnessCC = 0.0, saturationOffset = 0.0, contrastOffset = 0.0, tintColor = Color3.fromRGB(255, 255, 255), bloomEnabled = true, bloomIntensity = 0.65, bloomSize = 28, bloomThreshold = 0.82, sunRaysEnabled = true, sunRaysMult = 1.0, sunRaysSpread = 0.45, blurSize = 0.0, motionBlurEnabled = false, motionBlurStrength = 0.45, -- Камера и Оптика dofEnabled = true, dofAutoFocus = true, dofFarIntensity = 0.16, dofNearIntensity = 0.0, dofFocusDist = 55, dofRadius = 42, fov = 70, cameraRoll = 0, cinemaBars = false, cinemaBarHeight = 0.10, vignetteEnabled = false, vignetteOpacity = 0.35, lensFlareEnabled = true, lensFlareIntensity = 0.65, } local customConfig = {} for k, v in pairs(defaultConfig) do customConfig[k] = v end local lockedSettings = { GlobalShadows = true, ShadowSoftness = 0.12, GeographicLatitude = 42, ExposureCompensation = 0.05, EnvironmentDiffuseScale = 1.0, EnvironmentSpecularScale = 1.0, ClockTime = currentClockTime, Brightness = 2.4, Ambient = Color3.fromRGB(52, 56, 68), OutdoorAmbient = Color3.fromRGB(115, 125, 148), ColorShift_Top = Color3.fromRGB(255, 200, 165), ColorShift_Bottom = Color3.fromRGB(130, 125, 135), FogStart = 0, FogEnd = 100000, FogColor = Color3.fromRGB(175, 185, 200), } local function applyToLighting(props) internalWrite = true for k, v in pairs(props) do lockedSettings[k] = v Lighting[k] = v end internalWrite = false end applyToLighting(lockedSettings) local ourEffects = {} local function getOrCreateEffect(className, name) local effect = Lighting:FindFirstChild(name) if not effect or not effect:IsA(className) then if effect then effect:Destroy() end effect = Instance.new(className) effect.Name = name effect.Parent = Lighting end ourEffects[effect] = true return effect end local sky = getOrCreateEffect("Sky", "Shader_Sky") local bloom = getOrCreateEffect("BloomEffect", "Shader_Bloom") local dof = getOrCreateEffect("DepthOfFieldEffect", "Shader_DoF") local colorCorrection = getOrCreateEffect("ColorCorrectionEffect", "Shader_ColorCorrection") local sunRays = getOrCreateEffect("SunRaysEffect", "Shader_SunRays") local atmosphere = getOrCreateEffect("Atmosphere", "Shader_Atmosphere") local blurEffect = getOrCreateEffect("BlurEffect", "Shader_Blur") blurEffect.Size = 0 local terrain = workspace:FindFirstChildOfClass("Terrain") local clouds = terrain and terrain:FindFirstChild("Shader_Clouds") if not clouds and terrain then for _, c in ipairs(terrain:GetChildren()) do if c:IsA("Clouds") then c:Destroy() end end clouds = Instance.new("Clouds") clouds.Name = "Shader_Clouds" clouds.Cover = 0.28 clouds.Density = 0.55 clouds.Color = Color3.fromRGB(245, 232, 222) clouds.Parent = terrain end local blockedClasses = { ["Sky"] = true, ["Atmosphere"] = true, ["BloomEffect"] = true, ["ColorCorrectionEffect"] = true, ["SunRaysEffect"] = true, ["DepthOfFieldEffect"] = true, ["BlurEffect"] = true, } local function purgeForeignEffects(inst) if ourEffects[inst] then return end if blockedClasses[inst.ClassName] then task.defer(function() pcall(function() if inst:IsA("PostEffect") then inst.Enabled = false end inst:Destroy() end) end) end end for _, child in ipairs(Lighting:GetChildren()) do purgeForeignEffects(child) end Lighting.ChildAdded:Connect(purgeForeignEffects) Lighting.Changed:Connect(function(prop) if internalWrite then return end if lockedSettings[prop] ~= nil and Lighting[prop] ~= lockedSettings[prop] then internalWrite = true Lighting[prop] = lockedSettings[prop] internalWrite = false end end) -------------------------------------------------------------------- -- 3. МАТЕМАТИКА ЦВЕТА И РЕАЛИСТИЧНАЯ ПАЛИТРА СУТОК -------------------------------------------------------------------- local function lerp(a, b, t) return a + (b - a) * t end local function scaleColor(c, factor) return Color3.new( math.clamp(c.R * factor, 0, 1), math.clamp(c.G * factor, 0, 1), math.clamp(c.B * factor, 0, 1) ) end local function multiplyColor(c1, c2) return Color3.new( math.clamp(c1.R * c2.R, 0, 1), math.clamp(c1.G * c2.G, 0, 1), math.clamp(c1.B * c2.B, 0, 1) ) end local function colorToHex(c) return string.format("#%02X%02X%02X", math.clamp(math.floor(c.R * 255 + 0.5), 0, 255), math.clamp(math.floor(c.G * 255 + 0.5), 0, 255), math.clamp(math.floor(c.B * 255 + 0.5), 0, 255) ) end local function hexToColor(hex) hex = tostring(hex):gsub("#", ""):gsub("%s+", "") if #hex == 6 then local r = tonumber(hex:sub(1, 2), 16) local g = tonumber(hex:sub(3, 4), 16) local b = tonumber(hex:sub(5, 6), 16) if r and g and b then return Color3.fromRGB(r, g, b) end end return nil end local function kelvinAndTintToMultiplier(kelvin, tintShift) local k = math.clamp(kelvin, 2000, 11000) local r, g, b = 1.0, 1.0, 1.0 if k < 6500 then local t = (6500 - k) / 4500 g = lerp(1.0, 0.84, t) b = lerp(1.0, 0.68, t) else local t = (k - 6500) / 4500 r = lerp(1.0, 0.82, t) g = lerp(1.0, 0.91, t) end local ts = math.clamp(tintShift or 0, -1, 1) if ts < 0 then g = math.clamp(g + (-ts) * 0.15, 0, 1.2) elseif ts > 0 then r = math.clamp(r + ts * 0.12, 0, 1.2) b = math.clamp(b + ts * 0.12, 0, 1.2) end return Color3.new(math.clamp(r, 0, 1), math.clamp(g, 0, 1), math.clamp(b, 0, 1)) end local timeKeyframes = { { time = 0.0, top = Color3.fromRGB(42, 55, 88), bot = Color3.fromRGB(22, 28, 46), atCol = Color3.fromRGB(24, 34, 60), atDec = Color3.fromRGB(12, 18, 34), tint = Color3.fromRGB(235, 240, 255), haze = 0.28, glare = 0.0, rays = 0.0, sat = 0.04, cont = 0.12, bright = 0.75, amb = Color3.fromRGB(52, 60, 82), inAmb = Color3.fromRGB(30, 34, 46), cloudCol = Color3.fromRGB(48, 56, 78) }, { time = 5.15, top = Color3.fromRGB(165, 138, 148), bot = Color3.fromRGB(78, 82, 108), atCol = Color3.fromRGB(135, 125, 155), atDec = Color3.fromRGB(85, 75, 110), tint = Color3.fromRGB(242, 242, 252), haze = 0.65, glare = 0.12, rays = 0.08, sat = 0.06, cont = 0.12, bright = 1.25, amb = Color3.fromRGB(82, 92, 122), inAmb = Color3.fromRGB(40, 44, 58), cloudCol = Color3.fromRGB(155, 140, 160) }, { time = 6.3, top = Color3.fromRGB(252, 198, 162), bot = Color3.fromRGB(138, 128, 135), atCol = Color3.fromRGB(218, 182, 168), atDec = Color3.fromRGB(152, 122, 142), tint = Color3.fromRGB(255, 248, 242), haze = 0.88, glare = 0.32, rays = 0.34, sat = 0.10, cont = 0.13, bright = 2.15, amb = Color3.fromRGB(118, 128, 152), inAmb = Color3.fromRGB(54, 58, 70), cloudCol = Color3.fromRGB(245, 205, 190) }, { time = 7.75, top = Color3.fromRGB(255, 232, 205), bot = Color3.fromRGB(165, 172, 185), atCol = Color3.fromRGB(215, 222, 235), atDec = Color3.fromRGB(145, 160, 185), tint = Color3.fromRGB(255, 252, 248), haze = 0.45, glare = 0.18, rays = 0.25, sat = 0.10, cont = 0.12, bright = 2.55, amb = Color3.fromRGB(138, 148, 165), inAmb = Color3.fromRGB(68, 72, 80), cloudCol = Color3.fromRGB(252, 248, 244) }, { time = 12.0, top = Color3.fromRGB(255, 252, 246), bot = Color3.fromRGB(185, 205, 228), atCol = Color3.fromRGB(185, 218, 250), atDec = Color3.fromRGB(105, 135, 175), tint = Color3.fromRGB(255, 255, 255), haze = 0.24, glare = 0.12, rays = 0.18, sat = 0.08, cont = 0.11, bright = 2.75, amb = Color3.fromRGB(148, 156, 170), inAmb = Color3.fromRGB(76, 80, 88), cloudCol = Color3.fromRGB(255, 255, 255) }, { time = 16.75, top = Color3.fromRGB(255, 218, 175), bot = Color3.fromRGB(152, 150, 162), atCol = Color3.fromRGB(215, 195, 182), atDec = Color3.fromRGB(158, 135, 142), tint = Color3.fromRGB(255, 250, 245), haze = 0.62, glare = 0.26, rays = 0.32, sat = 0.11, cont = 0.13, bright = 2.50, amb = Color3.fromRGB(132, 138, 156), inAmb = Color3.fromRGB(62, 65, 76), cloudCol = Color3.fromRGB(252, 228, 208) }, { time = 17.85, top = Color3.fromRGB(252, 186, 145), bot = Color3.fromRGB(130, 122, 138), atCol = Color3.fromRGB(215, 168, 155), atDec = Color3.fromRGB(142, 108, 135), tint = Color3.fromRGB(255, 246, 240), haze = 0.85, glare = 0.35, rays = 0.38, sat = 0.12, cont = 0.14, bright = 2.25, amb = Color3.fromRGB(114, 122, 148), inAmb = Color3.fromRGB(52, 56, 68), cloudCol = Color3.fromRGB(245, 195, 178) }, { time = 18.6, top = Color3.fromRGB(228, 148, 138), bot = Color3.fromRGB(98, 95, 122), atCol = Color3.fromRGB(182, 132, 142), atDec = Color3.fromRGB(108, 84, 122), tint = Color3.fromRGB(250, 242, 246), haze = 0.78, glare = 0.22, rays = 0.22, sat = 0.10, cont = 0.14, bright = 1.75, amb = Color3.fromRGB(92, 100, 130), inAmb = Color3.fromRGB(42, 46, 60), cloudCol = Color3.fromRGB(212, 152, 162) }, { time = 19.4, top = Color3.fromRGB(132, 125, 165), bot = Color3.fromRGB(58, 64, 92), atCol = Color3.fromRGB(95, 102, 142), atDec = Color3.fromRGB(52, 58, 92), tint = Color3.fromRGB(238, 242, 255), haze = 0.48, glare = 0.06, rays = 0.05, sat = 0.07, cont = 0.13, bright = 1.15, amb = Color3.fromRGB(70, 78, 108), inAmb = Color3.fromRGB(34, 38, 52), cloudCol = Color3.fromRGB(115, 118, 148) }, { time = 20.8, top = Color3.fromRGB(48, 60, 92), bot = Color3.fromRGB(24, 30, 48), atCol = Color3.fromRGB(32, 42, 70), atDec = Color3.fromRGB(16, 22, 40), tint = Color3.fromRGB(235, 240, 255), haze = 0.30, glare = 0.0, rays = 0.0, sat = 0.05, cont = 0.12, bright = 0.85, amb = Color3.fromRGB(58, 65, 86), inAmb = Color3.fromRGB(32, 36, 48), cloudCol = Color3.fromRGB(55, 64, 86) }, { time = 24.0, top = Color3.fromRGB(42, 55, 88), bot = Color3.fromRGB(22, 28, 46), atCol = Color3.fromRGB(24, 34, 60), atDec = Color3.fromRGB(12, 18, 34), tint = Color3.fromRGB(235, 240, 255), haze = 0.28, glare = 0.0, rays = 0.0, sat = 0.04, cont = 0.12, bright = 0.75, amb = Color3.fromRGB(52, 60, 82), inAmb = Color3.fromRGB(30, 34, 46), cloudCol = Color3.fromRGB(48, 56, 78) }, } local function getTimeProperties(clockTime) local ct = clockTime % 24 local prop = nil for i = 1, #timeKeyframes - 1 do local k1 = timeKeyframes[i] local k2 = timeKeyframes[i + 1] if ct >= k1.time and ct <= k2.time then local alpha = (ct - k1.time) / (k2.time - k1.time) prop = { top = k1.top:Lerp(k2.top, alpha), bot = k1.bot:Lerp(k2.bot, alpha), atCol = k1.atCol:Lerp(k2.atCol, alpha), atDec = k1.atDec:Lerp(k2.atDec, alpha), tint = k1.tint:Lerp(k2.tint, alpha), haze = lerp(k1.haze, k2.haze, alpha), glare = lerp(k1.glare, k2.glare, alpha), rays = lerp(k1.rays, k2.rays, alpha), sat = lerp(k1.sat, k2.sat, alpha), cont = lerp(k1.cont, k2.cont, alpha), bright = lerp(k1.bright, k2.bright, alpha), amb = k1.amb:Lerp(k2.amb, alpha), inAmb = k1.inAmb:Lerp(k2.inAmb, alpha), cloudCol = k1.cloudCol:Lerp(k2.cloudCol, alpha) } break end end if not prop then prop = timeKeyframes[1] end local isTwilight = (ct >= 4.8 and ct <= 8.2) or (ct >= 16.2 and ct <= 20.0) if isTwilight then if customConfig.sunsetStyle == "PastelPink" then prop.top = prop.top:Lerp(Color3.fromRGB(255, 190, 210), 0.38) prop.atCol = prop.atCol:Lerp(Color3.fromRGB(230, 175, 205), 0.42) prop.atDec = prop.atDec:Lerp(Color3.fromRGB(155, 120, 175), 0.45) prop.cloudCol = prop.cloudCol:Lerp(Color3.fromRGB(250, 195, 215), 0.40) elseif customConfig.sunsetStyle == "ColdNordic" then prop.top = prop.top:Lerp(Color3.fromRGB(215, 225, 245), 0.45) prop.atCol = prop.atCol:Lerp(Color3.fromRGB(165, 185, 215), 0.50) prop.atDec = prop.atDec:Lerp(Color3.fromRGB(95, 115, 155), 0.50) prop.amb = prop.amb:Lerp(Color3.fromRGB(115, 135, 165), 0.35) prop.cloudCol = prop.cloudCol:Lerp(Color3.fromRGB(195, 210, 230), 0.45) prop.glare = prop.glare * 0.6 elseif customConfig.sunsetStyle == "WarmCinema" then prop.top = prop.top:Lerp(Color3.fromRGB(255, 172, 105), 0.35) prop.atCol = prop.atCol:Lerp(Color3.fromRGB(235, 155, 105), 0.35) prop.glare = prop.glare * 1.35 prop.sat = prop.sat + 0.06 end local w = customConfig.sunsetWarmth if w < 1.0 then local coolAlpha = math.clamp(1.0 - w, 0, 1) prop.top = prop.top:Lerp(Color3.fromRGB(205, 215, 235), coolAlpha * 0.65) prop.atCol = prop.atCol:Lerp(Color3.fromRGB(170, 185, 210), coolAlpha * 0.65) prop.cloudCol = prop.cloudCol:Lerp(Color3.fromRGB(210, 220, 235), coolAlpha * 0.6) elseif w > 1.0 then local warmAlpha = math.clamp((w - 1.0) / 0.8, 0, 1) prop.top = prop.top:Lerp(Color3.fromRGB(255, 165, 95), warmAlpha * 0.45) prop.atCol = prop.atCol:Lerp(Color3.fromRGB(240, 150, 100), warmAlpha * 0.45) prop.cloudCol = prop.cloudCol:Lerp(Color3.fromRGB(255, 180, 130), warmAlpha * 0.45) end end return prop end -------------------------------------------------------------------- -- 4. ПОГОДНЫЕ ЭФФЕКТЫ И 3-ТОЧЕЧНЫЙ СТУДИЙНЫЙ СВЕТ (STUDIO RIG) -------------------------------------------------------------------- local fxFolder = workspace:FindFirstChild("UltraShader_FX") or Instance.new("Folder") fxFolder.Name = "UltraShader_FX" fxFolder.Parent = workspace local weatherDome = Instance.new("Part") weatherDome.Name = "WeatherDome" weatherDome.Size = Vector3.new(110, 1, 110) weatherDome.Transparency = 1 weatherDome.CanCollide = false weatherDome.CanQuery = false weatherDome.CanTouch = false weatherDome.Anchored = true weatherDome.Parent = fxFolder -- 3-Point Studio Lighting Rig (Key, Fill, Rim) local rigLockedWorldCF = CFrame.new() local function createRigNode(name) local p = Instance.new("Part") p.Name = name p.Size = Vector3.new(0.4, 0.4, 0.4) p.Transparency = 1 p.CanCollide = false p.CanQuery = false p.CanTouch = false p.Anchored = true p.Parent = fxFolder local pl = Instance.new("PointLight") pl.Enabled = false pl.Parent = p return p, pl end local keyPart, keyLight = createRigNode("StudioRig_Key") local fillPart, fillLight = createRigNode("StudioRig_Fill") local rimPart, rimLight = createRigNode("StudioRig_Rim") local rainEmitter = Instance.new("ParticleEmitter") rainEmitter.Texture = "rbxassetid://258127006" rainEmitter.Orientation = Enum.ParticleOrientation.VelocityParallel rainEmitter.Size = NumberSequence.new(0.14, 0.20) rainEmitter.Transparency = NumberSequence.new({ NumberSequenceKeypoint.new(0, 0.15), NumberSequenceKeypoint.new(1, 0.50) }) rainEmitter.Color = ColorSequence.new(Color3.fromRGB(195, 215, 240)) rainEmitter.Lifetime = NumberRange.new(0.5, 0.7) rainEmitter.Rate = 0 rainEmitter.Speed = NumberRange.new(105, 135) rainEmitter.SpreadAngle = Vector2.new(4, 4) rainEmitter.EmissionDirection = Enum.NormalId.Bottom rainEmitter.Parent = weatherDome local dustEmitter = Instance.new("ParticleEmitter") dustEmitter.Texture = "rbxassetid://1084991219" dustEmitter.Size = NumberSequence.new({ NumberSequenceKeypoint.new(0, 0), NumberSequenceKeypoint.new(0.5, 0.10), NumberSequenceKeypoint.new(1, 0) }) dustEmitter.Transparency = NumberSequence.new({ NumberSequenceKeypoint.new(0, 1), NumberSequenceKeypoint.new(0.5, 0.55), NumberSequenceKeypoint.new(1, 1) }) dustEmitter.Color = ColorSequence.new(Color3.fromRGB(255, 245, 230)) dustEmitter.LightEmission = 0.45 dustEmitter.Lifetime = NumberRange.new(4, 7) dustEmitter.Rate = customConfig.dustRate dustEmitter.Speed = NumberRange.new(0.4, 1.4) dustEmitter.SpreadAngle = Vector2.new(180, 180) dustEmitter.Parent = weatherDome local rainSound = Instance.new("Sound") rainSound.Name = "RainAudio" rainSound.SoundId = "rbxassetid://1516791621" rainSound.Looped = true rainSound.Volume = 0 rainSound.Parent = weatherDome pcall(function() rainSound:Play() end) local wetPartsCache = {} local reflectMaterials = { [Enum.Material.Concrete] = true, [Enum.Material.Asphalt] = true, [Enum.Material.SmoothPlastic] = true, [Enum.Material.Slate] = true, [Enum.Material.Cobblestone] = true, [Enum.Material.Pavement] = true, [Enum.Material.Metal] = true, [Enum.Material.WoodPlanks] = true, } local function clearWetSurfaces() for part, origRef in pairs(wetPartsCache) do if part and part.Parent then TweenService:Create(part, TweenInfo.new(1.5), { Reflectance = origRef }):Play() end end table.clear(wetPartsCache) end local function updateWetSurfaces() if currentWeather ~= "Rain" or not rtxEnabled then if next(wetPartsCache) ~= nil then clearWetSurfaces() end return end local overlap = OverlapParams.new() overlap.FilterDescendantsInstances = { fxFolder, player.Character } overlap.FilterType = Enum.RaycastFilterType.Exclude overlap.MaxParts = 45 local parts = workspace:GetPartBoundsInBox(CFrame.new(camera.CFrame.Position), Vector3.new(140, 50, 140), overlap) for _, part in ipairs(parts) do if part:IsA("BasePart") and part.Anchored and part.Transparency == 0 and reflectMaterials[part.Material] then if wetPartsCache[part] == nil then wetPartsCache[part] = part.Reflectance end local targetRef = math.clamp(wetPartsCache[part] + customConfig.wetReflectanceMax * 0.6, 0.05, customConfig.wetReflectanceMax) TweenService:Create(part, TweenInfo.new(1.8), { Reflectance = targetRef }):Play() end end end local function triggerLightningStrike() if isLightningActive then return end isLightningActive = true task.spawn(function() local prevBright = lockedSettings.Brightness local prevExp = lockedSettings.ExposureCompensation applyToLighting({ Brightness = 6.2, ExposureCompensation = 0.65 }) task.wait(0.06) applyToLighting({ Brightness = prevBright, ExposureCompensation = prevExp }) task.wait(0.08) applyToLighting({ Brightness = 4.5, ExposureCompensation = 0.35 }) task.wait(0.05) applyToLighting({ Brightness = prevBright, ExposureCompensation = prevExp }) isLightningActive = false end) end -------------------------------------------------------------------- -- 5. ГЛАВНАЯ ФУНКЦИЯ ОБНОВЛЕНИЯ СВЕТА И ОКРУЖЕНИЯ -------------------------------------------------------------------- local function updateEnvironment() local tp = getTimeProperties(currentClockTime) local dayFactor = math.clamp(tp.bright / 2.6, 0.35, 1.0) local wSoftness = customConfig.shadowSoftness local wBright = customConfig.fullManualMode and customConfig.manualBrightness or tp.bright local wOutAmb = tp.amb local wInAmb = tp.inAmb local wTop = tp.top local wBot = tp.bot local wSat = customConfig.fullManualMode and 0 or tp.sat local wCont = customConfig.fullManualMode and 0 or tp.cont local wTint = customConfig.fullManualMode and Color3.new(1, 1, 1) or tp.tint local wAtDens = 0.31 local wAtCol = tp.atCol local wAtDec = tp.atDec local wHaze = tp.haze local wGlare = tp.glare local wCloudCov = 0.28 local wCloudDens = 0.55 local wCloudCol = tp.cloudCol sky.SunAngularSize = customConfig.sunAngularSize sky.MoonAngularSize = customConfig.moonAngularSize sky.StarCount = customConfig.starCount if currentWeather == "Clear" then sky.CelestialBodiesShown = customConfig.celestialShown rainEmitter.Rate = 0 dustEmitter.Rate = customConfig.dustRate baseSunRays = tp.rays elseif currentWeather == "Cloudy" then sky.CelestialBodiesShown = customConfig.celestialShown rainEmitter.Rate = 0 dustEmitter.Rate = math.floor(customConfig.dustRate * 0.5) baseSunRays = tp.rays * 0.65 wSoftness = math.clamp(customConfig.shadowSoftness + 0.12, 0, 1) wBright = wBright * 0.88 wOutAmb = tp.amb:Lerp(Color3.fromRGB(145, 152, 165), 0.25) wInAmb = tp.inAmb:Lerp(Color3.fromRGB(70, 74, 82), 0.25) wTop = tp.top:Lerp(Color3.fromRGB(235, 232, 228), 0.25) wSat = wSat * 0.8 wCont = wCont * 0.9 wAtDens = 0.36 wAtCol = tp.atCol:Lerp(Color3.fromRGB(215, 222, 232), 0.3) wHaze = tp.haze * 0.85 wGlare = tp.glare * 0.65 wCloudCov = 0.72 wCloudDens = 0.82 elseif currentWeather == "Overcast" then sky.CelestialBodiesShown = false rainEmitter.Rate = 0 dustEmitter.Rate = 0 baseSunRays = 0 wSoftness = math.clamp(customConfig.shadowSoftness + 0.35, 0, 1) wBright = 1.30 * dayFactor wOutAmb = scaleColor(Color3.fromRGB(122, 128, 140), dayFactor) wInAmb = scaleColor(Color3.fromRGB(88, 94, 105), dayFactor) wTop = scaleColor(Color3.fromRGB(135, 140, 150), dayFactor) wBot = scaleColor(Color3.fromRGB(105, 110, 120), dayFactor) wSat = -0.25 wCont = 0.08 wTint = Color3.fromRGB(230, 235, 242) wAtDens = 0.54 wAtCol = scaleColor(Color3.fromRGB(140, 148, 162), dayFactor) wAtDec = scaleColor(Color3.fromRGB(90, 98, 112), dayFactor) wHaze = 2.1 wGlare = 0.0 wCloudCov = 0.96 wCloudDens = 0.95 wCloudCol = scaleColor(Color3.fromRGB(135, 140, 150), dayFactor) elseif currentWeather == "Rain" then sky.CelestialBodiesShown = false rainEmitter.Rate = math.floor(2400 * customConfig.rainRateMult) dustEmitter.Rate = 0 baseSunRays = 0 wSoftness = math.clamp(customConfig.shadowSoftness + 0.4, 0, 1) wBright = 1.05 * dayFactor wOutAmb = scaleColor(Color3.fromRGB(82, 92, 112), dayFactor) wInAmb = scaleColor(Color3.fromRGB(62, 70, 84), dayFactor) wTop = scaleColor(Color3.fromRGB(98, 112, 135), dayFactor) wBot = scaleColor(Color3.fromRGB(65, 75, 90), dayFactor) wSat = -0.15 wCont = 0.16 wTint = Color3.fromRGB(210, 222, 238) wAtDens = 0.62 wAtCol = scaleColor(Color3.fromRGB(80, 92, 112), dayFactor) wAtDec = scaleColor(Color3.fromRGB(45, 55, 72), dayFactor) wHaze = 2.8 wGlare = 0.0 wCloudCov = 1.0 wCloudDens = 1.0 wCloudCol = scaleColor(Color3.fromRGB(58, 65, 80), dayFactor) elseif currentWeather == "Snow" then sky.CelestialBodiesShown = customConfig.celestialShown rainEmitter.Rate = 0 dustEmitter.Rate = 0 baseSunRays = 0.15 wSoftness = math.clamp(customConfig.shadowSoftness + 0.25, 0, 1) wBright = 1.55 * dayFactor wOutAmb = scaleColor(Color3.fromRGB(138, 148, 168), dayFactor) wInAmb = scaleColor(Color3.fromRGB(92, 98, 112), dayFactor) wTop = scaleColor(Color3.fromRGB(210, 228, 250), dayFactor) wBot = scaleColor(Color3.fromRGB(150, 165, 188), dayFactor) wSat = -0.05 wCont = 0.12 wTint = Color3.fromRGB(238, 245, 255) wAtDens = 0.46 wAtCol = scaleColor(Color3.fromRGB(210, 225, 242), dayFactor) wAtDec = scaleColor(Color3.fromRGB(150, 175, 202), dayFactor) wHaze = 1.65 wGlare = 0.15 wCloudCov = 0.88 wCloudDens = 0.82 wCloudCol = scaleColor(Color3.fromRGB(225, 235, 248), dayFactor) elseif currentWeather == "Fog" then sky.CelestialBodiesShown = false rainEmitter.Rate = 0 dustEmitter.Rate = customConfig.dustRate baseSunRays = 0.08 wSoftness = math.clamp(customConfig.shadowSoftness + 0.45, 0, 1) wBright = 1.15 * dayFactor wOutAmb = scaleColor(Color3.fromRGB(145, 155, 165), dayFactor) wInAmb = scaleColor(Color3.fromRGB(100, 110, 120), dayFactor) wSat = -0.28 wCont = 0.05 wTint = Color3.fromRGB(232, 238, 242) wAtDens = 0.78 wAtCol = scaleColor(Color3.fromRGB(185, 195, 205), dayFactor) wAtDec = scaleColor(Color3.fromRGB(130, 140, 155), dayFactor) wHaze = 4.5 wGlare = 0.08 wCloudCov = 1.0 wCloudDens = 1.0 elseif currentWeather == "Cyberpunk" then sky.CelestialBodiesShown = customConfig.celestialShown rainEmitter.Rate = math.floor(850 * customConfig.rainRateMult) dustEmitter.Rate = 80 baseSunRays = 0.45 wBright = 2.0 wOutAmb = Color3.fromRGB(105, 48, 150) wInAmb = Color3.fromRGB(45, 22, 72) wTop = Color3.fromRGB(245, 55, 165) wBot = Color3.fromRGB(40, 205, 250) wSat = 0.35 wCont = 0.24 wTint = Color3.fromRGB(248, 225, 255) wAtDens = 0.42 wAtCol = Color3.fromRGB(145, 40, 180) wAtDec = Color3.fromRGB(30, 175, 245) wHaze = 1.8 wGlare = 0.85 wCloudCov = 0.55 wCloudDens = 0.7 wCloudCol = Color3.fromRGB(200, 70, 235) end local tempMult = kelvinAndTintToMultiplier(customConfig.colorTempKelvin, customConfig.tempTintShift) local useManualRGB = customConfig.manualLightColors or customConfig.fullManualMode local finalTop = useManualRGB and multiplyColor(customConfig.manualTopColor, tempMult) or multiplyColor(wTop, tempMult) local finalBot = useManualRGB and multiplyColor(customConfig.manualBotColor, tempMult) or multiplyColor(wBot, tempMult) local finalOutAmb = useManualRGB and scaleColor(multiplyColor(customConfig.manualOutdoorColor, tempMult), customConfig.outdoorAmbientBoost) or scaleColor(multiplyColor(wOutAmb, tempMult), customConfig.outdoorAmbientBoost) local finalInAmb = useManualRGB and scaleColor(multiplyColor(customConfig.manualAmbientColor, tempMult), customConfig.ambientBoost) or scaleColor(multiplyColor(wInAmb, tempMult), customConfig.ambientBoost) baseSunRays = baseSunRays * customConfig.sunRaysMult sunRays.Enabled = customConfig.sunRaysEnabled sunRays.Spread = customConfig.sunRaysSpread applyToLighting({ ClockTime = currentClockTime, GlobalShadows = customConfig.globalShadows, ShadowSoftness = wSoftness, GeographicLatitude = customConfig.geographicLatitude, ExposureCompensation = customConfig.exposure, EnvironmentDiffuseScale = customConfig.diffuseScale, EnvironmentSpecularScale = rtxEnabled and customConfig.specularScale or 0.0, Brightness = (customConfig.fullManualMode and customConfig.manualBrightness or wBright) * customConfig.brightnessMult, OutdoorAmbient = finalOutAmb, Ambient = finalInAmb, ColorShift_Top = finalTop, ColorShift_Bottom = finalBot, FogStart = customConfig.atmoEnabled and 0 or customConfig.fogStart, FogEnd = customConfig.atmoEnabled and 100000 or customConfig.fogEnd, FogColor = customConfig.fogColor, }) colorCorrection.Enabled = customConfig.ccEnabled colorCorrection.Brightness = customConfig.brightnessCC colorCorrection.Saturation = math.clamp(wSat + customConfig.saturationOffset, -1, 2) colorCorrection.Contrast = math.clamp(wCont + customConfig.contrastOffset, -1, 2) colorCorrection.TintColor = multiplyColor(wTint, customConfig.tintColor) bloom.Enabled = customConfig.bloomEnabled bloom.Intensity = customConfig.bloomIntensity bloom.Size = customConfig.bloomSize bloom.Threshold = customConfig.bloomThreshold if not customConfig.motionBlurEnabled then blurEffect.Enabled = (customConfig.blurSize > 0.05) blurEffect.Size = customConfig.blurSize end dof.Enabled = customConfig.dofEnabled dof.FarIntensity = customConfig.dofFarIntensity dof.NearIntensity = customConfig.dofNearIntensity dof.InFocusRadius = customConfig.dofRadius if not customConfig.dofAutoFocus then dof.FocusDistance = customConfig.dofFocusDist end if customConfig.atmoEnabled then atmosphere.Parent = Lighting atmosphere.Density = math.clamp(wAtDens * customConfig.atmoDensityMult, 0, 1) atmosphere.Offset = customConfig.atmoOffset atmosphere.Color = (customConfig.manualAtmoColors or customConfig.fullManualMode) and customConfig.manualAtmoColor or wAtCol atmosphere.Decay = (customConfig.manualAtmoColors or customConfig.fullManualMode) and customConfig.manualAtmoDecay or wAtDec atmosphere.Haze = math.clamp(wHaze + customConfig.atmoHazeOffset, 0, 10) atmosphere.Glare = math.clamp(wGlare * customConfig.atmoGlareMult, 0, 10) else atmosphere.Parent = nil end if clouds then clouds.Enabled = customConfig.cloudsEnabled clouds.Cover = (customConfig.cloudCoverOverride >= 0) and customConfig.cloudCoverOverride or wCloudCov clouds.Density = (customConfig.cloudDensityOverride >= 0) and customConfig.cloudDensityOverride or wCloudDens clouds.Color = (customConfig.manualCloudColor or customConfig.fullManualMode) and customConfig.cloudCustomColor or wCloudCol end local rad = math.rad(customConfig.windAngle) workspace.GlobalWind = Vector3.new(math.cos(rad) * customConfig.windSpeed, 0, math.sin(rad) * customConfig.windSpeed) if terrain then terrain.WaterWaveSize = customConfig.waterWaveSize terrain.WaterWaveSpeed = customConfig.waterWaveSpeed terrain.WaterReflectance = customConfig.waterReflectance terrain.WaterTransparency = customConfig.waterTransparency terrain.WaterColor = customConfig.waterColor end -- 3-Point Studio Rig keyLight.Enabled = customConfig.rigEnabled keyLight.Brightness = customConfig.keyBrightness keyLight.Range = customConfig.keyRange keyLight.Color = customConfig.keyColor keyLight.Shadows = customConfig.rigShadows fillLight.Enabled = customConfig.rigEnabled fillLight.Brightness = customConfig.fillBrightness fillLight.Range = customConfig.fillRange fillLight.Color = customConfig.fillColor fillLight.Shadows = false rimLight.Enabled = customConfig.rigEnabled rimLight.Brightness = customConfig.rimBrightness rimLight.Range = customConfig.rimRange rimLight.Color = customConfig.rimColor rimLight.Shadows = customConfig.rigShadows if currentWeather ~= "Rain" then rainSound.Volume = 0 end end -------------------------------------------------------------------- -- 6. СИСТЕМА СОХРАНЕНИЯ / ЗАГРУЗКИ КОНФИГОВ (JSON + ПРЕСЕТЫ) -------------------------------------------------------------------- local uiSyncCallbacks = {} local function syncAllUI() for _, fn in ipairs(uiSyncCallbacks) do fn() end end local function serializeCurrentConfig() local data = { _clockTime = currentClockTime, _weather = currentWeather, _rtx = rtxEnabled, cfg = {} } for k, v in pairs(customConfig) do if typeof(v) == "Color3" then data.cfg[k] = { __colorHex = colorToHex(v) } else data.cfg[k] = v end end return HttpService:JSONEncode(data) end local function applySerializedConfig(jsonStr) local ok, decoded = pcall(function() return HttpService:JSONDecode(jsonStr) end) if not ok or type(decoded) ~= "table" or type(decoded.cfg) ~= "table" then return false end if type(decoded._clockTime) == "number" then currentClockTime = decoded._clockTime % 24 end if type(decoded._weather) == "string" then currentWeather = decoded._weather end if type(decoded._rtx) == "boolean" then rtxEnabled = decoded._rtx end for k, v in pairs(decoded.cfg) do if defaultConfig[k] ~= nil then if type(v) == "table" and v.__colorHex then local c = hexToColor(v.__colorHex) if c then customConfig[k] = c end elseif typeof(v) == typeof(defaultConfig[k]) then customConfig[k] = v end end end camera.FieldOfView = customConfig.fov syncAllUI() updateEnvironment() updateWetSurfaces() return true end local function applyPresetTable(presetTbl) for k, v in pairs(defaultConfig) do customConfig[k] = v end currentClockTime = presetTbl._clockTime or 17.85 currentWeather = presetTbl._weather or "Clear" for k, v in pairs(presetTbl) do if k ~= "_clockTime" and k ~= "_weather" and k ~= "name" and defaultConfig[k] ~= nil then customConfig[k] = v end end camera.FieldOfView = customConfig.fov syncAllUI() updateEnvironment() updateWetSurfaces() end local builtInPresets = { { name = "🌇 Golden Realism (Default)", _clockTime = 17.85, _weather = "Clear", sunsetStyle = "Realistic", sunsetWarmth = 1.0, exposure = 0.05, bloomIntensity = 0.65, shadowSoftness = 0.12, colorTempKelvin = 6500 }, { name = "❄️ Nordic Crisp Morning", _clockTime = 7.4, _weather = "Cloudy", sunsetStyle = "ColdNordic", sunsetWarmth = 0.4, exposure = 0.12, colorTempKelvin = 7800, saturationOffset = -0.15, contrastOffset = 0.12, atmoHazeOffset = 0.6 }, { name = "🔮 Cyberpunk Neon Rain", _clockTime = 21.5, _weather = "Cyberpunk", exposure = 0.1, bloomIntensity = 1.35, bloomThreshold = 0.65, saturationOffset = 0.25, contrastOffset = 0.22, wetReflectanceMax = 0.65 }, { name = "🎭 Dark Moody Cinema", _clockTime = 18.8, _weather = "Overcast", exposure = -0.25, shadowSoftness = 0.08, diffuseScale = 0.45, saturationOffset = -0.35, contrastOffset = 0.28, cinemaBars = true, vignetteEnabled = true, vignetteOpacity = 0.5 }, { name = "🌸 Dreamy Pastel Sunset", _clockTime = 18.1, _weather = "Clear", sunsetStyle = "PastelPink", sunsetWarmth = 1.15, exposure = 0.18, bloomIntensity = 1.1, bloomSize = 42, shadowSoftness = 0.35, saturationOffset = 0.08, contrastOffset = -0.05 }, { name = "💎 Clean Studio Showcase", _clockTime = 13.5, _weather = "Clear", fullManualMode = true, manualBrightness = 2.4, colorTempKelvin = 6500, rigEnabled = true, rigAttachMode = "Character", atmoDensityMult = 0.55, dofEnabled = false }, } local savedCustomConfigs = {} -------------------------------------------------------------------- -- 7. ПОСТРОЕНИЕ УДОБНОГО SIDEBAR-ИНТЕРФЕЙСА (STUDIO UI v6.0) -------------------------------------------------------------------- local screenGui = Instance.new("ScreenGui") screenGui.Name = "UltraShaderStudio_v6" screenGui.ResetOnSpawn = false screenGui.IgnoreGuiInset = true screenGui.Parent = player:WaitForChild("PlayerGui") -- Кинематографические чёрные полосы (Letterbox) local topCinemaBar = Instance.new("Frame") topCinemaBar.Size = UDim2.new(1, 0, 0, 0) topCinemaBar.BackgroundColor3 = Color3.fromRGB(0, 0, 0) topCinemaBar.BorderSizePixel = 0 topCinemaBar.ZIndex = 1 topCinemaBar.Parent = screenGui local botCinemaBar = Instance.new("Frame") botCinemaBar.Size = UDim2.new(1, 0, 0, 0) botCinemaBar.AnchorPoint = Vector2.new(0, 1) botCinemaBar.Position = UDim2.new(0, 0, 1, 0) botCinemaBar.BackgroundColor3 = Color3.fromRGB(0, 0, 0) botCinemaBar.BorderSizePixel = 0 botCinemaBar.ZIndex = 1 botCinemaBar.Parent = screenGui local function updateCinemaBars() local targetSize = customConfig.cinemaBars and UDim2.new(1, 0, customConfig.cinemaBarHeight, 0) or UDim2.new(1, 0, 0, 0) TweenService:Create(topCinemaBar, TweenInfo.new(0.3, Enum.EasingStyle.Quart, Enum.EasingDirection.Out), { Size = targetSize }):Play() TweenService:Create(botCinemaBar, TweenInfo.new(0.3, Enum.EasingStyle.Quart, Enum.EasingDirection.Out), { Size = targetSize }):Play() end -- Мягкая виньетка local vignetteFrame = Instance.new("Frame") vignetteFrame.Size = UDim2.new(1, 0, 1, 0) vignetteFrame.BackgroundTransparency = 1 vignetteFrame.BorderSizePixel = 0 vignetteFrame.ZIndex = 0 vignetteFrame.Parent = screenGui local vignetteStroke = Instance.new("UIStroke") vignetteStroke.Color = Color3.fromRGB(0, 0, 0) vignetteStroke.Thickness = 65 vignetteStroke.Transparency = 1 vignetteStroke.Parent = vignetteFrame -- Солнечные блики (Bokeh Lens Flare) local sunGlareOverlay = Instance.new("Frame") sunGlareOverlay.Size = UDim2.new(1, 0, 1, 0) sunGlareOverlay.BackgroundColor3 = Color3.fromRGB(255, 228, 200) sunGlareOverlay.BackgroundTransparency = 1 sunGlareOverlay.BorderSizePixel = 0 sunGlareOverlay.ZIndex = 0 sunGlareOverlay.Parent = screenGui local bokehData = { { scale = -0.35, size = 125, col = Color3.fromRGB(255, 215, 175), maxAlpha = 0.85 }, { scale = 0.18, size = 68, col = Color3.fromRGB(255, 235, 195), maxAlpha = 0.82 }, { scale = 0.52, size = 100, col = Color3.fromRGB(245, 195, 165), maxAlpha = 0.85 }, { scale = 0.82, size = 50, col = Color3.fromRGB(235, 240, 255), maxAlpha = 0.80 }, } local bokehCircles = {} for _, data in ipairs(bokehData) do local f = Instance.new("Frame") f.Size = UDim2.new(0, data.size, 0, data.size) f.AnchorPoint = Vector2.new(0.5, 0.5) f.BackgroundColor3 = data.col f.BackgroundTransparency = 1 f.BorderSizePixel = 0 f.ZIndex = 0 f.Parent = screenGui local corner = Instance.new("UICorner") corner.CornerRadius = UDim.new(1, 0) corner.Parent = f local stroke = Instance.new("UIStroke") stroke.Color = Color3.fromRGB(255, 245, 225) stroke.Thickness = 1.5 stroke.Transparency = 1 stroke.Parent = f table.insert(bokehCircles, { frame = f, stroke = stroke, data = data }) end -- Плавающая кнопка быстрого открытия local toggleBtn = Instance.new("TextButton") toggleBtn.Size = UDim2.new(0, 44, 0, 44) toggleBtn.Position = UDim2.new(0, 16, 0.5, -22) toggleBtn.BackgroundColor3 = Color3.fromRGB(18, 20, 28) toggleBtn.TextColor3 = Color3.fromRGB(255, 205, 120) toggleBtn.Text = "⚙️" toggleBtn.TextSize = 21 toggleBtn.Font = Enum.Font.GothamBold toggleBtn.ZIndex = 12 toggleBtn.Parent = screenGui local toggleCorner = Instance.new("UICorner") toggleCorner.CornerRadius = UDim.new(0, 12) toggleCorner.Parent = toggleBtn local toggleStroke = Instance.new("UIStroke") toggleStroke.Color = Color3.fromRGB(235, 165, 75) toggleStroke.Thickness = 1.5 toggleStroke.Parent = toggleBtn -- Главное окно (640x540 с боковым меню) local mainFrame = Instance.new("Frame") mainFrame.Size = UDim2.new(0, 640, 0, 540) mainFrame.Position = UDim2.new(0, 72, 0.5, -270) mainFrame.BackgroundColor3 = Color3.fromRGB(14, 15, 21) mainFrame.BackgroundTransparency = 0.03 mainFrame.BorderSizePixel = 0 mainFrame.ClipsDescendants = true mainFrame.ZIndex = 5 mainFrame.Parent = screenGui local mainCorner = Instance.new("UICorner") mainCorner.CornerRadius = UDim.new(0, 14) mainCorner.Parent = mainFrame local mainStroke = Instance.new("UIStroke") mainStroke.Color = Color3.fromRGB(62, 68, 88) mainStroke.Thickness = 1.5 mainStroke.Parent = mainFrame toggleBtn.MouseButton1Click:Connect(function() mainFrame.Visible = not mainFrame.Visible end) -- Верхняя шапка окна local headerBar = Instance.new("Frame") headerBar.Size = UDim2.new(1, 0, 0, 42) headerBar.BackgroundColor3 = Color3.fromRGB(20, 22, 31) headerBar.BorderSizePixel = 0 headerBar.ZIndex = 6 headerBar.Parent = mainFrame local titleLabel = Instance.new("TextLabel") titleLabel.Size = UDim2.new(0, 250, 1, 0) titleLabel.Position = UDim2.new(0, 14, 0, 0) titleLabel.BackgroundTransparency = 1 titleLabel.Font = Enum.Font.GothamBlack titleLabel.TextColor3 = Color3.fromRGB(255, 208, 125) titleLabel.TextSize = 13 titleLabel.TextXAlignment = Enum.TextXAlignment.Left titleLabel.ZIndex = 7 titleLabel.Parent = headerBar onLangChanged(function() titleLabel.Text = tr("appTitle") end) -- FPS & Clock индикатор local fpsLabel = Instance.new("TextLabel") fpsLabel.Size = UDim2.new(0, 120, 0, 26) fpsLabel.Position = UDim2.new(1, -262, 0.5, -13) fpsLabel.BackgroundColor3 = Color3.fromRGB(28, 31, 44) fpsLabel.Font = Enum.Font.GothamBold fpsLabel.Text = "FPS: 60 | 17:51" fpsLabel.TextColor3 = Color3.fromRGB(125, 245, 165) fpsLabel.TextSize = 11 fpsLabel.ZIndex = 7 fpsLabel.Parent = headerBar local fpsCor = Instance.new("UICorner") fpsCor.CornerRadius = UDim.new(0, 7) fpsCor.Parent = fpsLabel -- Кнопка переключения языка (EN / RU) local langBtn = Instance.new("TextButton") langBtn.Size = UDim2.new(0, 64, 0, 26) langBtn.Position = UDim2.new(1, -134, 0.5, -13) langBtn.BackgroundColor3 = Color3.fromRGB(48, 82, 142) langBtn.Font = Enum.Font.GothamBlack langBtn.Text = "🌐 EN" langBtn.TextColor3 = Color3.fromRGB(255, 255, 255) langBtn.TextSize = 11 langBtn.ZIndex = 7 langBtn.Parent = headerBar local langCor = Instance.new("UICorner") langCor.CornerRadius = UDim.new(0, 7) langCor.Parent = langBtn langBtn.MouseButton1Click:Connect(function() currentLang = (currentLang == "EN") and "RU" or "EN" langBtn.Text = "🌐 " .. currentLang for _, fn in ipairs(i18nListeners) do fn() end end) -- Кнопка сворачивания окна (Minimize) local isMinimized = false local minBtn = Instance.new("TextButton") minBtn.Size = UDim2.new(0, 28, 0, 26) minBtn.Position = UDim2.new(1, -64, 0.5, -13) minBtn.BackgroundColor3 = Color3.fromRGB(34, 38, 52) minBtn.Font = Enum.Font.GothamBlack minBtn.Text = "—" minBtn.TextColor3 = Color3.fromRGB(220, 225, 240) minBtn.TextSize = 12 minBtn.ZIndex = 7 minBtn.Parent = headerBar local minCor = Instance.new("UICorner") minCor.CornerRadius = UDim.new(0, 7) minCor.Parent = minBtn minBtn.MouseButton1Click:Connect(function() isMinimized = not isMinimized minBtn.Text = isMinimized and "▢" or "—" local targetSize = isMinimized and UDim2.new(0, 640, 0, 42) or UDim2.new(0, 640, 0, 540) TweenService:Create(mainFrame, TweenInfo.new(0.25, Enum.EasingStyle.Quart, Enum.EasingDirection.Out), { Size = targetSize }):Play() end) -- Кнопка закрытия (Close) local closeBtn = Instance.new("TextButton") closeBtn.Size = UDim2.new(0, 28, 0, 26) closeBtn.Position = UDim2.new(1, -32, 0.5, -13) closeBtn.BackgroundColor3 = Color3.fromRGB(135, 42, 48) closeBtn.Font = Enum.Font.GothamBlack closeBtn.Text = "✕" closeBtn.TextColor3 = Color3.fromRGB(255, 255, 255) closeBtn.TextSize = 12 closeBtn.ZIndex = 7 closeBtn.Parent = headerBar local closeCor = Instance.new("UICorner") closeCor.CornerRadius = UDim.new(0, 7) closeCor.Parent = closeBtn closeBtn.MouseButton1Click:Connect(function() mainFrame.Visible = false end) -- Перетаскивание окна local draggingWindow = false local dragStart, startPos headerBar.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then draggingWindow = true dragStart = input.Position startPos = mainFrame.Position end end) UserInputService.InputEnded:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then draggingWindow = false end end) UserInputService.InputChanged:Connect(function(input) if draggingWindow and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then local delta = input.Position - dragStart mainFrame.Position = UDim2.new(startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y) end end) -- Левая боковая панель навигации (Sidebar) local sidebar = Instance.new("Frame") sidebar.Size = UDim2.new(0, 158, 1, -42) sidebar.Position = UDim2.new(0, 0, 0, 42) sidebar.BackgroundColor3 = Color3.fromRGB(18, 19, 27) sidebar.BorderSizePixel = 0 sidebar.ZIndex = 6 sidebar.Parent = mainFrame local sideTabContainer = Instance.new("Frame") sideTabContainer.Size = UDim2.new(1, -14, 1, -86) sideTabContainer.Position = UDim2.new(0, 7, 0, 8) sideTabContainer.BackgroundTransparency = 1 sideTabContainer.ZIndex = 7 sideTabContainer.Parent = sidebar local sideLayout = Instance.new("UIListLayout") sideLayout.SortOrder = Enum.SortOrder.LayoutOrder sideLayout.Padding = UDim.new(0, 5) sideLayout.Parent = sideTabContainer -- Нижние кнопки в сайдбаре (Сброс всего и Скрыть GUI) local resetAllBtn = Instance.new("TextButton") resetAllBtn.Size = UDim2.new(1, -14, 0, 30) resetAllBtn.Position = UDim2.new(0, 7, 1, -72) resetAllBtn.BackgroundColor3 = Color3.fromRGB(125, 42, 45) resetAllBtn.Font = Enum.Font.GothamBold resetAllBtn.TextColor3 = Color3.fromRGB(255, 240, 240) resetAllBtn.TextSize = 11 resetAllBtn.ZIndex = 7 resetAllBtn.Parent = sidebar local raCor = Instance.new("UICorner") raCor.CornerRadius = UDim.new(0, 7) raCor.Parent = resetAllBtn local hideGuiBtn = Instance.new("TextButton") hideGuiBtn.Size = UDim2.new(1, -14, 0, 28) hideGuiBtn.Position = UDim2.new(0, 7, 1, -36) hideGuiBtn.BackgroundColor3 = Color3.fromRGB(32, 36, 50) hideGuiBtn.Font = Enum.Font.GothamBold hideGuiBtn.TextColor3 = Color3.fromRGB(200, 210, 230) hideGuiBtn.TextSize = 11 hideGuiBtn.ZIndex = 7 hideGuiBtn.Parent = sidebar local hgCor = Instance.new("UICorner") hgCor.CornerRadius = UDim.new(0, 7) hgCor.Parent = hideGuiBtn onLangChanged(function() resetAllBtn.Text = tr("btnResetAll") hideGuiBtn.Text = tr("btnHideUI") end) resetAllBtn.MouseButton1Click:Connect(function() for k, v in pairs(defaultConfig) do customConfig[k] = v end currentClockTime = 17.85 currentWeather = "Clear" rtxEnabled = true camera.FieldOfView = 70 syncAllUI() updateCinemaBars() updateEnvironment() updateWetSurfaces() end) hideGuiBtn.MouseButton1Click:Connect(function() mainFrame.Visible = false toggleBtn.Visible = false end) -- Правая рабочая область (Поисковая строка + Контейнер страниц) local rightArea = Instance.new("Frame") rightArea.Size = UDim2.new(1, -158, 1, -42) rightArea.Position = UDim2.new(0, 158, 0, 42) rightArea.BackgroundTransparency = 1 rightArea.ZIndex = 6 rightArea.Parent = mainFrame local searchBox = Instance.new("TextBox") searchBox.Size = UDim2.new(1, -20, 0, 30) searchBox.Position = UDim2.new(0, 10, 0, 8) searchBox.BackgroundColor3 = Color3.fromRGB(22, 24, 35) searchBox.Font = Enum.Font.GothamMedium searchBox.PlaceholderColor3 = Color3.fromRGB(130, 138, 160) searchBox.Text = "" searchBox.TextColor3 = Color3.fromRGB(240, 245, 255) searchBox.TextSize = 11 searchBox.ClearTextOnFocus = false searchBox.TextXAlignment = Enum.TextXAlignment.Left searchBox.ZIndex = 7 searchBox.Parent = rightArea local sbPad = Instance.new("UIPadding") sbPad.PaddingLeft = UDim.new(0, 10) sbPad.PaddingRight = UDim.new(0, 28) sbPad.Parent = searchBox local sbCor = Instance.new("UICorner") sbCor.CornerRadius = UDim.new(0, 8) sbCor.Parent = searchBox local sbStroke = Instance.new("UIStroke") sbStroke.Color = Color3.fromRGB(48, 54, 74) sbStroke.Thickness = 1 sbStroke.Parent = searchBox local clearSearchBtn = Instance.new("TextButton") clearSearchBtn.Size = UDim2.new(0, 22, 0, 22) clearSearchBtn.Position = UDim2.new(1, 2, 0.5, -11) clearSearchBtn.BackgroundTransparency = 1 clearSearchBtn.Font = Enum.Font.GothamBold clearSearchBtn.Text = "✕" clearSearchBtn.TextColor3 = Color3.fromRGB(160, 168, 190) clearSearchBtn.TextSize = 11 clearSearchBtn.Visible = false clearSearchBtn.ZIndex = 8 clearSearchBtn.Parent = searchBox clearSearchBtn.MouseButton1Click:Connect(function() searchBox.Text = "" end) onLangChanged(function() searchBox.PlaceholderText = tr("searchPlaceholder") end) local pagesContainer = Instance.new("Frame") pagesContainer.Size = UDim2.new(1, -20, 1, -48) pagesContainer.Position = UDim2.new(0, 10, 0, 44) pagesContainer.BackgroundTransparency = 1 pagesContainer.ZIndex = 6 pagesContainer.Parent = rightArea local tabsInfo = { { id = "SkyWeather", key = "tab_SkyWeather" }, { id = "LightShadows", key = "tab_LightShadows" }, { id = "StudioRig", key = "tab_StudioRig" }, { id = "AtmoWorld", key = "tab_AtmoWorld" }, { id = "PostFX", key = "tab_PostFX" }, { id = "Camera", key = "tab_Camera" }, { id = "Configs", key = "tab_Configs" }, } local tabPages = {} local tabButtons = {} local searchableItems = {} -- { frame = Instance, getSearchText = fn } local function applySearchFilter() local query = string.lower(searchBox.Text or "") clearSearchBtn.Visible = (#query > 0) for _, item in ipairs(searchableItems) do if #query == 0 then item.frame.Visible = true else local txt = string.lower(item.getSearchText() or "") item.frame.Visible = (string.find(txt, query, 1, true) ~= nil) end end end searchBox:GetPropertyChangedSignal("Text"):Connect(applySearchFilter) local function switchTab(tabId) for id, page in pairs(tabPages) do page.Visible = (id == tabId) end for id, btn in pairs(tabButtons) do if id == tabId then btn.BackgroundColor3 = Color3.fromRGB(218, 132, 42) btn.TextColor3 = Color3.fromRGB(255, 255, 255) else btn.BackgroundColor3 = Color3.fromRGB(26, 28, 40) btn.TextColor3 = Color3.fromRGB(185, 192, 210) end end end for idx, tInfo in ipairs(tabsInfo) do local tBtn = Instance.new("TextButton") tBtn.Size = UDim2.new(1, 0, 0, 34) tBtn.BackgroundColor3 = Color3.fromRGB(26, 28, 40) tBtn.Font = Enum.Font.GothamBold tBtn.TextSize = 11 tBtn.TextXAlignment = Enum.TextXAlignment.Left tBtn.TextColor3 = Color3.fromRGB(185, 192, 210) tBtn.LayoutOrder = idx tBtn.ZIndex = 8 tBtn.Parent = sideTabContainer local tPad = Instance.new("UIPadding") tPad.PaddingLeft = UDim.new(0, 10) tPad.Parent = tBtn local tc = Instance.new("UICorner") tc.CornerRadius = UDim.new(0, 8) tc.Parent = tBtn onLangChanged(function() tBtn.Text = tr(tInfo.key) end) local page = Instance.new("ScrollingFrame") page.Name = "Page_" .. tInfo.id page.Size = UDim2.new(1, 0, 1, 0) page.BackgroundTransparency = 1 page.BorderSizePixel = 0 page.ScrollBarThickness = 4 page.ScrollBarImageColor3 = Color3.fromRGB(235, 155, 65) page.AutomaticCanvasSize = Enum.AutomaticSize.Y page.CanvasSize = UDim2.new(0, 0, 0, 0) page.Visible = false page.ZIndex = 6 page.Parent = pagesContainer local layout = Instance.new("UIListLayout") layout.SortOrder = Enum.SortOrder.LayoutOrder layout.Padding = UDim.new(0, 6) layout.Parent = page local pad = Instance.new("UIPadding") pad.PaddingRight = UDim.new(0, 8) pad.PaddingBottom = UDim.new(0, 16) pad.Parent = page tabPages[tInfo.id] = page tabButtons[tInfo.id] = tBtn tBtn.MouseButton1Click:Connect(function() switchTab(tInfo.id) end) end -------------------------------------------------------------------- -- 8. УЛУЧШЕННЫЕ UI-КОМПОНЕНТЫ (С ВВОДОМ ЧИСЕЛ, СБРОСОМ И HEX) -------------------------------------------------------------------- local orderCounter = 0 local function nextOrder() orderCounter = orderCounter + 1 return orderCounter end local function registerSearchable(frame, i18nKey) table.insert(searchableItems, { frame = frame, getSearchText = function() return (I18N.EN[i18nKey] or "") .. " " .. (I18N.RU[i18nKey] or "") .. " " .. tostring(i18nKey) end }) end local function createSectionHeader(parent, i18nKey) local lbl = Instance.new("TextLabel") lbl.Size = UDim2.new(1, 0, 0, 22) lbl.BackgroundTransparency = 1 lbl.Font = Enum.Font.GothamBlack lbl.TextColor3 = Color3.fromRGB(255, 198, 105) lbl.TextSize = 11 lbl.TextXAlignment = Enum.TextXAlignment.Left lbl.LayoutOrder = nextOrder() lbl.ZIndex = 7 lbl.Parent = parent onLangChanged(function() lbl.Text = tr(i18nKey) end) return lbl end local activeSliderUpdate = nil UserInputService.InputEnded:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then activeSliderUpdate = nil end end) UserInputService.InputChanged:Connect(function(input) if activeSliderUpdate and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then activeSliderUpdate(input.Position.X) end end) -- Улучшенный слайдер с ручным вводом значения и кнопкой сброса ↺ local function createSlider(parent, i18nKey, minVal, maxVal, defaultVal, decimals, callback) local container = Instance.new("Frame") container.Size = UDim2.new(1, 0, 0, 44) container.BackgroundColor3 = Color3.fromRGB(22, 24, 34) container.BorderSizePixel = 0 container.LayoutOrder = nextOrder() container.ZIndex = 7 container.Parent = container.Parent or parent local cor = Instance.new("UICorner") cor.CornerRadius = UDim.new(0, 8) cor.Parent = container local title = Instance.new("TextLabel") title.Size = UDim2.new(1, -105, 0, 18) title.Position = UDim2.new(0, 10, 0, 4) title.BackgroundTransparency = 1 title.Font = Enum.Font.GothamMedium title.TextColor3 = Color3.fromRGB(225, 230, 242) title.TextSize = 11 title.TextXAlignment = Enum.TextXAlignment.Left title.TextTruncate = Enum.TextTruncate.AtEnd title.ZIndex = 8 title.Parent = container local valBox = Instance.new("TextBox") valBox.Size = UDim2.new(0, 56, 0, 18) valBox.Position = UDim2.new(1, -86, 0, 4) valBox.BackgroundColor3 = Color3.fromRGB(32, 35, 48) valBox.Font = Enum.Font.GothamBold valBox.TextColor3 = Color3.fromRGB(255, 210, 130) valBox.TextSize = 10 valBox.ClearTextOnFocus = false valBox.ZIndex = 8 valBox.Parent = container local vbCor = Instance.new("UICorner") vbCor.CornerRadius = UDim.new(0, 5) vbCor.Parent = valBox local resetBtn = Instance.new("TextButton") resetBtn.Size = UDim2.new(0, 20, 0, 18) resetBtn.Position = UDim2.new(1, -26, 0, 4) resetBtn.BackgroundColor3 = Color3.fromRGB(36, 40, 54) resetBtn.Font = Enum.Font.GothamBold resetBtn.Text = "↺" resetBtn.TextColor3 = Color3.fromRGB(185, 195, 215) resetBtn.TextSize = 11 resetBtn.ZIndex = 8 resetBtn.Parent = container local rbCor = Instance.new("UICorner") rbCor.CornerRadius = UDim.new(0, 5) rbCor.Parent = resetBtn local track = Instance.new("Frame") track.Size = UDim2.new(1, -24, 0, 6) track.Position = UDim2.new(0, 12, 0, 30) track.BackgroundColor3 = Color3.fromRGB(40, 44, 60) track.BorderSizePixel = 0 track.ZIndex = 8 track.Parent = container local tc = Instance.new("UICorner") tc.CornerRadius = UDim.new(1, 0) tc.Parent = track local fill = Instance.new("Frame") fill.Size = UDim2.new(0, 0, 1, 0) fill.BackgroundColor3 = Color3.fromRGB(235, 145, 45) fill.BorderSizePixel = 0 fill.ZIndex = 9 fill.Parent = track local fc = Instance.new("UICorner") fc.CornerRadius = UDim.new(1, 0) fc.Parent = fill local knob = Instance.new("Frame") knob.Size = UDim2.new(0, 13, 0, 13) knob.AnchorPoint = Vector2.new(0.5, 0.5) knob.Position = UDim2.new(1, 0, 0.5, 0) knob.BackgroundColor3 = Color3.fromRGB(255, 255, 255) knob.ZIndex = 10 knob.Parent = fill local kc = Instance.new("UICorner") kc.CornerRadius = UDim.new(1, 0) kc.Parent = knob local fmt = "%." .. tostring(decimals or 2) .. "f" local currentVal = defaultVal local api = {} onLangChanged(function() title.Text = tr(i18nKey) end) function api:SetValue(val, silent) currentVal = math.clamp(val, minVal, maxVal) local alpha = (currentVal - minVal) / (maxVal - minVal) fill.Size = UDim2.new(alpha, 0, 1, 0) valBox.Text = string.format(fmt, currentVal) if not silent and callback then callback(currentVal) end end function api:SetCustomDisplay(displayStr, alpha) fill.Size = UDim2.new(math.clamp(alpha, 0, 1), 0, 1, 0) valBox.Text = displayStr end valBox.FocusLost:Connect(function() local num = tonumber(valBox.Text) if num then api:SetValue(num, false) else valBox.Text = string.format(fmt, currentVal) end end) resetBtn.MouseButton1Click:Connect(function() api:SetValue(defaultVal, false) end) local function updateFromX(inputX) local rel = math.clamp((inputX - track.AbsolutePosition.X) / track.AbsoluteSize.X, 0, 1) local val = minVal + rel * (maxVal - minVal) api:SetValue(val, false) end track.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then activeSliderUpdate = updateFromX updateFromX(input.Position.X) end end) registerSearchable(container, i18nKey) api:SetValue(defaultVal, true) return api end -- Компактный сворачиваемый RGB + HEX пикер local function createRGBPicker(parent, i18nKey, defaultColor, callback) local expanded = false local box = Instance.new("Frame") box.Size = UDim2.new(1, 0, 0, 32) box.BackgroundColor3 = Color3.fromRGB(21, 23, 33) box.BorderSizePixel = 0 box.ClipsDescendants = true box.LayoutOrder = nextOrder() box.ZIndex = 7 box.Parent = parent local cor = Instance.new("UICorner") cor.CornerRadius = UDim.new(0, 8) cor.Parent = box local stroke = Instance.new("UIStroke") stroke.Color = Color3.fromRGB(45, 50, 66) stroke.Thickness = 1 stroke.Parent = box local lbl = Instance.new("TextLabel") lbl.Size = UDim2.new(1, -175, 0, 32) lbl.Position = UDim2.new(0, 10, 0, 0) lbl.BackgroundTransparency = 1 lbl.Font = Enum.Font.GothamBold lbl.TextColor3 = Color3.fromRGB(228, 234, 245) lbl.TextSize = 11 lbl.TextXAlignment = Enum.TextXAlignment.Left lbl.TextTruncate = Enum.TextTruncate.AtEnd lbl.ZIndex = 8 lbl.Parent = box onLangChanged(function() lbl.Text = tr(i18nKey) end) local hexBox = Instance.new("TextBox") hexBox.Size = UDim2.new(0, 64, 0, 20) hexBox.Position = UDim2.new(1, -158, 0, 6) hexBox.BackgroundColor3 = Color3.fromRGB(32, 35, 48) hexBox.Font = Enum.Font.GothamBold hexBox.TextColor3 = Color3.fromRGB(235, 240, 255) hexBox.TextSize = 10 hexBox.ClearTextOnFocus = false hexBox.ZIndex = 8 hexBox.Parent = box local hc = Instance.new("UICorner") hc.CornerRadius = UDim.new(0, 5) hc.Parent = hexBox local previewBtn = Instance.new("TextButton") previewBtn.Size = UDim2.new(0, 54, 0, 20) previewBtn.Position = UDim2.new(1, -88, 0, 6) previewBtn.BackgroundColor3 = defaultColor previewBtn.Text = "▼" previewBtn.Font = Enum.Font.GothamBold previewBtn.TextSize = 9 previewBtn.TextColor3 = Color3.fromRGB(255, 255, 255) previewBtn.TextStrokeTransparency = 0.4 previewBtn.ZIndex = 8 previewBtn.Parent = box local pc = Instance.new("UICorner") pc.CornerRadius = UDim.new(0, 5) pc.Parent = previewBtn local resetBtn = Instance.new("TextButton") resetBtn.Size = UDim2.new(0, 20, 0, 20) resetBtn.Position = UDim2.new(1, -28, 0, 6) resetBtn.BackgroundColor3 = Color3.fromRGB(36, 40, 54) resetBtn.Font = Enum.Font.GothamBold resetBtn.Text = "↺" resetBtn.TextColor3 = Color3.fromRGB(185, 195, 215) resetBtn.TextSize = 11 resetBtn.ZIndex = 8 resetBtn.Parent = box local rc = Instance.new("UICorner") rc.CornerRadius = UDim.new(0, 5) rc.Parent = resetBtn local rVal = math.floor(defaultColor.R * 255 + 0.5) local gVal = math.floor(defaultColor.G * 255 + 0.5) local bVal = math.floor(defaultColor.B * 255 + 0.5) local channels = { { name = "R", col = Color3.fromRGB(235, 75, 75), y = 40 }, { name = "G", col = Color3.fromRGB(75, 215, 105), y = 60 }, { name = "B", col = Color3.fromRGB(80, 155, 245), y = 80 }, } local fills = {} local valLabels = {} local api = {} local function refreshUI(silent) local c = Color3.fromRGB(rVal, gVal, bVal) previewBtn.BackgroundColor3 = c hexBox.Text = colorToHex(c) fills[1].Size = UDim2.new(rVal / 255, 0, 1, 0) fills[2].Size = UDim2.new(gVal / 255, 0, 1, 0) fills[3].Size = UDim2.new(bVal / 255, 0, 1, 0) valLabels[1].Text = "R: " .. rVal valLabels[2].Text = "G: " .. gVal valLabels[3].Text = "B: " .. bVal if not silent and callback then callback(c) end end for idx, ch in ipairs(channels) do local cLbl = Instance.new("TextLabel") cLbl.Size = UDim2.new(0, 46, 0, 16) cLbl.Position = UDim2.new(0, 10, 0, ch.y - 4) cLbl.BackgroundTransparency = 1 cLbl.Font = Enum.Font.GothamBold cLbl.TextColor3 = ch.col cLbl.TextSize = 10 cLbl.TextXAlignment = Enum.TextXAlignment.Left cLbl.ZIndex = 8 cLbl.Parent = box valLabels[idx] = cLbl local trk = Instance.new("Frame") trk.Size = UDim2.new(1, -68, 0, 7) trk.Position = UDim2.new(0, 56, 0, ch.y) trk.BackgroundColor3 = Color3.fromRGB(38, 42, 56) trk.BorderSizePixel = 0 trk.ZIndex = 8 trk.Parent = box local tc = Instance.new("UICorner") tc.CornerRadius = UDim.new(1, 0) tc.Parent = trk local fl = Instance.new("Frame") fl.Size = UDim2.new(0, 0, 1, 0) fl.BackgroundColor3 = ch.col fl.BorderSizePixel = 0 fl.ZIndex = 9 fl.Parent = trk local fc = Instance.new("UICorner") fc.CornerRadius = UDim.new(1, 0) fc.Parent = fl fills[idx] = fl local function updateChannelFromX(inputX) local rel = math.clamp((inputX - trk.AbsolutePosition.X) / trk.AbsoluteSize.X, 0, 1) local v = math.floor(rel * 255 + 0.5) if idx == 1 then rVal = v elseif idx == 2 then gVal = v else bVal = v end refreshUI(false) end trk.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then activeSliderUpdate = updateChannelFromX updateChannelFromX(input.Position.X) end end) end previewBtn.MouseButton1Click:Connect(function() expanded = not expanded previewBtn.Text = expanded and "▲" or "▼" box.Size = expanded and UDim2.new(1, 0, 0, 96) or UDim2.new(1, 0, 0, 32) end) hexBox.FocusLost:Connect(function() local parsed = hexToColor(hexBox.Text) if parsed then api:SetColor(parsed, false) else hexBox.Text = colorToHex(Color3.fromRGB(rVal, gVal, bVal)) end end) resetBtn.MouseButton1Click:Connect(function() api:SetColor(defaultColor, false) end) function api:SetColor(c, silent) rVal = math.floor(c.R * 255 + 0.5) gVal = math.floor(c.G * 255 + 0.5) bVal = math.floor(c.B * 255 + 0.5) refreshUI(silent) end registerSearchable(box, i18nKey) refreshUI(true) return api end local function createToggle(parent, i18nKey, defaultState, callback) local btn = Instance.new("TextButton") btn.Size = UDim2.new(1, 0, 0, 30) btn.Font = Enum.Font.GothamBold btn.TextColor3 = Color3.fromRGB(240, 245, 255) btn.TextSize = 11 btn.LayoutOrder = nextOrder() btn.ZIndex = 7 btn.Parent = parent local cor = Instance.new("UICorner") cor.CornerRadius = UDim.new(0, 8) cor.Parent = btn local state = defaultState local api = {} local function updateVisual() btn.BackgroundColor3 = state and Color3.fromRGB(36, 86, 60) or Color3.fromRGB(26, 28, 40) btn.Text = tr(i18nKey) .. ": " .. (state and tr("stateOn") or tr("stateOff")) end onLangChanged(updateVisual) function api:SetState(newState, silent) state = newState updateVisual() if not silent and callback then callback(state) end end btn.MouseButton1Click:Connect(function() api:SetState(not state, false) end) registerSearchable(btn, i18nKey) return api end local function createGridFrame(parent, columns, cellHeight) local holder = Instance.new("Frame") holder.Size = UDim2.new(1, 0, 0, cellHeight) holder.AutomaticSize = Enum.AutomaticSize.Y holder.BackgroundTransparency = 1 holder.LayoutOrder = nextOrder() holder.ZIndex = 7 holder.Parent = parent local grid = Instance.new("UIGridLayout") grid.CellSize = UDim2.new(1 / columns, -6, 0, cellHeight) grid.CellPadding = UDim2.new(0, 6, 0, 6) grid.SortOrder = Enum.SortOrder.LayoutOrder grid.Parent = holder return holder end local function createGridButton(gridParent, i18nKeyOrRaw, bgCol, callback, isRawText) local b = Instance.new("TextButton") b.BackgroundColor3 = bgCol or Color3.fromRGB(30, 33, 46) b.Font = Enum.Font.GothamBold b.TextColor3 = Color3.fromRGB(245, 245, 255) b.TextSize = 11 b.LayoutOrder = nextOrder() b.ZIndex = 8 b.Parent = gridParent local c = Instance.new("UICorner") c.CornerRadius = UDim.new(0, 7) c.Parent = b local s = Instance.new("UIStroke") s.Color = Color3.fromRGB(56, 62, 82) s.Thickness = 1 s.Parent = b if isRawText then b.Text = i18nKeyOrRaw else onLangChanged(function() b.Text = tr(i18nKeyOrRaw) end) end if callback then b.MouseButton1Click:Connect(callback) end return b, s end local function bindSlider(parent, i18nKey, cfgKey, minV, maxV, dec, extraFn) local s = createSlider(parent, i18nKey, minV, maxV, customConfig[cfgKey], dec, function(v) customConfig[cfgKey] = v if extraFn then extraFn(v) end updateEnvironment() end) table.insert(uiSyncCallbacks, function() s:SetValue(customConfig[cfgKey], true) end) return s end local function bindToggle(parent, i18nKey, cfgKey, extraFn) local t = createToggle(parent, i18nKey, customConfig[cfgKey], function(st) customConfig[cfgKey] = st if extraFn then extraFn(st) end updateEnvironment() end) table.insert(uiSyncCallbacks, function() t:SetState(customConfig[cfgKey], true) end) return t end local function bindColor(parent, i18nKey, cfgKey, extraFn) local p = createRGBPicker(parent, i18nKey, customConfig[cfgKey], function(c) customConfig[cfgKey] = c if extraFn then extraFn(c) end updateEnvironment() end) table.insert(uiSyncCallbacks, function() p:SetColor(customConfig[cfgKey], true) end) return p end -------------------------------------------------------------------- -- 9. ЗАПОЛНЕНИЕ 7 ВКЛАДОК НАСТРОЕК -------------------------------------------------------------------- -- ==================== TAB 1: SKY & WEATHER ==================== local pSky = tabPages["SkyWeather"] createSectionHeader(pSky, "sec_Sunset") local sunsetGrid = createGridFrame(pSky, 2, 28) local sunsetDefs = { { id = "Realistic", key = "style_Realistic" }, { id = "PastelPink", key = "style_PastelPink" }, { id = "ColdNordic", key = "style_ColdNordic" }, { id = "WarmCinema", key = "style_WarmCinema" }, } local sunsetBtns = {} local function refreshSunsetButtons() for id, b in pairs(sunsetBtns) do b.BackgroundColor3 = (id == customConfig.sunsetStyle) and Color3.fromRGB(205, 118, 45) or Color3.fromRGB(28, 30, 42) end end for _, st in ipairs(sunsetDefs) do local b = createGridButton(sunsetGrid, st.key, Color3.fromRGB(28, 30, 42), function() customConfig.sunsetStyle = st.id refreshSunsetButtons() updateEnvironment() end) sunsetBtns[st.id] = b end table.insert(uiSyncCallbacks, refreshSunsetButtons) refreshSunsetButtons() bindSlider(pSky, "sunsetWarmth", "sunsetWarmth", 0.0, 1.8, 2) createSectionHeader(pSky, "sec_TimeCelestial") local timeSlider = createSlider(pSky, "clockTime", 0, 24, currentClockTime, 2, function(val) currentClockTime = val % 24 local h = math.floor(currentClockTime) local m = math.floor((currentClockTime - h) * 60) updateEnvironment() end) local function syncTimeUI() local h = math.floor(currentClockTime) local m = math.floor((currentClockTime - h) * 60) timeSlider:SetCustomDisplay(string.format("%02d:%02d", h, m), (currentClockTime % 24) / 24) end table.insert(uiSyncCallbacks, syncTimeUI) local qtGrid = createGridFrame(pSky, 3, 28) local quickTimes = { { key = "qt_Dawn", time = 5.15, col = Color3.fromRGB(68, 76, 112) }, { key = "qt_Sunrise", time = 6.3, col = Color3.fromRGB(172, 115, 90) }, { key = "qt_Noon", time = 12.0, col = Color3.fromRGB(58, 112, 172) }, { key = "qt_Sunset", time = 17.85, col = Color3.fromRGB(185, 112, 82) }, { key = "qt_Dusk", time = 18.6, col = Color3.fromRGB(142, 82, 102) }, { key = "qt_Midnight", time = 0.0, col = Color3.fromRGB(32, 42, 72) }, } for _, qt in ipairs(quickTimes) do createGridButton(qtGrid, qt.key, qt.col, function() currentClockTime = qt.time syncTimeUI() updateEnvironment() end) end createToggle(pSky, "autoTime", false, function(st) autoTimeEnabled = st end) createSlider(pSky, "timeSpeed", 0.1, 10.0, secondsPerGameMinute, 1, function(v) secondsPerGameMinute = v end) bindSlider(pSky, "latitude", "geographicLatitude", -90, 90, 0) bindSlider(pSky, "sunSize", "sunAngularSize", 1, 60, 0) bindSlider(pSky, "moonSize", "moonAngularSize", 1, 60, 0) bindSlider(pSky, "starCount", "starCount", 0, 5000, 0) bindToggle(pSky, "celestialShown", "celestialShown") createSectionHeader(pSky, "sec_Weather") local weatherDefs = { { id = "Clear", key = "w_Clear" }, { id = "Cloudy", key = "w_Cloudy" }, { id = "Overcast", key = "w_Overcast" }, { id = "Rain", key = "w_Rain" }, { id = "Snow", key = "w_Snow" }, { id = "Fog", key = "w_Fog" }, { id = "Cyberpunk", key = "w_Cyberpunk" }, } local weatherGrid = createGridFrame(pSky, 2, 28) local weatherBtns = {} local function refreshWeatherButtons() for id, item in pairs(weatherBtns) do item.btn.BackgroundColor3 = (id == currentWeather) and Color3.fromRGB(45, 82, 136) or Color3.fromRGB(26, 28, 40) item.stroke.Color = (id == currentWeather) and Color3.fromRGB(100, 175, 255) or Color3.fromRGB(56, 62, 82) end end for _, wd in ipairs(weatherDefs) do local b, s = createGridButton(weatherGrid, wd.key, Color3.fromRGB(26, 28, 40), function() currentWeather = wd.id refreshWeatherButtons() updateEnvironment() updateWetSurfaces() end) weatherBtns[wd.id] = { btn = b, stroke = s } end table.insert(uiSyncCallbacks, refreshWeatherButtons) refreshWeatherButtons() bindSlider(pSky, "rainRate", "rainRateMult", 0.1, 2.5, 2) bindSlider(pSky, "wetReflectance", "wetReflectanceMax", 0.0, 0.85, 2, function() updateWetSurfaces() end) bindSlider(pSky, "rainVolume", "rainVolumeMult", 0.0, 2.0, 2) bindToggle(pSky, "rainSplashes", "rainSplashes") bindSlider(pSky, "dustRate", "dustRate", 0, 250, 0) local lGrid = createGridFrame(pSky, 1, 30) createGridButton(lGrid, "btnLightning", Color3.fromRGB(62, 82, 145), triggerLightningStrike) -- ==================== TAB 2: LIGHT & SHADOWS ==================== local pLight = tabPages["LightShadows"] createSectionHeader(pLight, "sec_LightMode") bindToggle(pLight, "fullManualMode", "fullManualMode") local spGrid = createGridFrame(pLight, 2, 28) local shadowPresets = { { key = "sp_SharpRTX", shadows = true, soft = 0.03, exp = 0.05, diff = 1.0, spec = 1.0 }, { key = "sp_SoftReal", shadows = true, soft = 0.22, exp = 0.05, diff = 0.9, spec = 0.9 }, { key = "sp_HighContrast", shadows = true, soft = 0.0, exp = -0.05, diff = 0.55, spec = 1.0 }, { key = "sp_SoftDiffused", shadows = true, soft = 0.65, exp = 0.12, diff = 1.0, spec = 0.65 }, { key = "sp_DarkCinema", shadows = true, soft = 0.10, exp = -0.18, diff = 0.35, spec = 1.0 }, { key = "sp_MaxFPS", shadows = false, soft = 0.5, exp = 0.05, diff = 0.7, spec = 0.3 }, } for _, sp in ipairs(shadowPresets) do createGridButton(spGrid, sp.key, Color3.fromRGB(34, 38, 54), function() customConfig.globalShadows = sp.shadows customConfig.shadowSoftness = sp.soft customConfig.exposure = sp.exp customConfig.diffuseScale = sp.diff customConfig.specularScale = sp.spec syncAllUI() updateEnvironment() end) end createSectionHeader(pLight, "sec_DirectShadows") bindToggle(pLight, "globalShadows", "globalShadows") local rtxTog = createToggle(pLight, "rtxReflections", rtxEnabled, function(st) rtxEnabled = st updateEnvironment() updateWetSurfaces() end) table.insert(uiSyncCallbacks, function() rtxTog:SetState(rtxEnabled, true) end) bindSlider(pLight, "colorTemp", "colorTempKelvin", 2000, 11000, 0) bindSlider(pLight, "tempTint", "tempTintShift", -1.0, 1.0, 2) bindSlider(pLight, "brightnessMult", "brightnessMult", 0.0, 4.0, 2) bindSlider(pLight, "manualBrightness", "manualBrightness", 0.0, 6.0, 2) bindSlider(pLight, "exposure", "exposure", -2.5, 2.5, 2) bindSlider(pLight, "shadowSoftness", "shadowSoftness", 0.0, 1.0, 2) createSectionHeader(pLight, "sec_AmbientPBR") bindSlider(pLight, "outdoorBoost", "outdoorAmbientBoost", 0.0, 2.5, 2) bindSlider(pLight, "ambientBoost", "ambientBoost", 0.0, 2.5, 2) bindSlider(pLight, "specularScale", "specularScale", 0.0, 1.0, 2) bindSlider(pLight, "diffuseScale", "diffuseScale", 0.0, 1.0, 2) createSectionHeader(pLight, "sec_ManualRGB") bindToggle(pLight, "manualLightColors", "manualLightColors") bindColor(pLight, "col_Top", "manualTopColor") bindColor(pLight, "col_Bot", "manualBotColor") bindColor(pLight, "col_Outdoor", "manualOutdoorColor") bindColor(pLight, "col_Ambient", "manualAmbientColor") -- ==================== TAB 3: 3-POINT STUDIO RIG ==================== local pRig = tabPages["StudioRig"] createSectionHeader(pRig, "sec_StudioRig") bindToggle(pRig, "rigEnabled", "rigEnabled") local rigModeGrid = createGridFrame(pRig, 3, 28) local rigModes = { { id = "Camera", key = "rigMode_Camera" }, { id = "Character", key = "rigMode_Char" }, { id = "World", key = "rigMode_World" }, } local rigModeBtns = {} local function refreshRigModeBtns() for id, b in pairs(rigModeBtns) do b.BackgroundColor3 = (id == customConfig.rigAttachMode) and Color3.fromRGB(205, 118, 45) or Color3.fromRGB(28, 30, 42) end end for _, rm in ipairs(rigModes) do local b = createGridButton(rigModeGrid, rm.key, Color3.fromRGB(28, 30, 42), function() customConfig.rigAttachMode = rm.id if rm.id == "World" then local char = player.Character local root = char and char:FindFirstChild("HumanoidRootPart") rigLockedWorldCF = root and root.CFrame or camera.CFrame end refreshRigModeBtns() end) rigModeBtns[rm.id] = b end table.insert(uiSyncCallbacks, refreshRigModeBtns) refreshRigModeBtns() bindToggle(pRig, "rigShadows", "rigShadows") bindSlider(pRig, "rigDistance", "rigDistance", 3, 35, 1) bindSlider(pRig, "keyBright", "keyBrightness", 0.0, 6.0, 2) bindSlider(pRig, "keyRange", "keyRange", 5, 60, 0) bindColor(pRig, "col_Key", "keyColor") bindSlider(pRig, "fillBright", "fillBrightness", 0.0, 6.0, 2) bindSlider(pRig, "fillRange", "fillRange", 5, 60, 0) bindColor(pRig, "col_Fill", "fillColor") bindSlider(pRig, "rimBright", "rimBrightness", 0.0, 6.0, 2) bindSlider(pRig, "rimRange", "rimRange", 5, 60, 0) bindColor(pRig, "col_Rim", "rimColor") -- ==================== TAB 4: ATMOSPHERE & WORLD ==================== local pAtmo = tabPages["AtmoWorld"] createSectionHeader(pAtmo, "sec_Atmosphere") bindToggle(pAtmo, "atmoEnabled", "atmoEnabled") bindSlider(pAtmo, "atmoDensity", "atmoDensityMult", 0.0, 2.5, 2) bindSlider(pAtmo, "atmoOffset", "atmoOffset", 0.0, 1.0, 2) bindSlider(pAtmo, "atmoHaze", "atmoHazeOffset", -1.0, 5.0, 2) bindSlider(pAtmo, "atmoGlare", "atmoGlareMult", 0.0, 3.0, 2) bindToggle(pAtmo, "manualAtmoColors", "manualAtmoColors") bindColor(pAtmo, "col_Atmo", "manualAtmoColor") bindColor(pAtmo, "col_Decay", "manualAtmoDecay") createSectionHeader(pAtmo, "sec_ClassicFog") bindSlider(pAtmo, "fogStart", "fogStart", 0, 1500, 0) bindSlider(pAtmo, "fogEnd", "fogEnd", 20, 5000, 0) bindColor(pAtmo, "col_Fog", "fogColor") createSectionHeader(pAtmo, "sec_CloudsWind") bindToggle(pAtmo, "cloudsEnabled", "cloudsEnabled") local cCovSlider = createSlider(pAtmo, "cloudCover", -0.05, 1.0, -0.05, 2, function(v) customConfig.cloudCoverOverride = (v < 0) and -1 or v updateEnvironment() end) local cDenSlider = createSlider(pAtmo, "cloudDensity", -0.05, 1.0, -0.05, 2, function(v) customConfig.cloudDensityOverride = (v < 0) and -1 or v updateEnvironment() end) table.insert(uiSyncCallbacks, function() cCovSlider:SetValue(customConfig.cloudCoverOverride < 0 and -0.05 or customConfig.cloudCoverOverride, true) cDenSlider:SetValue(customConfig.cloudDensityOverride < 0 and -0.05 or customConfig.cloudDensityOverride, true) end) bindToggle(pAtmo, "manualCloudColor", "manualCloudColor") bindColor(pAtmo, "col_Cloud", "cloudCustomColor") bindSlider(pAtmo, "windSpeed", "windSpeed", 0, 65, 0) bindSlider(pAtmo, "windAngle", "windAngle", 0, 360, 0) createSectionHeader(pAtmo, "sec_Water") bindSlider(pAtmo, "waterWaveSize", "waterWaveSize", 0.0, 1.0, 2) bindSlider(pAtmo, "waterWaveSpeed", "waterWaveSpeed", 0, 85, 0) bindSlider(pAtmo, "waterReflect", "waterReflectance", 0.0, 1.0, 2) bindSlider(pAtmo, "waterTrans", "waterTransparency", 0.0, 1.0, 2) bindColor(pAtmo, "col_Water", "waterColor") -- ==================== TAB 5: COLOR & POST-FX ==================== local pPost = tabPages["PostFX"] createSectionHeader(pPost, "sec_LUTs") local lutGrid = createGridFrame(pPost, 2, 28) local lutPresets = { { key = "lut_Natural", sat = 0.0, cont = 0.0, tint = Color3.fromRGB(255, 255, 255) }, { key = "lut_Clean", sat = -0.08, cont = 0.04, tint = Color3.fromRGB(255, 255, 255) }, { key = "lut_Film", sat = -0.05, cont = 0.12, tint = Color3.fromRGB(248, 246, 240) }, { key = "lut_Blockbuster", sat = 0.08, cont = 0.20, tint = Color3.fromRGB(242, 248, 255) }, { key = "lut_Pastel", sat = -0.14, cont = 0.08, tint = Color3.fromRGB(255, 240, 225) }, { key = "lut_Nordic", sat = -0.25, cont = 0.16, tint = Color3.fromRGB(215, 235, 255) }, { key = "lut_Cyber", sat = 0.32, cont = 0.24, tint = Color3.fromRGB(250, 230, 255) }, { key = "lut_Noir", sat = -1.0, cont = 0.38, tint = Color3.fromRGB(255, 255, 255) }, } for _, lut in ipairs(lutPresets) do createGridButton(lutGrid, lut.key, Color3.fromRGB(34, 38, 52), function() customConfig.saturationOffset = lut.sat customConfig.contrastOffset = lut.cont customConfig.tintColor = lut.tint syncAllUI() updateEnvironment() end) end createSectionHeader(pPost, "sec_ColorCorrection") bindToggle(pPost, "ccEnabled", "ccEnabled") bindSlider(pPost, "ccBrightness", "brightnessCC", -0.4, 0.4, 2) bindSlider(pPost, "ccSaturation", "saturationOffset", -1.0, 1.0, 2) bindSlider(pPost, "ccContrast", "contrastOffset", -0.8, 1.0, 2) bindColor(pPost, "col_Tint", "tintColor") createSectionHeader(pPost, "sec_BloomRaysBlur") bindToggle(pPost, "bloomEnabled", "bloomEnabled") bindSlider(pPost, "bloomIntensity", "bloomIntensity", 0.0, 3.0, 2) bindSlider(pPost, "bloomSize", "bloomSize", 0, 56, 0) bindSlider(pPost, "bloomThreshold", "bloomThreshold", 0.1, 2.5, 2) bindToggle(pPost, "sunRaysEnabled", "sunRaysEnabled") bindSlider(pPost, "sunRaysMult", "sunRaysMult", 0.0, 2.5, 2) bindSlider(pPost, "sunRaysSpread", "sunRaysSpread", 0.0, 1.0, 2) bindSlider(pPost, "blurSize", "blurSize", 0.0, 24.0, 1) bindToggle(pPost, "motionBlur", "motionBlurEnabled") bindSlider(pPost, "motionBlurStrength", "motionBlurStrength", 0.1, 1.5, 2) -- ==================== TAB 6: CAMERA & OPTICS ==================== local pCam = tabPages["Camera"] createSectionHeader(pCam, "sec_DoF") bindToggle(pCam, "dofEnabled", "dofEnabled") bindToggle(pCam, "dofAuto", "dofAutoFocus") bindSlider(pCam, "dofFar", "dofFarIntensity", 0.0, 1.0, 2) bindSlider(pCam, "dofNear", "dofNearIntensity", 0.0, 1.0, 2) bindSlider(pCam, "dofDist", "dofFocusDist", 5, 250, 0) bindSlider(pCam, "dofRadius", "dofRadius", 5, 150, 0) createSectionHeader(pCam, "sec_LensCinema") bindSlider(pCam, "fov", "fov", 20, 115, 0, function(v) camera.FieldOfView = v end) bindSlider(pCam, "camRoll", "cameraRoll", -45, 45, 0) bindToggle(pCam, "cinemaBars", "cinemaBars", updateCinemaBars) bindSlider(pCam, "cinemaHeight", "cinemaBarHeight", 0.04, 0.22, 2, function() if customConfig.cinemaBars then updateCinemaBars() end end) bindToggle(pCam, "vignette", "vignetteEnabled") bindSlider(pCam, "vignetteOpacity", "vignetteOpacity", 0.1, 0.9, 2) bindToggle(pCam, "lensFlare", "lensFlareEnabled") bindSlider(pCam, "flareIntensity", "lensFlareIntensity", 0.1, 1.5, 2) createSectionHeader(pCam, "sec_Freecam") local freecamActive = false local freecamPos = Vector3.zero local freecamAngles = Vector2.zero local freecamSpeed = 45 local function setFreecam(state) freecamActive = state local char = player.Character local root = char and char:FindFirstChild("HumanoidRootPart") if freecamActive then freecamPos = camera.CFrame.Position local rx, ry, _ = camera.CFrame:ToOrientation() freecamAngles = Vector2.new(rx, ry) camera.CameraType = Enum.CameraType.Scriptable if root then root.Anchored = true end else camera.CameraType = Enum.CameraType.Custom if root then root.Anchored = false end end end createToggle(pCam, "freecam", false, setFreecam) createSlider(pCam, "freecamSpeed", 5, 180, freecamSpeed, 0, function(v) freecamSpeed = v end) createSlider(pCam, "walkSpeed", 8, 100, 16, 0, function(v) local hum = player.Character and player.Character:FindFirstChildOfClass("Humanoid") if hum then hum.WalkSpeed = v end end) createSlider(pCam, "gravity", 15, 196.2, workspace.Gravity, 1, function(v) workspace.Gravity = v end) -- ==================== TAB 7: CONFIGS & PRESETS ==================== local pCfg = tabPages["Configs"] createSectionHeader(pCfg, "sec_BuiltInPresets") local presetGrid = createGridFrame(pCfg, 2, 30) for _, pr in ipairs(builtInPresets) do createGridButton(presetGrid, pr.name, Color3.fromRGB(34, 42, 60), function() applyPresetTable(pr) updateCinemaBars() end, true) end createSectionHeader(pCfg, "sec_CustomConfigs") local cfgNameBox = Instance.new("TextBox") cfgNameBox.Size = UDim2.new(1, 0, 0, 30) cfgNameBox.BackgroundColor3 = Color3.fromRGB(22, 24, 35) cfgNameBox.Font = Enum.Font.GothamMedium cfgNameBox.PlaceholderColor3 = Color3.fromRGB(130, 138, 160) cfgNameBox.Text = "" cfgNameBox.TextColor3 = Color3.fromRGB(240, 245, 255) cfgNameBox.TextSize = 11 cfgNameBox.ClearTextOnFocus = false cfgNameBox.LayoutOrder = nextOrder() cfgNameBox.ZIndex = 7 cfgNameBox.Parent = pCfg local cnbCor = Instance.new("UICorner") cnbCor.CornerRadius = UDim.new(0, 7) cnbCor.Parent = cfgNameBox local saveCfgBtn = Instance.new("TextButton") saveCfgBtn.Size = UDim2.new(1, 0, 0, 30) saveCfgBtn.BackgroundColor3 = Color3.fromRGB(38, 92, 64) saveCfgBtn.Font = Enum.Font.GothamBold saveCfgBtn.TextColor3 = Color3.fromRGB(255, 255, 255) saveCfgBtn.TextSize = 11 saveCfgBtn.LayoutOrder = nextOrder() saveCfgBtn.ZIndex = 7 saveCfgBtn.Parent = pCfg local scbCor = Instance.new("UICorner") scbCor.CornerRadius = UDim.new(0, 7) scbCor.Parent = saveCfgBtn local savedListFrame = Instance.new("Frame") savedListFrame.Size = UDim2.new(1, 0, 0, 0) savedListFrame.AutomaticSize = Enum.AutomaticSize.Y savedListFrame.BackgroundTransparency = 1 savedListFrame.LayoutOrder = nextOrder() savedListFrame.ZIndex = 7 savedListFrame.Parent = pCfg local slLayout = Instance.new("UIListLayout") slLayout.SortOrder = Enum.SortOrder.LayoutOrder slLayout.Padding = UDim.new(0, 5) slLayout.Parent = savedListFrame createSectionHeader(pCfg, "sec_ImportExport") local jsonBox = Instance.new("TextBox") jsonBox.Size = UDim2.new(1, 0, 0, 58) jsonBox.BackgroundColor3 = Color3.fromRGB(20, 22, 32) jsonBox.Font = Enum.Font.Code jsonBox.PlaceholderColor3 = Color3.fromRGB(120, 128, 150) jsonBox.Text = "" jsonBox.TextColor3 = Color3.fromRGB(185, 235, 195) jsonBox.TextSize = 10 jsonBox.TextWrapped = true jsonBox.ClearTextOnFocus = false jsonBox.TextXAlignment = Enum.TextXAlignment.Left jsonBox.TextYAlignment = Enum.TextYAlignment.Top jsonBox.LayoutOrder = nextOrder() jsonBox.ZIndex = 7 jsonBox.Parent = pCfg local jbPad = Instance.new("UIPadding") jbPad.PaddingLeft = UDim.new(0, 8) jbPad.PaddingRight = UDim.new(0, 8) jbPad.PaddingTop = UDim.new(0, 6) jbPad.Parent = jsonBox local jbCor = Instance.new("UICorner") jbCor.CornerRadius = UDim.new(0, 7) jbCor.Parent = jsonBox local ieGrid = createGridFrame(pCfg, 2, 30) local exportBtn = createGridButton(ieGrid, "btnExportCurrent", Color3.fromRGB(48, 75, 125), function() jsonBox.Text = serializeCurrentConfig() end) local importBtn = createGridButton(ieGrid, "btnImportBox", Color3.fromRGB(195, 115, 42), function() local ok = applySerializedConfig(jsonBox.Text) if ok then updateCinemaBars() else jsonBox.Text = tr("cfgInvalidMsg") end end) local function rebuildSavedConfigsList() for _, ch in ipairs(savedListFrame:GetChildren()) do if ch:IsA("Frame") then ch:Destroy() end end for idx, item in ipairs(savedCustomConfigs) do local row = Instance.new("Frame") row.Size = UDim2.new(1, 0, 0, 30) row.BackgroundColor3 = Color3.fromRGB(24, 27, 38) row.ZIndex = 7 row.Parent = savedListFrame local rCor = Instance.new("UICorner") rCor.CornerRadius = UDim.new(0, 7) rCor.Parent = row local nameLbl = Instance.new("TextLabel") nameLbl.Size = UDim2.new(1, -135, 1, 0) nameLbl.Position = UDim2.new(0, 10, 0, 0) nameLbl.BackgroundTransparency = 1 nameLbl.Font = Enum.Font.GothamBold nameLbl.Text = "📄 " .. item.name nameLbl.TextColor3 = Color3.fromRGB(235, 240, 255) nameLbl.TextSize = 11 nameLbl.TextXAlignment = Enum.TextXAlignment.Left nameLbl.ZIndex = 8 nameLbl.Parent = row local loadBtn = Instance.new("TextButton") loadBtn.Size = UDim2.new(0, 82, 0, 22) loadBtn.Position = UDim2.new(1, -116, 0.5, -11) loadBtn.BackgroundColor3 = Color3.fromRGB(48, 88, 145) loadBtn.Font = Enum.Font.GothamBold loadBtn.Text = tr("btnLoad") loadBtn.TextColor3 = Color3.fromRGB(255, 255, 255) loadBtn.TextSize = 10 loadBtn.ZIndex = 8 loadBtn.Parent = row local lCor = Instance.new("UICorner") lCor.CornerRadius = UDim.new(0, 5) lCor.Parent = loadBtn local delBtn = Instance.new("TextButton") delBtn.Size = UDim2.new(0, 24, 0, 22) delBtn.Position = UDim2.new(1, -28, 0.5, -11) delBtn.BackgroundColor3 = Color3.fromRGB(130, 42, 45) delBtn.Font = Enum.Font.GothamBold delBtn.Text = tr("btnDelete") delBtn.TextColor3 = Color3.fromRGB(255, 255, 255) delBtn.TextSize = 10 delBtn.ZIndex = 8 delBtn.Parent = row local dCor = Instance.new("UICorner") dCor.CornerRadius = UDim.new(0, 5) dCor.Parent = delBtn loadBtn.MouseButton1Click:Connect(function() applySerializedConfig(item.json) jsonBox.Text = item.json updateCinemaBars() end) delBtn.MouseButton1Click:Connect(function() table.remove(savedCustomConfigs, idx) rebuildSavedConfigsList() end) end end onLangChanged(function() cfgNameBox.PlaceholderText = tr("cfgNamePlaceholder") saveCfgBtn.Text = tr("btnSaveCfg") jsonBox.PlaceholderText = tr("jsonPlaceholder") rebuildSavedConfigsList() end) saveCfgBtn.MouseButton1Click:Connect(function() local name = cfgNameBox.Text if not name or #name:gsub("%s+", "") == 0 then name = "Config #" .. tostring(#savedCustomConfigs + 1) end local encoded = serializeCurrentConfig() table.insert(savedCustomConfigs, { name = name, json = encoded }) cfgNameBox.Text = "" jsonBox.Text = encoded rebuildSavedConfigsList() end) UserInputService.InputBegan:Connect(function(input, gpe) if gpe then return end if input.KeyCode == Enum.KeyCode.H then local vis = not toggleBtn.Visible toggleBtn.Visible = vis mainFrame.Visible = vis end end) switchTab("SkyWeather") -------------------------------------------------------------------- -- 10. ГЛАВНЫЙ ЦИКЛ РЕНДЕРА (FREECAM, MOTION BLUR, RIG, DOF, ОСАДКИ) -------------------------------------------------------------------- local snowAccumulator = 0 local splashAccumulator = 0 local wetTimer = 0 local lightningTimer = 0 local smoothGlare = 0 local fpsCounter = 60 local prevLookVec = camera.CFrame.LookVector local rayParams = RaycastParams.new() rayParams.FilterType = Enum.RaycastFilterType.Exclude local function spawnRainSplash(pos, normal) local splash = Instance.new("Part") splash.Size = Vector3.new(0.15, 0.02, 0.15) splash.Material = Enum.Material.Neon splash.Color = Color3.fromRGB(200, 225, 255) splash.Transparency = 0.45 splash.Anchored = true splash.CanCollide = false splash.CanQuery = false splash.CanTouch = false splash.CastShadow = false splash.CFrame = CFrame.lookAt(pos + normal * 0.03, pos + normal) * CFrame.Angles(math.rad(90), 0, 0) splash.Parent = fxFolder local mesh = Instance.new("CylinderMesh") mesh.Parent = splash TweenService:Create(splash, TweenInfo.new(0.28, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), { Size = Vector3.new(1.1, 0.02, 1.1), Transparency = 1 }):Play() Debris:AddItem(splash, 0.3) end RunService.RenderStepped:Connect(function(dt) fpsCounter = lerp(fpsCounter, 1 / math.max(dt, 0.001), 0.1) local h = math.floor(currentClockTime) local m = math.floor((currentClockTime - h) * 60) fpsLabel.Text = string.format("FPS: %d | %02d:%02d", math.floor(fpsCounter + 0.5), h, m) if autoTimeEnabled and not activeSliderUpdate then local hoursPerSecond = 1 / (secondsPerGameMinute * 60) currentClockTime = (currentClockTime + dt * hoursPerSecond) % 24 syncTimeUI() updateEnvironment() end -- Freecam & Camera Roll if freecamActive then if UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton2) then UserInputService.MouseBehavior = Enum.MouseBehavior.LockCurrentPosition local delta = UserInputService:GetMouseDelta() freecamAngles = Vector2.new( math.clamp(freecamAngles.X - delta.Y * 0.004, -math.rad(89), math.rad(89)), freecamAngles.Y - delta.X * 0.004 ) else UserInputService.MouseBehavior = Enum.MouseBehavior.Default end local rotCF = CFrame.fromOrientation(freecamAngles.X, freecamAngles.Y, math.rad(customConfig.cameraRoll)) local moveVec = Vector3.zero if UserInputService:IsKeyDown(Enum.KeyCode.W) then moveVec = moveVec + rotCF.LookVector end if UserInputService:IsKeyDown(Enum.KeyCode.S) then moveVec = moveVec - rotCF.LookVector end if UserInputService:IsKeyDown(Enum.KeyCode.D) then moveVec = moveVec + rotCF.RightVector end if UserInputService:IsKeyDown(Enum.KeyCode.A) then moveVec = moveVec - rotCF.RightVector end if UserInputService:IsKeyDown(Enum.KeyCode.E) then moveVec = moveVec + Vector3.new(0, 1, 0) end if UserInputService:IsKeyDown(Enum.KeyCode.Q) then moveVec = moveVec - Vector3.new(0, 1, 0) end local speedMult = UserInputService:IsKeyDown(Enum.KeyCode.LeftShift) and 2.2 or 1.0 freecamPos = freecamPos + moveVec * freecamSpeed * speedMult * dt camera.CFrame = CFrame.new(freecamPos) * rotCF elseif math.abs(customConfig.cameraRoll) > 0.1 then camera.CFrame = camera.CFrame * CFrame.Angles(0, 0, math.rad(customConfig.cameraRoll)) end -- Dynamic Camera Motion Blur local curLook = camera.CFrame.LookVector if customConfig.motionBlurEnabled then local angularSpeed = (curLook - prevLookVec).Magnitude / math.max(dt, 0.001) local targetBlur = customConfig.blurSize + math.clamp(angularSpeed * 2.2 * customConfig.motionBlurStrength, 0, 22) blurEffect.Size = lerp(blurEffect.Size, targetBlur, dt * 14) blurEffect.Enabled = (blurEffect.Size > 0.1) end prevLookVec = curLook local camPos = camera.CFrame.Position weatherDome.Position = camPos + Vector3.new(0, 28, 0) rayParams.FilterDescendantsInstances = { fxFolder, player.Character } -- Позиционирование 3-точечного студийного света (Key, Fill, Rim) if customConfig.rigEnabled then local anchorCF = camera.CFrame if customConfig.rigAttachMode == "Character" then local root = player.Character and player.Character:FindFirstChild("HumanoidRootPart") if root then anchorCF = root.CFrame end elseif customConfig.rigAttachMode == "World" then anchorCF = rigLockedWorldCF end local d = customConfig.rigDistance keyPart.CFrame = anchorCF * CFrame.new(d * 0.7, d * 0.45, -d * 0.75) fillPart.CFrame = anchorCF * CFrame.new(-d * 0.8, d * 0.15, -d * 0.6) rimPart.CFrame = anchorCF * CFrame.new(0, d * 0.55, d * 0.85) end vignetteStroke.Transparency = customConfig.vignetteEnabled and (1 - customConfig.vignetteOpacity) or 1 if customConfig.dofEnabled and customConfig.dofAutoFocus then local focusHit = workspace:Raycast(camPos, camera.CFrame.LookVector * 250, rayParams) local targetDist = focusHit and (focusHit.Position - camPos).Magnitude or 85 dof.FocusDistance = lerp(dof.FocusDistance, math.clamp(targetDist, 6, 220), dt * 8) end -- Оптические блики солнца (Lens Flare & Bokeh) if rtxEnabled and customConfig.lensFlareEnabled and sky.CelestialBodiesShown then local sunDir = Lighting:GetSunDirection() if sunDir.Y > -0.04 then local lookDot = math.clamp(camera.CFrame.LookVector:Dot(sunDir), 0, 1) local sunHit = workspace:Raycast(camPos, sunDir * 700, rayParams) local sunVisible = (sunHit == nil) and 1 or 0 local targetGlare = (lookDot ^ 3.0) * sunVisible * customConfig.lensFlareIntensity smoothGlare = lerp(smoothGlare, targetGlare, dt * 8) sunRays.Intensity = baseSunRays + smoothGlare * 0.28 bloom.Intensity = customConfig.bloomIntensity + smoothGlare * 0.45 sunGlareOverlay.BackgroundTransparency = math.clamp(1 - smoothGlare * 0.10, 0.88, 1) local sunScreenPos, onScreen = camera:WorldToViewportPoint(camPos + sunDir * 1000) local vpCenter = camera.ViewportSize * 0.5 local sun2D = Vector2.new(sunScreenPos.X, sunScreenPos.Y) local delta = vpCenter - sun2D for _, item in ipairs(bokehCircles) do if smoothGlare > 0.05 and onScreen then local pos = vpCenter + delta * item.data.scale item.frame.Position = UDim2.new(0, pos.X, 0, pos.Y) local vis = math.clamp(smoothGlare, 0, 1) item.frame.BackgroundTransparency = lerp(1, item.data.maxAlpha, vis) item.stroke.Transparency = lerp(1, item.data.maxAlpha - 0.08, vis) else item.frame.BackgroundTransparency = 1 item.stroke.Transparency = 1 end end else smoothGlare = lerp(smoothGlare, 0, dt * 6) sunRays.Intensity = lerp(sunRays.Intensity, 0, dt * 6) bloom.Intensity = lerp(bloom.Intensity, customConfig.bloomIntensity, dt * 6) sunGlareOverlay.BackgroundTransparency = 1 for _, item in ipairs(bokehCircles) do item.frame.BackgroundTransparency = 1 item.stroke.Transparency = 1 end end else sunRays.Intensity = lerp(sunRays.Intensity, baseSunRays, dt * 6) bloom.Intensity = lerp(bloom.Intensity, customConfig.bloomIntensity, dt * 6) sunGlareOverlay.BackgroundTransparency = 1 for _, item in ipairs(bokehCircles) do item.frame.BackgroundTransparency = 1 item.stroke.Transparency = 1 end end -- Дождь, лужи и гроза if currentWeather == "Rain" then local roofCheck = workspace:Raycast(camPos, Vector3.new(0, 50, 0), rayParams) local targetVol = (roofCheck and 0.22 or 0.70) * customConfig.rainVolumeMult local targetPitch = roofCheck and 0.8 or 1.0 rainSound.Volume = lerp(rainSound.Volume, targetVol, dt * 5) rainSound.PlaybackSpeed = lerp(rainSound.PlaybackSpeed, targetPitch, dt * 5) if customConfig.rainSplashes then splashAccumulator = splashAccumulator + dt if splashAccumulator >= 0.03 then splashAccumulator = 0 for _ = 1, 2 do local rx = math.random(-35, 35) local rz = math.random(-35, 35) local origin = camPos + Vector3.new(rx, 25, rz) local hit = workspace:Raycast(origin, Vector3.new(0, -60, 0), rayParams) if hit and hit.Normal.Y > 0.5 then spawnRainSplash(hit.Position, hit.Normal) end end end end wetTimer = wetTimer + dt if wetTimer > 1.5 then wetTimer = 0 updateWetSurfaces() end lightningTimer = lightningTimer + dt if lightningTimer > math.random(12, 22) and not isLightningActive then lightningTimer = 0 triggerLightningStrike() end end end) -- Физические 3D-снежинки RunService.Heartbeat:Connect(function(dt) if currentWeather ~= "Snow" then return end snowAccumulator = snowAccumulator + dt if snowAccumulator < 0.03 then return end snowAccumulator = 0 local camPos = camera.CFrame.Position local windVec = workspace.GlobalWind * 0.25 for _ = 1, 3 do local rx = math.random(-45, 45) local rz = math.random(-45, 45) local spawnPos = camPos + Vector3.new(rx, math.random(22, 32), rz) local roofHit = workspace:Raycast(spawnPos + Vector3.new(0, 30, 0), Vector3.new(0, -35, 0), rayParams) if not roofHit then local flake = Instance.new("Part") local flakeSize = math.random(14, 24) / 100 flake.Size = Vector3.new(flakeSize, flakeSize, flakeSize) flake.Shape = Enum.PartType.Ball flake.Material = Enum.Material.Neon flake.Color = Color3.fromRGB(245, 250, 255) flake.Transparency = math.random(15, 40) / 100 flake.CanCollide = false flake.CanTouch = false flake.CanQuery = false flake.CastShadow = false flake.Massless = true flake.CFrame = CFrame.new(spawnPos) flake.Parent = fxFolder flake.AssemblyLinearVelocity = Vector3.new( math.random(-4, 4) + windVec.X, -math.random(8, 13), math.random(-4, 4) + windVec.Z ) Debris:AddItem(flake, 3.5) end end end) syncTimeUI() updateEnvironment()