diff --git a/Assets/OctoCore/Data/settings.asset b/Assets/OctoCore/Data/settings.asset index 49684795..dce02313 100644 --- a/Assets/OctoCore/Data/settings.asset +++ b/Assets/OctoCore/Data/settings.asset @@ -13,7 +13,7 @@ MonoBehaviour: m_Name: settings m_EditorClassIdentifier: Application: - TargetFrameRate: 60 + TargetFrameRate: -1 VSyncCount: 0 Save: Booleans: @@ -202,6 +202,6 @@ MonoBehaviour: FadeOutDuration: 0.5 FadeColor: {r: 0, g: 0, b: 0, a: 1} Ui: - ReferenceSize: {x: 1440, y: 3120} + ReferenceSize: {x: 1920, y: 1080} IconsBackground: DefaultButton: {fileID: 0} diff --git a/Assets/Settings.meta b/Assets/Settings.meta new file mode 100644 index 00000000..7f0917d2 --- /dev/null +++ b/Assets/Settings.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3223e9cf0851176469211087c7397d6e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Settings/Build Profiles.meta b/Assets/Settings/Build Profiles.meta new file mode 100644 index 00000000..fe837910 --- /dev/null +++ b/Assets/Settings/Build Profiles.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f6c4c332e60f4b749b62ae09f89410b2 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Settings/Build Profiles/Windows.asset b/Assets/Settings/Build Profiles/Windows.asset new file mode 100644 index 00000000..a1cfb0f3 --- /dev/null +++ b/Assets/Settings/Build Profiles/Windows.asset @@ -0,0 +1,423 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-8040410276296602408 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 21008, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: UnityEngine.dll::UnityEngine.AdaptivePerformance.Basic.BasicProviderSettings + m_Logging: 0 + m_AutomaticPerformanceModeEnabled: 1 + m_AutomaticGameModeEnabled: 0 + m_EnableBoostOnStartup: 1 + m_StatsLoggingFrequencyInFrames: 0 + m_IndexerSettings: + m_Active: 1 + m_ThermalActionDelay: 10 + m_PerformanceActionDelay: 4 + m_ScalerSettings: + m_AdaptiveFramerate: + m_Name: Adaptive Framerate + m_Enabled: 0 + m_Scale: 1 + m_VisualImpact: 2 + m_Target: 7 + m_MaxLevel: 45 + m_MinBound: 15 + m_MaxBound: 60 + m_AdaptiveResolution: + m_Name: Adaptive Resolution + m_Enabled: 0 + m_Scale: 1 + m_VisualImpact: 0 + m_Target: 6 + m_MaxLevel: 9 + m_MinBound: 0.5 + m_MaxBound: 1 + m_AdaptiveBatching: + m_Name: Adaptive Batching + m_Enabled: 0 + m_Scale: 1 + m_VisualImpact: 1 + m_Target: 1 + m_MaxLevel: 1 + m_MinBound: 0 + m_MaxBound: 1 + m_AdaptiveLOD: + m_Name: Adaptive LOD + m_Enabled: 0 + m_Scale: 1 + m_VisualImpact: 2 + m_Target: 2 + m_MaxLevel: 3 + m_MinBound: 0.4 + m_MaxBound: 1 + m_AdaptiveLut: + m_Name: Adaptive Lut + m_Enabled: 0 + m_Scale: 1 + m_VisualImpact: 1 + m_Target: 3 + m_MaxLevel: 1 + m_MinBound: 0 + m_MaxBound: 1 + m_AdaptiveMSAA: + m_Name: Adaptive MSAA + m_Enabled: 0 + m_Scale: 1 + m_VisualImpact: 1 + m_Target: 6 + m_MaxLevel: 2 + m_MinBound: 0 + m_MaxBound: 1 + m_AdaptiveShadowCascade: + m_Name: Adaptive Shadow Cascade + m_Enabled: 0 + m_Scale: 1 + m_VisualImpact: 1 + m_Target: 3 + m_MaxLevel: 2 + m_MinBound: 0 + m_MaxBound: 1 + m_AdaptiveShadowDistance: + m_Name: Adaptive Shadow Distance + m_Enabled: 0 + m_Scale: 1 + m_VisualImpact: 0 + m_Target: 2 + m_MaxLevel: 3 + m_MinBound: 0.15 + m_MaxBound: 1 + m_AdaptiveShadowmapResolution: + m_Name: Adaptive Shadowmap Resolution + m_Enabled: 0 + m_Scale: 1 + m_VisualImpact: 0 + m_Target: 2 + m_MaxLevel: 3 + m_MinBound: 0.15 + m_MaxBound: 1 + m_AdaptiveShadowQuality: + m_Name: Adaptive Shadow Quality + m_Enabled: 0 + m_Scale: 1 + m_VisualImpact: 2 + m_Target: 3 + m_MaxLevel: 3 + m_MinBound: 0 + m_MaxBound: 1 + m_AdaptiveSorting: + m_Name: Adaptive Sorting + m_Enabled: 0 + m_Scale: 1 + m_VisualImpact: 1 + m_Target: 1 + m_MaxLevel: 1 + m_MinBound: 0 + m_MaxBound: 1 + m_AdaptiveTransparency: + m_Name: Adaptive Transparency + m_Enabled: 0 + m_Scale: 1 + m_VisualImpact: 2 + m_Target: 2 + m_MaxLevel: 1 + m_MinBound: 0 + m_MaxBound: 1 + m_AdaptiveViewDistance: + m_Name: Adaptive View Distance + m_Enabled: 0 + m_Scale: 1 + m_VisualImpact: 2 + m_Target: 2 + m_MaxLevel: 40 + m_MinBound: 50 + m_MaxBound: 1000 + m_AdaptivePhysics: + m_Name: Adaptive Physics + m_Enabled: 0 + m_Scale: 1 + m_VisualImpact: 0 + m_Target: 1 + m_MaxLevel: 5 + m_MinBound: 0.5 + m_MaxBound: 1 + m_AdaptiveDecals: + m_Name: Adaptive Decals + m_Enabled: 0 + m_Scale: 1 + m_VisualImpact: 1 + m_Target: 2 + m_MaxLevel: 20 + m_MinBound: 0.01 + m_MaxBound: 1 + m_AdaptiveLayerCulling: + m_Name: Adaptive Layer Culling + m_Enabled: 0 + m_Scale: 1 + m_VisualImpact: 1 + m_Target: 1 + m_MaxLevel: 40 + m_MinBound: 0.01 + m_MaxBound: 1 + m_scalerProfileList: + - m_AdaptiveFramerate: + m_Name: Adaptive Framerate + m_Enabled: 1 + m_Scale: 1 + m_VisualImpact: 2 + m_Target: 7 + m_MaxLevel: 45 + m_MinBound: 15 + m_MaxBound: 60 + m_AdaptiveResolution: + m_Name: Adaptive Resolution + m_Enabled: 1 + m_Scale: 1 + m_VisualImpact: 0 + m_Target: 6 + m_MaxLevel: 9 + m_MinBound: 0.5 + m_MaxBound: 1 + m_AdaptiveBatching: + m_Name: Adaptive Batching + m_Enabled: 1 + m_Scale: 1 + m_VisualImpact: 1 + m_Target: 1 + m_MaxLevel: 1 + m_MinBound: 0 + m_MaxBound: 1 + m_AdaptiveLOD: + m_Name: Adaptive LOD + m_Enabled: 0 + m_Scale: 1 + m_VisualImpact: 2 + m_Target: 2 + m_MaxLevel: 3 + m_MinBound: 0.4 + m_MaxBound: 1 + m_AdaptiveLut: + m_Name: Adaptive Lut + m_Enabled: 0 + m_Scale: 1 + m_VisualImpact: 1 + m_Target: 3 + m_MaxLevel: 1 + m_MinBound: 0 + m_MaxBound: 1 + m_AdaptiveMSAA: + m_Name: Adaptive MSAA + m_Enabled: 1 + m_Scale: 1 + m_VisualImpact: 1 + m_Target: 6 + m_MaxLevel: 2 + m_MinBound: 0 + m_MaxBound: 1 + m_AdaptiveShadowCascade: + m_Name: Adaptive Shadow Cascade + m_Enabled: 0 + m_Scale: 1 + m_VisualImpact: 1 + m_Target: 3 + m_MaxLevel: 2 + m_MinBound: 0 + m_MaxBound: 1 + m_AdaptiveShadowDistance: + m_Name: Adaptive Shadow Distance + m_Enabled: 1 + m_Scale: 1 + m_VisualImpact: 0 + m_Target: 2 + m_MaxLevel: 3 + m_MinBound: 0.15 + m_MaxBound: 1 + m_AdaptiveShadowmapResolution: + m_Name: Adaptive Shadowmap Resolution + m_Enabled: 1 + m_Scale: 1 + m_VisualImpact: 0 + m_Target: 2 + m_MaxLevel: 3 + m_MinBound: 0.15 + m_MaxBound: 1 + m_AdaptiveShadowQuality: + m_Name: Adaptive Shadow Quality + m_Enabled: 1 + m_Scale: 1 + m_VisualImpact: 2 + m_Target: 3 + m_MaxLevel: 3 + m_MinBound: 0 + m_MaxBound: 1 + m_AdaptiveSorting: + m_Name: Adaptive Sorting + m_Enabled: 0 + m_Scale: 1 + m_VisualImpact: 1 + m_Target: 1 + m_MaxLevel: 1 + m_MinBound: 0 + m_MaxBound: 1 + m_AdaptiveTransparency: + m_Name: Adaptive Transparency + m_Enabled: 0 + m_Scale: 1 + m_VisualImpact: 2 + m_Target: 2 + m_MaxLevel: 1 + m_MinBound: 0 + m_MaxBound: 1 + m_AdaptiveViewDistance: + m_Name: Adaptive View Distance + m_Enabled: 1 + m_Scale: 1 + m_VisualImpact: 2 + m_Target: 2 + m_MaxLevel: 40 + m_MinBound: 50 + m_MaxBound: 1000 + m_AdaptivePhysics: + m_Name: Adaptive Physics + m_Enabled: 0 + m_Scale: 1 + m_VisualImpact: 0 + m_Target: 1 + m_MaxLevel: 5 + m_MinBound: 0.5 + m_MaxBound: 1 + m_AdaptiveDecals: + m_Name: Adaptive Decals + m_Enabled: 0 + m_Scale: 1 + m_VisualImpact: 1 + m_Target: 2 + m_MaxLevel: 20 + m_MinBound: 0.01 + m_MaxBound: 1 + m_AdaptiveLayerCulling: + m_Name: Adaptive Layer Culling + m_Enabled: 1 + m_Scale: 1 + m_VisualImpact: 1 + m_Target: 1 + m_MaxLevel: 40 + m_MinBound: 0.01 + m_MaxBound: 1 + m_Name: Default Scaler Profile + m_DefaultScalerProfilerIndex: 0 + k_AssetVersion: 3 +--- !u!114 &-5753694202720027155 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 21007, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: UnityEngine.dll::UnityEngine.AdaptivePerformance.Basic.BasicProviderLoader +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 15003, guid: 0000000000000000e000000000000000, type: 0} + m_Name: Windows + m_EditorClassIdentifier: UnityEditor.dll::UnityEditor.Build.Profile.BuildProfile + m_AssetVersion: 1 + m_BuildTarget: 19 + m_Subtarget: 2 + m_PlatformId: 4e3c793746204150860bf175a9a41a05 + m_PlatformBuildProfile: + rid: 777404368997580871 + m_OverrideGlobalSceneList: 0 + m_Scenes: [] + m_HasScriptingDefines: 0 + m_ScriptingDefines: [] + m_PlayerSettingsYaml: + m_Settings: [] + references: + version: 2 + RefIds: + - rid: 777404368997580871 + type: {class: WindowsPlatformSettings, ns: UnityEditor.WindowsStandalone, asm: UnityEditor.WindowsStandalone.Extensions} + data: + m_Development: 0 + m_ConnectProfiler: 0 + m_BuildWithDeepProfilingSupport: 0 + m_AllowDebugging: 0 + m_WaitForManagedDebugger: 0 + m_ManagedDebuggerFixedPort: 0 + m_ExplicitNullChecks: 0 + m_ExplicitDivideByZeroChecks: 0 + m_ExplicitArrayBoundsChecks: 0 + m_CompressionType: 2 + m_InstallInBuildFolder: 0 + m_InsightsSettingsContainer: + m_BuildProfileEngineDiagnosticsState: 0 + m_AdaptivePerformanceEnabled: 0 + m_WindowsBuildAndRunDeployTarget: 0 + m_Architecture: 0 + m_CreateSolution: 0 + m_CopyPDBFiles: 0 + m_WindowsDevicePortalAddress: + m_WindowsDevicePortalUsername: +--- !u!114 &4165002225771193241 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 21001, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: UnityEngine.dll::UnityEngine.AdaptivePerformance.AdaptivePerformanceManagerSettings + m_AutomaticLoading: 0 + m_AutomaticRunning: 0 + m_Loaders: + - {fileID: -5753694202720027155} +--- !u!114 &5629712832191110986 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 21013, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: UnityEditor.dll::UnityEditor.AdaptivePerformance.Editor.Metadata.BuildProfileProviderContainer + m_AdaptivePerformanceProviderSettings: + - {fileID: -8040410276296602408} +--- !u!114 &8662654418772437197 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 21000, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: UnityEngine.dll::UnityEngine.AdaptivePerformance.AdaptivePerformanceGeneralSettings + m_LoaderManagerInstance: {fileID: 4165002225771193241} + m_InitManagerOnStart: 1 + m_LastSelectedProvider: diff --git a/Assets/Settings/Build Profiles/Windows.asset.meta b/Assets/Settings/Build Profiles/Windows.asset.meta new file mode 100644 index 00000000..a6e310d4 --- /dev/null +++ b/Assets/Settings/Build Profiles/Windows.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 713820e2c8e214b479490bd75412609d +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_Content/Materials/Toon/M_toon_post_process_default.mat b/Assets/_Content/Materials/Toon/M_toon_post_process_default.mat index 3af7a1d8..c54c3eb6 100644 --- a/Assets/_Content/Materials/Toon/M_toon_post_process_default.mat +++ b/Assets/_Content/Materials/Toon/M_toon_post_process_default.mat @@ -150,12 +150,12 @@ Material: - _OutlineNoiseScale: 300 - _OutlineNoiseStrength: 0.256 - _OutlineSoftness: 1 - - _OutlineThickness: 0.21 + - _OutlineThickness: 0.2 - _OutlineThicknessVar: 1 - _Parallax: 0.005 - _QueueOffset: 0 - _ReceiveShadows: 1 - - _ShaderWeight: 0.845 + - _ShaderWeight: 1 - _ShadowStrength: 1 - _Smoothness: 0.5 - _SmoothnessTextureChannel: 0 diff --git a/Assets/_Content/Models/Environments/Theatre/Materials/M_theatre_concrete.mat b/Assets/_Content/Models/Environments/Theatre/Materials/M_theatre_concrete.mat index 80c472d7..db8a104a 100644 --- a/Assets/_Content/Models/Environments/Theatre/Materials/M_theatre_concrete.mat +++ b/Assets/_Content/Models/Environments/Theatre/Materials/M_theatre_concrete.mat @@ -118,11 +118,11 @@ Material: - _Cull: 2 - _Cutoff: 0.5 - _DetailAlbedoMapScale: 1 - - _DetailIntensityA: 0.5 + - _DetailIntensityA: 0.3 - _DetailIntensityB: 0.5 - _DetailNormalMapScale: 1 - _DetailSize: 1 - - _DetailSizeA: 0.8 + - _DetailSizeA: 0.5 - _DetailSizeB: 1 - _DstBlend: 0 - _DstBlendAlpha: 0 diff --git a/Assets/_Content/Models/Props/Theatre/Furnitures/Lights/SpotlightOnTripod/Prefabs/Spotlight On Tripod.prefab b/Assets/_Content/Models/Props/Theatre/Furnitures/Lights/SpotlightOnTripod/Prefabs/Spotlight On Tripod.prefab index e92726f4..26f79a9e 100644 --- a/Assets/_Content/Models/Props/Theatre/Furnitures/Lights/SpotlightOnTripod/Prefabs/Spotlight On Tripod.prefab +++ b/Assets/_Content/Models/Props/Theatre/Furnitures/Lights/SpotlightOnTripod/Prefabs/Spotlight On Tripod.prefab @@ -806,7 +806,7 @@ Light: serializedVersion: 2 m_Bits: 4294967295 m_RenderingLayerMask: 13 - m_Lightmapping: 4 + m_Lightmapping: 1 m_LightShadowCasterMode: 0 m_AreaSize: {x: 1, y: 1} m_BounceIntensity: 0 diff --git a/Assets/_Content/Models/Props/Theatre/Furnitures/Lights/SpotlightTop/Prefabs/SpotlightTop.prefab b/Assets/_Content/Models/Props/Theatre/Furnitures/Lights/SpotlightTop/Prefabs/SpotlightTop.prefab index f0c64d0c..7bf3dcb2 100644 --- a/Assets/_Content/Models/Props/Theatre/Furnitures/Lights/SpotlightTop/Prefabs/SpotlightTop.prefab +++ b/Assets/_Content/Models/Props/Theatre/Furnitures/Lights/SpotlightTop/Prefabs/SpotlightTop.prefab @@ -46,12 +46,12 @@ Light: m_Type: 0 m_Color: {r: 0.7921569, g: 0.5803922, b: 0.32156864, a: 1} m_Intensity: 1500 - m_Range: 29 - m_SpotAngle: 54.753372 + m_Range: 24.095201 + m_SpotAngle: 30 m_InnerSpotAngle: 13.486629 m_CookieSize2D: {x: 10, y: 10} m_Shadows: - m_Type: 0 + m_Type: 1 m_Resolution: -1 m_CustomResolution: -1 m_Strength: 1 @@ -84,7 +84,7 @@ Light: serializedVersion: 2 m_Bits: 4294967295 m_RenderingLayerMask: 13 - m_Lightmapping: 4 + m_Lightmapping: 1 m_LightShadowCasterMode: 0 m_AreaSize: {x: 1, y: 1} m_BounceIntensity: 0 diff --git a/Assets/_Content/Models/Props/Theatre/Kits/IndustrialKit/Prefabs/spotlight_A.prefab b/Assets/_Content/Models/Props/Theatre/Kits/IndustrialKit/Prefabs/spotlight_A.prefab index 0f725e22..3f5266f1 100644 --- a/Assets/_Content/Models/Props/Theatre/Kits/IndustrialKit/Prefabs/spotlight_A.prefab +++ b/Assets/_Content/Models/Props/Theatre/Kits/IndustrialKit/Prefabs/spotlight_A.prefab @@ -82,7 +82,7 @@ MeshRenderer: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 3438387521784179324} - m_Enabled: 1 + m_Enabled: 0 m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 @@ -141,7 +141,7 @@ GameObject: m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 + m_StaticEditorFlags: 1 m_IsActive: 1 --- !u!4 &1424397006805052333 Transform: diff --git a/Assets/_Content/Scenes/Theatre.unity b/Assets/_Content/Scenes/Theatre.unity index 0308a768..cb0c9f53 100644 --- a/Assets/_Content/Scenes/Theatre.unity +++ b/Assets/_Content/Scenes/Theatre.unity @@ -8312,6 +8312,10 @@ PrefabInstance: propertyPath: m_Name value: spotlight_C (5) objectReference: {fileID: 0} + - target: {fileID: 5384500464928760839, guid: e7bb097752ed1e649b2eed5ce64be3a7, type: 3} + propertyPath: m_CastShadows + value: 0 + objectReference: {fileID: 0} - target: {fileID: 7997473343129277624, guid: e7bb097752ed1e649b2eed5ce64be3a7, type: 3} propertyPath: m_LocalPosition.x value: 8.902578 @@ -8352,6 +8356,10 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} + - target: {fileID: 9142186919531607142, guid: e7bb097752ed1e649b2eed5ce64be3a7, type: 3} + propertyPath: m_StaticEditorFlags + value: 1 + objectReference: {fileID: 0} m_RemovedComponents: [] m_RemovedGameObjects: [] m_AddedGameObjects: [] @@ -15029,6 +15037,10 @@ PrefabInstance: propertyPath: m_Name value: spotlight_C (3) objectReference: {fileID: 0} + - target: {fileID: 5384500464928760839, guid: e7bb097752ed1e649b2eed5ce64be3a7, type: 3} + propertyPath: m_CastShadows + value: 0 + objectReference: {fileID: 0} - target: {fileID: 7997473343129277624, guid: e7bb097752ed1e649b2eed5ce64be3a7, type: 3} propertyPath: m_LocalPosition.x value: 8.902578 @@ -15069,6 +15081,10 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} + - target: {fileID: 9142186919531607142, guid: e7bb097752ed1e649b2eed5ce64be3a7, type: 3} + propertyPath: m_StaticEditorFlags + value: 1 + objectReference: {fileID: 0} m_RemovedComponents: [] m_RemovedGameObjects: [] m_AddedGameObjects: [] @@ -1224358,6 +1224374,10 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} + - target: {fileID: 4224516816523089515, guid: a914811f92ae09e4da58ba6521252d85, type: 3} + propertyPath: m_Lightmapping + value: 2 + objectReference: {fileID: 0} - target: {fileID: 8334225068845063078, guid: a914811f92ae09e4da58ba6521252d85, type: 3} propertyPath: m_Name value: pillarSculpture_L @@ -1496608,6 +1496628,34 @@ PrefabInstance: propertyPath: m_IsActive value: 0 objectReference: {fileID: 0} + - target: {fileID: 3795876706762551794, guid: 65124df6e07fe0f438cd845f948aac8c, type: 3} + propertyPath: m_LocalRotation.w + value: 0.6369404 + objectReference: {fileID: 0} + - target: {fileID: 3795876706762551794, guid: 65124df6e07fe0f438cd845f948aac8c, type: 3} + propertyPath: m_LocalRotation.x + value: 0.7709076 + objectReference: {fileID: 0} + - target: {fileID: 3795876706762551794, guid: 65124df6e07fe0f438cd845f948aac8c, type: 3} + propertyPath: m_LocalRotation.y + value: -0.0024587153 + objectReference: {fileID: 0} + - target: {fileID: 3795876706762551794, guid: 65124df6e07fe0f438cd845f948aac8c, type: 3} + propertyPath: m_LocalRotation.z + value: 0.0015398163 + objectReference: {fileID: 0} + - target: {fileID: 3795876706762551794, guid: 65124df6e07fe0f438cd845f948aac8c, type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 100.87201 + objectReference: {fileID: 0} + - target: {fileID: 3795876706762551794, guid: 65124df6e07fe0f438cd845f948aac8c, type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0.22999573 + objectReference: {fileID: 0} + - target: {fileID: 3795876706762551794, guid: 65124df6e07fe0f438cd845f948aac8c, type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0.55599976 + objectReference: {fileID: 0} - target: {fileID: 4345676193667958489, guid: 65124df6e07fe0f438cd845f948aac8c, type: 3} propertyPath: m_Enabled value: 0 @@ -1497427,10 +1497475,6 @@ PrefabInstance: propertyPath: m_Name value: spotlight_A (3) objectReference: {fileID: 0} - - target: {fileID: 5867715795311792935, guid: 512704cfb7849d143b8f6232fdd650fb, type: 3} - propertyPath: m_Enabled - value: 0 - objectReference: {fileID: 0} m_RemovedComponents: [] m_RemovedGameObjects: [] m_AddedGameObjects: [] @@ -1784858,7 +1784902,7 @@ GameObject: m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 - m_StaticEditorFlags: 18 + m_StaticEditorFlags: 19 m_IsActive: 1 --- !u!4 &1158152704 Transform: @@ -1787270,7 +1787314,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 0 + m_IsActive: 1 --- !u!4 &1196872730 Transform: m_ObjectHideFlags: 0 @@ -1787927,7 +1787971,7 @@ GameObject: m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 - m_StaticEditorFlags: 18 + m_StaticEditorFlags: 19 m_IsActive: 1 --- !u!4 &1217965860 Transform: @@ -1792188,26 +1792232,6 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 2.17 objectReference: {fileID: 0} - - target: {fileID: 2824494044506281194, guid: 10e5caa37a9610f419d5423bb0c48bdf, type: 3} - propertyPath: m_Range - value: 24.095201 - objectReference: {fileID: 0} - - target: {fileID: 2824494044506281194, guid: 10e5caa37a9610f419d5423bb0c48bdf, type: 3} - propertyPath: m_Intensity - value: 1500 - objectReference: {fileID: 0} - - target: {fileID: 2824494044506281194, guid: 10e5caa37a9610f419d5423bb0c48bdf, type: 3} - propertyPath: m_SpotAngle - value: 30 - objectReference: {fileID: 0} - - target: {fileID: 2824494044506281194, guid: 10e5caa37a9610f419d5423bb0c48bdf, type: 3} - propertyPath: m_Shadows.m_Type - value: 1 - objectReference: {fileID: 0} - - target: {fileID: 2824494044506281194, guid: 10e5caa37a9610f419d5423bb0c48bdf, type: 3} - propertyPath: m_Shadows.m_NearPlane - value: 0.2 - objectReference: {fileID: 0} - target: {fileID: 3069673527672632347, guid: 10e5caa37a9610f419d5423bb0c48bdf, type: 3} propertyPath: m_AdditionalLightsShadowResolutionTier value: 1 @@ -3393788,6 +3393812,10 @@ PrefabInstance: propertyPath: m_Name value: spotlight_C (2) objectReference: {fileID: 0} + - target: {fileID: 5384500464928760839, guid: e7bb097752ed1e649b2eed5ce64be3a7, type: 3} + propertyPath: m_CastShadows + value: 0 + objectReference: {fileID: 0} - target: {fileID: 7997473343129277624, guid: e7bb097752ed1e649b2eed5ce64be3a7, type: 3} propertyPath: m_LocalPosition.x value: 8.902578 @@ -3393828,6 +3393856,10 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} + - target: {fileID: 9142186919531607142, guid: e7bb097752ed1e649b2eed5ce64be3a7, type: 3} + propertyPath: m_StaticEditorFlags + value: 1 + objectReference: {fileID: 0} m_RemovedComponents: [] m_RemovedGameObjects: [] m_AddedGameObjects: [] @@ -3393925,6 +3393957,10 @@ PrefabInstance: propertyPath: m_Name value: spotlight_C (4) objectReference: {fileID: 0} + - target: {fileID: 5384500464928760839, guid: e7bb097752ed1e649b2eed5ce64be3a7, type: 3} + propertyPath: m_CastShadows + value: 0 + objectReference: {fileID: 0} - target: {fileID: 7997473343129277624, guid: e7bb097752ed1e649b2eed5ce64be3a7, type: 3} propertyPath: m_LocalPosition.x value: -1.997421 @@ -3393965,6 +3394001,10 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} + - target: {fileID: 9142186919531607142, guid: e7bb097752ed1e649b2eed5ce64be3a7, type: 3} + propertyPath: m_StaticEditorFlags + value: 1 + objectReference: {fileID: 0} m_RemovedComponents: [] m_RemovedGameObjects: [] m_AddedGameObjects: [] @@ -3394181,6 +3394221,14 @@ PrefabInstance: serializedVersion: 3 m_TransformParent: {fileID: 622343290} m_Modifications: + - target: {fileID: 1476756471834662335, guid: 6493d77978c5c1246a0410d1f9204524, type: 3} + propertyPath: _stressLevel + value: 0.6 + objectReference: {fileID: 0} + - target: {fileID: 1476756471834662335, guid: 6493d77978c5c1246a0410d1f9204524, type: 3} + propertyPath: _masterIntensityInspector + value: 1.8 + objectReference: {fileID: 0} - target: {fileID: 1735456339091181674, guid: 6493d77978c5c1246a0410d1f9204524, type: 3} propertyPath: m_SlopeLimit value: 45 @@ -3505927,6 +3505975,10 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} + - target: {fileID: 4224516816523089515, guid: a914811f92ae09e4da58ba6521252d85, type: 3} + propertyPath: m_Lightmapping + value: 2 + objectReference: {fileID: 0} - target: {fileID: 8334225068845063078, guid: a914811f92ae09e4da58ba6521252d85, type: 3} propertyPath: m_Name value: pillarSculpture_R diff --git a/Assets/_Content/Settings/PC_RPAsset.asset b/Assets/_Content/Settings/PC_RPAsset.asset index 19c70c9b..f39f988c 100644 --- a/Assets/_Content/Settings/PC_RPAsset.asset +++ b/Assets/_Content/Settings/PC_RPAsset.asset @@ -100,7 +100,7 @@ MonoBehaviour: obsoleteHasProbeVolumes: m_Keys: [] m_Values: - m_PrefilteringModeMainLightShadows: 3 + m_PrefilteringModeMainLightShadows: 0 m_PrefilteringModeAdditionalLight: 0 m_PrefilteringModeAdditionalLightShadows: 2 m_PrefilterXRKeywords: 1 diff --git a/Assets/_Content/Settings/PC_Renderer.asset b/Assets/_Content/Settings/PC_Renderer.asset index 8293ef77..dd4e1388 100644 --- a/Assets/_Content/Settings/PC_Renderer.asset +++ b/Assets/_Content/Settings/PC_Renderer.asset @@ -283,7 +283,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: a1614fc811f8f184697d9bee70ab9fe5, type: 3} m_Name: DecalRendererFeature m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.DecalRendererFeature - m_Active: 1 + m_Active: 0 m_Settings: technique: 0 maxDrawDistance: 1000 diff --git a/Assets/_Content/Shaders/EnkiBilal/Include/EnkiBiIal.hlsl b/Assets/_Content/Shaders/EnkiBilal/Include/EnkiBiIal.hlsl index 7150d9f9..b11e03f1 100644 --- a/Assets/_Content/Shaders/EnkiBilal/Include/EnkiBiIal.hlsl +++ b/Assets/_Content/Shaders/EnkiBilal/Include/EnkiBiIal.hlsl @@ -1,31 +1,68 @@ #ifndef ENKI_BILAL_INCLUDED #define ENKI_BILAL_INCLUDED -#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" +/* + ENKI BILLAL - MEDIUM VERSION WITH SECOND DETAIL LAYER + + Goal: + Keep the optimized stylized render while allowing DetailTexB to be tested again. + + Changes from the original version: + - Removed custom shadow sampling. + In the original shader, shadowAtten was calculated but never used. + This was pure GPU overhead. + - Removed Lighting.hlsl include. + GetMainLight / GetAdditionalLight are no longer used here. + - Uses the optimized SampleProjectedDetailLOD from Details.hlsl. + - DetailTexA is active when DetailIntensityA > 0. + - DetailTexB is active when DetailIntensityB > 0. + - Both details are limited by camera distance. + - World/Object conversions are computed only once if at least one detail layer is used. + - Simple fog is preserved. + + Cost with the new Details.hlsl: + - DetailTexA only: 6 texture samples. + - DetailTexA + DetailTexB: 12 texture samples. + + This is still much cheaper than the original setup. +*/ + +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Assets/_Content/Shaders/Include/Noises.hlsl" #include "Assets/_Content/Shaders/Include/Details.hlsl" #include "Assets/_Content/Shaders/Include/Utilities.hlsl" -//#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusion.hlsl" +/* + Maximum distance for projected details. + + Lower value = better GPU performance. + Higher value = details visible farther from the camera. + + Recommended range: + - 12 to 18 for dense scenes. + - 25 to 30 if details disappear too aggressively in depth. +*/ +#define ENKI_DETAIL_MAX_DISTANCE 18.0 + +/* + Fade range used to avoid a hard cutoff. + + Detail starts fading at: + ENKI_DETAIL_MAX_DISTANCE - ENKI_DETAIL_FADE_DISTANCE. +*/ +#define ENKI_DETAIL_FADE_DISTANCE 4.0 + +/* + Safety stub. + + If another include or older graph version still calls GetShadow, + the shader will compile and return "no custom shadow". + + In this Medium version, custom shadow sampling is intentionally disabled. +*/ float GetShadow(float3 PositionWS) { - float4 shadowCoord = TransformWorldToShadowCoord(PositionWS); - Light mainLight = GetMainLight(shadowCoord); - - float shadow = 1 - mainLight.shadowAttenuation; - -#if defined(_ADDITIONAL_LIGHTS) - uint lightsCount = GetAdditionalLightsCount(); - - [loop] - for (uint i = 0; i < lightsCount; i++) - { - Light light = GetAdditionalLight(i, PositionWS); - shadow = max(shadow, 1 - light.shadowAttenuation); - } -#endif - - return saturate(shadow); + return 0.0; } void EnkiBillal_float @@ -49,64 +86,99 @@ void EnkiBillal_float out float Alpha ) { - // Common - float depth = length(PositionWS - _WorldSpaceCameraPos.xyz); - - float3 pivotWS = TransformObjectToWorld(float3(0, 0, 0)); - - float3 scale = GetScale(pivotWS); - - float3 positionOS = TransformWorldToObject(PositionWS) * scale; - float3 normalOS = normalize(TransformWorldToObjectDir(NormalWS)); - - //float ao = GetScreenSpaceAmbientOcclusion(ScreenUV).directAmbientOcclusion; - - // Shadow - - float shadow = GetShadow(PositionWS); - float shadowAtten = Remap(1, 0, .6, 1, shadow); - - // Detail - - float4 detailA = SampleProjectedDetailLOD - ( - DetailTexA, - positionOS, - normalOS, - ProjectionsBlend, - DetailSizeA, - depth - - ); - - float4 detailB = SampleProjectedDetailLOD - ( - DetailTexB, - positionOS, - normalOS, - ProjectionsBlend, - DetailSizeB, - depth - - ); - - float detailMaskA = smoothstep(0, .8, detailA.a); - float detailMaskB = smoothstep(0, .8, detailB.a); - - // Fog - - // Output - + /* + Base output. + If no extra effect is applied, this function remains very cheap. + */ Output = Color.rgb; - Output = lerp(Output.rgb, detailA.rgb, detailMaskA * DetailIntensityA); - Output = lerp(Output.rgb, detailB.rgb, detailMaskB * DetailIntensityB); - + Alpha = Color.a; + + /* + Camera-to-fragment distance. + Used for projected detail distance limiting and optional fog. + */ + float depth = length(PositionWS - _WorldSpaceCameraPos.xyz); + + /* + Distance fade for projected details. + + detailFade is: + - 1 near the camera. + - 0 beyond ENKI_DETAIL_MAX_DISTANCE. + */ + float detailFadeStart = ENKI_DETAIL_MAX_DISTANCE - ENKI_DETAIL_FADE_DISTANCE; + float detailFade = 1.0 - smoothstep(detailFadeStart, ENKI_DETAIL_MAX_DISTANCE, depth); + + float detailWeightA = DetailIntensityA * detailFade; + float detailWeightB = DetailIntensityB * detailFade; + + /* + Only compute object-space data if at least one detail layer is actually used. + */ + if (detailWeightA > 0.001 || detailWeightB > 0.001) + { + float3 pivotWS = TransformObjectToWorld(float3(0.0, 0.0, 0.0)); + float3 scale = GetScale(pivotWS); + + float3 positionOS = TransformWorldToObject(PositionWS) * scale; + float3 normalOS = normalize(TransformWorldToObjectDir(NormalWS)); + + /* + Detail layer A. + */ + if (detailWeightA > 0.001) + { + float4 detailA = SampleProjectedDetailLOD + ( + DetailTexA, + positionOS, + normalOS, + ProjectionsBlend, + DetailSizeA, + depth + ); + + float detailMaskA = smoothstep(0.0, 0.8, detailA.a); + + Output = lerp(Output, detailA.rgb, detailMaskA * detailWeightA); + } + + /* + Detail layer B. + + This is intentionally restored for testing. + If performance drops too much, set DetailIntensityB to 0 + or remove this block again. + */ + if (detailWeightB > 0.001) + { + float4 detailB = SampleProjectedDetailLOD + ( + DetailTexB, + positionOS, + normalOS, + ProjectionsBlend, + DetailSizeB, + depth + ); + + float detailMaskB = smoothstep(0.0, 0.8, detailB.a); + + Output = lerp(Output, detailB.rgb, detailMaskB * detailWeightB); + } + } + + /* + Simple fog is preserved. + + If fog becomes a measurable cost later, it can be moved to a cheaper global pass + or replaced with a simpler approximation. + */ if (FogUse) { - Output = lerp(Output.rgb, FogColor.rgb, smoothstep(FogMin, FogMax, depth) * FogColor.a); + float fogFactor = smoothstep(FogMin, FogMax, depth) * FogColor.a; + Output = lerp(Output, FogColor.rgb, fogFactor); } - - Alpha = Color.a; } #endif \ No newline at end of file diff --git a/Assets/_Content/Shaders/EnkiBilal/Include/Mask.hlsl b/Assets/_Content/Shaders/EnkiBilal/Include/Mask.hlsl index 3e1826ad..0bbd65f4 100644 --- a/Assets/_Content/Shaders/EnkiBilal/Include/Mask.hlsl +++ b/Assets/_Content/Shaders/EnkiBilal/Include/Mask.hlsl @@ -1,6 +1,27 @@ #ifndef MASK_INCLUDED #define MASK_INCLUDED +/* + MASK - MEDIUM COMPATIBLE VERSION + + Goal: + Keep the original portal / projection behavior while avoiding unnecessary work + in cases where the mask is not supposed to affect the object. + + Important compatibility point: + In the original shader, when all three masks are active, MaskID 0 is affected: + Alpha = (MaskID <= 1) ? 1 - mask : mask; + + The previous Medium version incorrectly skipped MaskID 0 entirely. + That could break portal logic. + + Changes from the original version: + - Preserves the original Alpha logic. + - Keeps rounded rectangle SDF to avoid changing portal shape. + - Adds safer early returns only when they do not change original behavior. + - Samples only active masks outside the "all three active" special case. +*/ + float ProjectionMask( float3 PositionWS, float3 CamPositionWS, @@ -8,51 +29,78 @@ float ProjectionMask( float3 RectNormalWS, float3 RectUpWS, float2 RectSize, - float Oval) + float Oval +) { - // Build the rectangle local frame + /* + Build the local projection frame. + */ float3 N = normalize(RectNormalWS); float3 U = normalize(RectUpWS); - float3 R = normalize(cross(N, U)); // Right axis - U = normalize(cross(R, N)); // Recompute Up orthogonally in case RectUpWS is not perfectly perpendicular to RectNormalWS + float3 R = normalize(cross(N, U)); - // Ray from camera toward the fragment - float3 rayDir = normalize(PositionWS - CamPositionWS); + /* + Recompute U to guarantee an orthogonal frame. + */ + U = normalize(cross(R, N)); - // Ray-plane intersection - // Plane equation: dot(P - RectPositionWS, N) = 0 + /* + Ray from camera to fragment. + */ + float3 camToFrag = PositionWS - CamPositionWS; + float distToFrag = length(camToFrag); + + if (distToFrag <= 1e-5) + return 0.0; + + float3 rayDir = camToFrag / distToFrag; + + /* + Ray-plane intersection. + */ float denom = dot(rayDir, N); - // Ray is parallel to the plane or facing away — no hit if (abs(denom) < 1e-6) - return 0; + return 0.0; float t = dot(RectPositionWS - CamPositionWS, N) / denom; - // Intersection must be in front of the camera (t > 0) - // and not beyond the fragment (t <= distance from camera to fragment) - float tFrag = dot(PositionWS - CamPositionWS, rayDir); - if (t < 0.0 || t > tFrag + 1e-4) - return 0; + /* + Reject intersections behind the camera or behind the current fragment. + */ + if (t < 0.0 || t > distToFrag + 1e-4) + return 0.0; - // Compute the hit point on the plane + /* + Compute hit point on the projection plane. + */ float3 hitPoint = CamPositionWS + rayDir * t; - // Project hit point into the rectangle local space + /* + Convert hit point to rectangle local coordinates. + */ float3 localVec = hitPoint - RectPositionWS; - float localU = dot(localVec, R); // horizontal axis - float localV = dot(localVec, U); // vertical axis + float localU = dot(localVec, R); + float localV = dot(localVec, U); float halfW = RectSize.x * 0.5; float halfH = RectSize.y * 0.5; - // Corner radius: 0 = rectangle, min(halfW, halfH) = oval + if (halfW <= 1e-5 || halfH <= 1e-5) + return 0.0; + + /* + Original rounded rectangle SDF preserved. + + The previous Medium version replaced this with a hard rectangle / ellipse. + That was cheaper, but it could change the portal shape. + */ float radius = saturate(Oval) * min(halfW, halfH); - // Rounded rectangle SDF float2 uv = float2(localU, localV); float2 ext = float2(halfW, halfH); float2 q = abs(uv) - ext + radius; + float sdf = length(max(q, 0.0)) - radius; return sdf <= 0.0 ? 1.0 : 0.0; @@ -60,17 +108,20 @@ float ProjectionMask( float SampleProjectionMask(float3 PositionWS, float4x4 M) { - if (M[0].w == 0) - return 0; + /* + M[0].w is used as the active flag. + */ + if (M[0].w <= 0.5) + return 0.0; return ProjectionMask( PositionWS, - M[0].xyz, // CamPositionWS - M[1].xyz, // RectPositionWS - M[3].xyz, // RectNormalWS - M[2].xyz, // RectUpWS - float2(M[2].w, M[3].w), // RectSize - M[1].w // Shape + M[0].xyz, // Camera world position + M[1].xyz, // Rectangle world position + M[3].xyz, // Rectangle normal in world space + M[2].xyz, // Rectangle up vector in world space + float2(M[2].w, M[3].w), // Rectangle size + M[1].w // Rounded shape amount ); } @@ -84,40 +135,82 @@ void Mask_float out float Alpha ) { - Alpha = 1; - - if (Mask0[0].w == 1 && Mask1[0].w == 1 && Mask2[0].w == 1) + float active0 = Mask0[0].w > 0.5 ? 1.0 : 0.0; + float active1 = Mask1[0].w > 0.5 ? 1.0 : 0.0; + float active2 = Mask2[0].w > 0.5 ? 1.0 : 0.0; + + float activeCount = active0 + active1 + active2; + + /* + No active mask case. + + Preserves original behavior: + - MaskID 1 is hidden. + - Other IDs remain visible. + */ + if (activeCount <= 0.0) { - float mask = SampleProjectionMask(PositionWS, Mask0); + Alpha = (MaskID == 1) ? 0.0 : 1.0; + return; + } + + /* + Original special case: + when all three masks are active, MaskID 0 is also affected by the mask. + + This is probably what your portal depends on. + */ + if (active0 > 0.5 && active1 > 0.5 && active2 > 0.5) + { + float mask = 0.0; + + mask += SampleProjectionMask(PositionWS, Mask0); mask += SampleProjectionMask(PositionWS, Mask1); mask += SampleProjectionMask(PositionWS, Mask2); + mask = saturate(mask); - - Alpha = (MaskID <= 1) ? 1 - mask : mask; + + Alpha = (MaskID <= 1.0) ? (1.0 - mask) : mask; + return; } - else if (MaskID == 0) + + /* + Safe optimization: + In the original shader, when not all three masks are active, + MaskID 0 is always fully visible. + + So only here it is safe to skip all projection work for MaskID 0. + */ + if (MaskID == 0) { - Alpha = 1; - } - else - { - float Active = Mask0[0].w + Mask1[0].w + Mask2[0].w; - - if (Active > 0) - { - float mask = saturate( - SampleProjectionMask(PositionWS, Mask0) + - SampleProjectionMask(PositionWS, Mask1) + - SampleProjectionMask(PositionWS, Mask2) - ); - - Alpha = (MaskID == 1) ? 1 - mask : mask; - } - else - { - Alpha = (MaskID == 1) ? 0 : 1; - } + Alpha = 1.0; + return; } + + /* + Partial active mask case. + + Only sample masks that are active. + */ + float maskPartial = 0.0; + + if (active0 > 0.5) + maskPartial += SampleProjectionMask(PositionWS, Mask0); + + if (active1 > 0.5) + maskPartial += SampleProjectionMask(PositionWS, Mask1); + + if (active2 > 0.5) + maskPartial += SampleProjectionMask(PositionWS, Mask2); + + maskPartial = saturate(maskPartial); + + /* + Original convention preserved: + - MaskID 1 is visible outside the mask. + - MaskID > 1 is visible inside the mask. + */ + Alpha = (MaskID == 1.0) ? (1.0 - maskPartial) : maskPartial; } -#endif +#endif \ No newline at end of file diff --git a/Assets/_Content/Shaders/EnkiBilal/Include/Original.meta b/Assets/_Content/Shaders/EnkiBilal/Include/Original.meta new file mode 100644 index 00000000..536184d2 --- /dev/null +++ b/Assets/_Content/Shaders/EnkiBilal/Include/Original.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4b83c226d7219d244b50aa3f10545374 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_Content/Shaders/EnkiBilal/Include/Original/EnkiBiIal.hlsl b/Assets/_Content/Shaders/EnkiBilal/Include/Original/EnkiBiIal.hlsl new file mode 100644 index 00000000..7150d9f9 --- /dev/null +++ b/Assets/_Content/Shaders/EnkiBilal/Include/Original/EnkiBiIal.hlsl @@ -0,0 +1,112 @@ +#ifndef ENKI_BILAL_INCLUDED +#define ENKI_BILAL_INCLUDED + +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" +#include "Assets/_Content/Shaders/Include/Noises.hlsl" +#include "Assets/_Content/Shaders/Include/Details.hlsl" +#include "Assets/_Content/Shaders/Include/Utilities.hlsl" +//#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/AmbientOcclusion.hlsl" + +float GetShadow(float3 PositionWS) +{ + float4 shadowCoord = TransformWorldToShadowCoord(PositionWS); + Light mainLight = GetMainLight(shadowCoord); + + float shadow = 1 - mainLight.shadowAttenuation; + +#if defined(_ADDITIONAL_LIGHTS) + uint lightsCount = GetAdditionalLightsCount(); + + [loop] + for (uint i = 0; i < lightsCount; i++) + { + Light light = GetAdditionalLight(i, PositionWS); + shadow = max(shadow, 1 - light.shadowAttenuation); + } +#endif + + return saturate(shadow); +} + +void EnkiBillal_float +( + float4 Color, + UnityTexture2D DetailTexA, + UnityTexture2D DetailTexB, + float2 ScreenUV, + float3 PositionWS, + float3 NormalWS, + float ProjectionsBlend, + float DetailIntensityA, + float DetailIntensityB, + float DetailSizeA, + float DetailSizeB, + uint FogUse, + float4 FogColor, + float FogMin, + float FogMax, + out float3 Output, + out float Alpha +) +{ + // Common + float depth = length(PositionWS - _WorldSpaceCameraPos.xyz); + + float3 pivotWS = TransformObjectToWorld(float3(0, 0, 0)); + + float3 scale = GetScale(pivotWS); + + float3 positionOS = TransformWorldToObject(PositionWS) * scale; + float3 normalOS = normalize(TransformWorldToObjectDir(NormalWS)); + + //float ao = GetScreenSpaceAmbientOcclusion(ScreenUV).directAmbientOcclusion; + + // Shadow + + float shadow = GetShadow(PositionWS); + float shadowAtten = Remap(1, 0, .6, 1, shadow); + + // Detail + + float4 detailA = SampleProjectedDetailLOD + ( + DetailTexA, + positionOS, + normalOS, + ProjectionsBlend, + DetailSizeA, + depth + + ); + + float4 detailB = SampleProjectedDetailLOD + ( + DetailTexB, + positionOS, + normalOS, + ProjectionsBlend, + DetailSizeB, + depth + + ); + + float detailMaskA = smoothstep(0, .8, detailA.a); + float detailMaskB = smoothstep(0, .8, detailB.a); + + // Fog + + // Output + + Output = Color.rgb; + Output = lerp(Output.rgb, detailA.rgb, detailMaskA * DetailIntensityA); + Output = lerp(Output.rgb, detailB.rgb, detailMaskB * DetailIntensityB); + + if (FogUse) + { + Output = lerp(Output.rgb, FogColor.rgb, smoothstep(FogMin, FogMax, depth) * FogColor.a); + } + + Alpha = Color.a; +} + +#endif \ No newline at end of file diff --git a/Assets/_Content/Shaders/EnkiBilal/Include/Original/EnkiBiIal.hlsl.meta b/Assets/_Content/Shaders/EnkiBilal/Include/Original/EnkiBiIal.hlsl.meta new file mode 100644 index 00000000..971548c2 --- /dev/null +++ b/Assets/_Content/Shaders/EnkiBilal/Include/Original/EnkiBiIal.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c4f3908c63ccbf2429b0628cdc9a2e23 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_Content/Shaders/EnkiBilal/Include/Original/Mask.hlsl b/Assets/_Content/Shaders/EnkiBilal/Include/Original/Mask.hlsl new file mode 100644 index 00000000..3e1826ad --- /dev/null +++ b/Assets/_Content/Shaders/EnkiBilal/Include/Original/Mask.hlsl @@ -0,0 +1,123 @@ +#ifndef MASK_INCLUDED +#define MASK_INCLUDED + +float ProjectionMask( + float3 PositionWS, + float3 CamPositionWS, + float3 RectPositionWS, + float3 RectNormalWS, + float3 RectUpWS, + float2 RectSize, + float Oval) +{ + // Build the rectangle local frame + float3 N = normalize(RectNormalWS); + float3 U = normalize(RectUpWS); + float3 R = normalize(cross(N, U)); // Right axis + U = normalize(cross(R, N)); // Recompute Up orthogonally in case RectUpWS is not perfectly perpendicular to RectNormalWS + + // Ray from camera toward the fragment + float3 rayDir = normalize(PositionWS - CamPositionWS); + + // Ray-plane intersection + // Plane equation: dot(P - RectPositionWS, N) = 0 + float denom = dot(rayDir, N); + + // Ray is parallel to the plane or facing away — no hit + if (abs(denom) < 1e-6) + return 0; + + float t = dot(RectPositionWS - CamPositionWS, N) / denom; + + // Intersection must be in front of the camera (t > 0) + // and not beyond the fragment (t <= distance from camera to fragment) + float tFrag = dot(PositionWS - CamPositionWS, rayDir); + if (t < 0.0 || t > tFrag + 1e-4) + return 0; + + // Compute the hit point on the plane + float3 hitPoint = CamPositionWS + rayDir * t; + + // Project hit point into the rectangle local space + float3 localVec = hitPoint - RectPositionWS; + float localU = dot(localVec, R); // horizontal axis + float localV = dot(localVec, U); // vertical axis + + float halfW = RectSize.x * 0.5; + float halfH = RectSize.y * 0.5; + + // Corner radius: 0 = rectangle, min(halfW, halfH) = oval + float radius = saturate(Oval) * min(halfW, halfH); + + // Rounded rectangle SDF + float2 uv = float2(localU, localV); + float2 ext = float2(halfW, halfH); + float2 q = abs(uv) - ext + radius; + float sdf = length(max(q, 0.0)) - radius; + + return sdf <= 0.0 ? 1.0 : 0.0; +} + +float SampleProjectionMask(float3 PositionWS, float4x4 M) +{ + if (M[0].w == 0) + return 0; + + return ProjectionMask( + PositionWS, + M[0].xyz, // CamPositionWS + M[1].xyz, // RectPositionWS + M[3].xyz, // RectNormalWS + M[2].xyz, // RectUpWS + float2(M[2].w, M[3].w), // RectSize + M[1].w // Shape + ); +} + +void Mask_float +( + float3 PositionWS, + float MaskID, + float4x4 Mask0, + float4x4 Mask1, + float4x4 Mask2, + out float Alpha +) +{ + Alpha = 1; + + if (Mask0[0].w == 1 && Mask1[0].w == 1 && Mask2[0].w == 1) + { + float mask = SampleProjectionMask(PositionWS, Mask0); + mask += SampleProjectionMask(PositionWS, Mask1); + mask += SampleProjectionMask(PositionWS, Mask2); + mask = saturate(mask); + + Alpha = (MaskID <= 1) ? 1 - mask : mask; + } + else if (MaskID == 0) + { + Alpha = 1; + } + else + { + float Active = Mask0[0].w + Mask1[0].w + Mask2[0].w; + + if (Active > 0) + { + float mask = saturate( + SampleProjectionMask(PositionWS, Mask0) + + SampleProjectionMask(PositionWS, Mask1) + + SampleProjectionMask(PositionWS, Mask2) + ); + + Alpha = (MaskID == 1) ? 1 - mask : mask; + } + else + { + Alpha = (MaskID == 1) ? 0 : 1; + } + } +} + +#endif diff --git a/Assets/_Content/Shaders/EnkiBilal/Include/Original/Mask.hlsl.meta b/Assets/_Content/Shaders/EnkiBilal/Include/Original/Mask.hlsl.meta new file mode 100644 index 00000000..5757f7ad --- /dev/null +++ b/Assets/_Content/Shaders/EnkiBilal/Include/Original/Mask.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 5e676c47e68d7e141bf1ab708fbdebca +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_Content/Shaders/EnkiBilal/Include/Original/Stripes.hlsl b/Assets/_Content/Shaders/EnkiBilal/Include/Original/Stripes.hlsl new file mode 100644 index 00000000..b99a2ef4 --- /dev/null +++ b/Assets/_Content/Shaders/EnkiBilal/Include/Original/Stripes.hlsl @@ -0,0 +1,71 @@ +#ifndef STRIPES_INCLUDED +#define STRIPES_INCLUDED + +// Returns a value in [0, 1) +float VanDerCorput(uint index) +{ + // Reverse bits of the integer and scale to [0,1] + return (float) reversebits(index) * 2.3283064365386963e-10; +} + +void Stripes_float( + float2 UV, + float Density, + float Count, + float Thickness, + float Offset, + float DistortionAmplitude, + float DistortionFrequency, + out float Stripes +) +{ + float density = saturate(Density); + float offset = frac(Offset); + float distortionAmplitude = DistortionAmplitude * .1; + uint stripeCount = max((uint) round(Count), 1u); + + float2 uv = UV; + uv.x += offset; + + float2 uvA = uv; + float2 uvB = uv; + uvA.x = frac(uvA.x + cos((uv.y + offset) * sin(uv.x) * DistortionFrequency + offset * 7.8) * distortionAmplitude); + uvB.x = frac(uvB.x + sin((uv.y + offset) * cos(uv.x) * DistortionFrequency + offset * 5.3) * distortionAmplitude); + + float stripDistanceY = abs(saturate(uv.y) - .5); + + float stripeMax = 0; + + for (uint i = 0u; i < stripeCount; i++) + { + float vdc = VanDerCorput(i); + bool usesSecondDistortion = vdc >= .5; + + float thickness = vdc < .3 ? 1 : (vdc < .6 ? 1.8 : 2.6); + thickness *= saturate(Thickness); + + float wrappedX = usesSecondDistortion ? uvB.x : uvA.x; + + float localProgress = saturate(density * stripeCount - vdc * stripeCount); + + float stripeCenterX = frac((i + .5) / stripeCount); + float stripDistanceX = abs(wrappedX - stripeCenterX); + stripDistanceX = min(stripDistanceX, 1.0 - stripDistanceX); + + float stepX = (1. / stripeCount) * localProgress * thickness * .5; + float stepY = localProgress * .5 - .01; + + float softEdgeX = .01; + float softEdgeY = .05; + + float widthMask = 1 - smoothstep(stepX - softEdgeX, stepX, stripDistanceX); + float heightMask = 1 - smoothstep(stepY - softEdgeY, stepY, stripDistanceY); + + float stripeMask = widthMask * heightMask; + stripeMax = max(stripeMax, stripeMask); + } + + Stripes = stripeMax; +} + +#endif \ No newline at end of file diff --git a/Assets/_Content/Shaders/EnkiBilal/Include/Original/Stripes.hlsl.meta b/Assets/_Content/Shaders/EnkiBilal/Include/Original/Stripes.hlsl.meta new file mode 100644 index 00000000..b958d097 --- /dev/null +++ b/Assets/_Content/Shaders/EnkiBilal/Include/Original/Stripes.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: fa3b413e6fe24314f874cc5f0bce969d +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_Content/Shaders/EnkiBilal/Include/Stripes.hlsl b/Assets/_Content/Shaders/EnkiBilal/Include/Stripes.hlsl index b99a2ef4..1cb78e2e 100644 --- a/Assets/_Content/Shaders/EnkiBilal/Include/Stripes.hlsl +++ b/Assets/_Content/Shaders/EnkiBilal/Include/Stripes.hlsl @@ -1,11 +1,89 @@ #ifndef STRIPES_INCLUDED #define STRIPES_INCLUDED -// Returns a value in [0, 1) +/* + STRIPES - MEDIUM VERSION + + Goal: + Reduce the GPU cost of the procedural stripe pattern. + + Changes from the original version: + - Removed the dynamic loop over the full stripe count. + Original behavior: evaluate every stripe from 0 to Count. + New behavior: evaluate only 6 nearby stripe candidates. + - Clamped Count to 32 to prevent expensive high-count cases. + - Kept Van der Corput distribution to preserve stable pseudo-random variation. + - Kept the two distortion paths to preserve part of the organic look. + - Visual result is an approximation of the original, but much cheaper. +*/ + float VanDerCorput(uint index) { - // Reverse bits of the integer and scale to [0,1] - return (float) reversebits(index) * 2.3283064365386963e-10; + return (float)reversebits(index) * 2.3283064365386963e-10; +} + +int WrapIndex(int x, int count) +{ + int r = x % count; + return r < 0 ? r + count : r; +} + +float EvalStripeCandidate( + uint index, + uint stripeCount, + float wrappedXA, + float wrappedXB, + float stripDistanceY, + float density, + float thicknessInput +) +{ + float vdc = VanDerCorput(index); + + /* + Same progressive reveal logic as the original shader. + + Original: + saturate(density * stripeCount - vdc * stripeCount) + + Equivalent simplified form: + saturate((density - vdc) * stripeCount) + */ + float localProgress = saturate((density - vdc) * stripeCount); + + if (localProgress <= 0.0001) + return 0.0; + + /* + Keep the original two distortion paths. + Each stripe chooses one path based on its pseudo-random value. + */ + float wrappedX = vdc >= 0.5 ? wrappedXB : wrappedXA; + + /* + Keep the original thickness variation. + This prevents the stripes from looking too uniform. + */ + float thickness = vdc < 0.3 ? 1.0 : (vdc < 0.6 ? 1.8 : 2.6); + thickness *= saturate(thicknessInput); + + float stripeCenterX = ((float)index + 0.5) / (float)stripeCount; + + float stripDistanceX = abs(wrappedX - stripeCenterX); + stripDistanceX = min(stripDistanceX, 1.0 - stripDistanceX); + + float stepX = (1.0 / (float)stripeCount) * localProgress * thickness * 0.5; + float stepY = localProgress * 0.5 - 0.01; + + /* + Soft edges are kept from the original shader. + If more performance is needed, these smoothstep calls can be replaced + with step calls, but the result will look harsher. + */ + float widthMask = 1.0 - smoothstep(stepX - 0.01, stepX, stripDistanceX); + float heightMask = 1.0 - smoothstep(stepY - 0.05, stepY, stripDistanceY); + + return widthMask * heightMask; } void Stripes_float( @@ -21,48 +99,78 @@ void Stripes_float( { float density = saturate(Density); float offset = frac(Offset); - float distortionAmplitude = DistortionAmplitude * .1; - uint stripeCount = max((uint) round(Count), 1u); + + /* + Intentional clamp. + Above 32 stripes, the cost increases while the visual gain is usually limited, + especially on distant objects or in a strongly stylized render. + */ + uint stripeCount = max((uint)round(Count), 1u); + stripeCount = min(stripeCount, 32u); + + float distortionAmplitude = DistortionAmplitude * 0.1; float2 uv = UV; - uv.x += offset; - - float2 uvA = uv; - float2 uvB = uv; - uvA.x = frac(uvA.x + cos((uv.y + offset) * sin(uv.x) * DistortionFrequency + offset * 7.8) * distortionAmplitude); - uvB.x = frac(uvB.x + sin((uv.y + offset) * cos(uv.x) * DistortionFrequency + offset * 5.3) * distortionAmplitude); - - float stripDistanceY = abs(saturate(uv.y) - .5); + uv.x = frac(uv.x + offset); - float stripeMax = 0; - - for (uint i = 0u; i < stripeCount; i++) + /* + The two distortion paths are computed once and reused for all nearby candidates. + */ + float wrappedXA = frac( + uv.x + cos((uv.y + offset) * sin(uv.x) * DistortionFrequency + offset * 7.8) + * distortionAmplitude + ); + + float wrappedXB = frac( + uv.x + sin((uv.y + offset) * cos(uv.x) * DistortionFrequency + offset * 5.3) + * distortionAmplitude + ); + + float stripDistanceY = abs(saturate(uv.y) - 0.5); + + int sc = (int)stripeCount; + + /* + Find the nearest stripe indices for both distortion paths. + Original shader tested every stripe. + Medium version tests only base - 1, base, base + 1 for A and B. + */ + int baseA = (int)floor(wrappedXA * sc); + int baseB = (int)floor(wrappedXB * sc); + + float stripeMax = 0.0; + + [unroll] + for (int k = -1; k <= 1; k++) { - float vdc = VanDerCorput(i); - bool usesSecondDistortion = vdc >= .5; + uint idxA = (uint)WrapIndex(baseA + k, sc); + uint idxB = (uint)WrapIndex(baseB + k, sc); - float thickness = vdc < .3 ? 1 : (vdc < .6 ? 1.8 : 2.6); - thickness *= saturate(Thickness); - - float wrappedX = usesSecondDistortion ? uvB.x : uvA.x; + stripeMax = max( + stripeMax, + EvalStripeCandidate( + idxA, + stripeCount, + wrappedXA, + wrappedXB, + stripDistanceY, + density, + Thickness + ) + ); - float localProgress = saturate(density * stripeCount - vdc * stripeCount); - - float stripeCenterX = frac((i + .5) / stripeCount); - float stripDistanceX = abs(wrappedX - stripeCenterX); - stripDistanceX = min(stripDistanceX, 1.0 - stripDistanceX); - - float stepX = (1. / stripeCount) * localProgress * thickness * .5; - float stepY = localProgress * .5 - .01; - - float softEdgeX = .01; - float softEdgeY = .05; - - float widthMask = 1 - smoothstep(stepX - softEdgeX, stepX, stripDistanceX); - float heightMask = 1 - smoothstep(stepY - softEdgeY, stepY, stripDistanceY); - - float stripeMask = widthMask * heightMask; - stripeMax = max(stripeMax, stripeMask); + stripeMax = max( + stripeMax, + EvalStripeCandidate( + idxB, + stripeCount, + wrappedXA, + wrappedXB, + stripDistanceY, + density, + Thickness + ) + ); } Stripes = stripeMax; diff --git a/Assets/_Content/Shaders/Include/Details.hlsl b/Assets/_Content/Shaders/Include/Details.hlsl index a48f466e..255f20a4 100644 --- a/Assets/_Content/Shaders/Include/Details.hlsl +++ b/Assets/_Content/Shaders/Include/Details.hlsl @@ -3,6 +3,46 @@ #include "Assets/_Content/Shaders/Include/Utilities.hlsl" +/* + DETAILS - MEDIUM LOD VERSION + + Goal: + Keep the large performance gain from the optimized triplanar version, + while restoring the old distance-based "detail upscale" behavior with smoother transitions. + + Main changes compared to the original version: + - Replaced the 7-direction projection system with standard 3-axis triplanar mapping. + - Removed the expensive 2x2 texture bombing by default. + - Restored manual distance-based detail scaling. + - Reduced the LOD ratio from 4.0 to 2.0 to make transitions less visible. + - Added stable spatial jitter to avoid the whole screen switching LOD at the same distance. + - Kept the public function signature SampleProjectedDetailLOD(...) + so existing Shader Graph nodes do not break. + + Original cost per detail layer: + 7 projections * 2 LOD levels * 4 bombing samples = 56 texture samples. + + This version: + 3 projections * 2 LOD levels = 6 texture samples. + + If EnkiBillal samples both DetailTexA and DetailTexB: + 6 * 2 = 12 texture samples. + Still much cheaper than the original 112 samples. +*/ + +#define DETAILS_USE_LIGHT_BOMBING 0 + +/* + Distance-based detail LOD. + + This restores the old idea: + - close camera -> smaller, sharper details; + - far camera -> larger, more readable details. + + Difference from the original: + lodRatio is reduced from 4.0 to 2.0. + This makes each transition less visible. +*/ void GetDetailLOD ( float Depth, @@ -13,81 +53,140 @@ void GetDetailLOD out float LODBlend ) { - const float lodRatio = 4; - const float lodSize = DetailSizeA / lodRatio * 2; + const float lodRatio = 2.0; + const float baseScale = 1.0; float dist = max(Depth, 1e-5); - float lod = log(dist) / log(lodRatio) + LODJitter; // log2(dist); + + float lod = log(dist) / log(lodRatio) + LODJitter; float lodFloor = floor(lod); float lodFrac = lod - lodFloor; - LODBlend = lodFrac * lodFrac * (3 - 2 * lodFrac); + /* + Quintic smootherstep. + This is smoother than classic smoothstep and helps hide the LOD blend. + */ + float t = saturate(lodFrac); + LODBlend = t * t * t * (t * (t * 6.0 - 15.0) + 10.0); - DetailSizeAA = lodSize * pow(lodRatio, lodFloor); - DetailSizeAB = lodSize * pow(lodRatio, lodFloor + 1); + DetailSizeAA = DetailSizeA * baseScale * pow(lodRatio, lodFloor); + DetailSizeAB = DetailSizeA * baseScale * pow(lodRatio, lodFloor + 1.0); } +/* + Default fast texture sample. + Uses normal GPU mipmapping. +*/ +float4 SampleDetailTextureFast +( + UnityTexture2D Tex, + float2 UV +) +{ + return Tex.tex.Sample(Tex.samplerstate, UV); +} + +/* + Optional lightweight texture bombing. + + Disabled by default. + + Compared to the original SampleBombedTexture: + - original: 4 texture samples + 4 rotations + 4 weights; + - this version: 1 texture sample with stable per-cell offset and rotation. + + Warning: + This can create visible cell transitions because neighboring cells are not blended. +*/ +float4 SampleDetailTextureLightBombed +( + UnityTexture2D Tex, + float2 UV +) +{ + float2 cell = floor(UV); + + float2 randomOffset = (Hash2D(cell) - 0.5) * 0.35; + float randomAngle = Hash1From2D(cell) * TWO_PI; + + float2 sampleUV = UV + randomOffset; + + sampleUV = RotateUV + ( + sampleUV, + cell + 0.5, + randomAngle + ); + + return Tex.tex.Sample(Tex.samplerstate, sampleUV); +} + +/* + Compatibility function. + + Existing code can still call SampleBombedTexture. + In Medium mode, it routes to: + - direct sampling by default; + - optional one-sample light bombing if enabled. +*/ float4 SampleBombedTexture ( UnityTexture2D Tex, float2 UV ) { - const float cellBlend = 4; - - float2 cell = floor(UV); - float2 local = frac(UV); - - float4 result = 0; - float weightSum = 0; - - [unroll] - for (int y = 0; y < 2; y++) - { - [unroll] - for (int x = 0; x < 2; x++) - { - float2 currentCell = cell + float2(x, y); - - float2 randomOffset = (Hash2D(currentCell) - .5) * .35; - float randomAngle = Hash1From2D(currentCell) * TWO_PI; - - float2 center = float2(x, y) + randomOffset; - float2 delta = local - center; - - float weight = - pow(saturate(1 - abs(delta.x)), cellBlend) * - pow(saturate(1 - abs(delta.y)), cellBlend); - - float2 sampleUV = UV + randomOffset; - - sampleUV = RotateUV - ( - sampleUV, - currentCell + .5, - randomAngle - ); - - result += Tex.tex.Sample - ( - Tex.samplerstate, - sampleUV - ) * weight; - - weightSum += weight; - } - } - - return result / max(weightSum, 1e-5); +#if DETAILS_USE_LIGHT_BOMBING + return SampleDetailTextureLightBombed(Tex, UV); +#else + return SampleDetailTextureFast(Tex, UV); +#endif } +/* + Triplanar weights. + + ProjectionBlend keeps the same artistic role: + - low value -> softer blend between axes; + - high value -> sharper projection selection. + + The original shader used up to 32. + This version uses 16 by default to reduce overly sharp transitions. +*/ +float3 GetTriplanarWeights +( + float3 NormalOS, + float ProjectionBlend +) +{ + float3 n = abs(normalize(NormalOS)); + + float sharpness = lerp(2.0, 16.0, saturate(ProjectionBlend)); + + float3 w = pow(saturate(n), sharpness); + float sumW = max(w.x + w.y + w.z, 1e-5); + + return w / sumW; +} + +/* + Compatibility structure. + + Kept because old code or Shader Graph nodes may still expect this type. + The optimized SampleProjectedDetailLOD below does not use the old 7-projection path. +*/ struct ProjectionData { float2 uv[7]; float mask[7]; }; +/* + Compatibility fallback. + + Fills only the first three entries using standard triplanar projections. + Entries 3..6 are disabled. +*/ ProjectionData GetProjections ( float3 PositionOS, @@ -97,57 +196,72 @@ ProjectionData GetProjections { ProjectionData data; - float3 normal = normalize(NormalOS); + float3 w = GetTriplanarWeights(NormalOS, ProjectionBlend); - float3 projectionNormals[7] = - { - normalize(float3(1, 1, 1)), - normalize(float3(-1, 1, 1)), - normalize(float3(1, -1, 1)), - normalize(float3(-1, -1, 1)), - float3(1, 0, 0), - float3(0, 1, 0), - float3(0, 0, 1) - }; + /* + Standard triplanar UVs: + - X projection samples the YZ plane. + - Y projection samples the XZ plane. + - Z projection samples the XY plane. + */ + data.uv[0] = PositionOS.zy; + data.uv[1] = PositionOS.xz; + data.uv[2] = PositionOS.xy; - float sharpness = lerp(2, 32, saturate(ProjectionBlend)); - - float maskSum = 0; + data.mask[0] = w.x; + data.mask[1] = w.y; + data.mask[2] = w.z; [unroll] - for (int i = 0; i < 7; i++) + for (int i = 3; i < 7; i++) { - float3 n = projectionNormals[i]; - - float d = abs(dot(normal, n)); - - data.mask[i] = pow(saturate(d), sharpness); - maskSum += data.mask[i]; - - float3 up = abs(n.y) < .999 - ? float3(0, 1, 0) - : float3(1, 0, 0); - - float3 tangent = normalize(cross(up, n)); - float3 bitangent = normalize(cross(n, tangent)); - - data.uv[i] = float2 - ( - dot(PositionOS, tangent), - dot(PositionOS, bitangent) - ); + data.uv[i] = 0.0; + data.mask[i] = 0.0; } - maskSum = max(maskSum, 1e-5); - - [unroll] - for (int i = 0; i < 7; i++) - data.mask[i] /= maskSum; - return data; } +/* + Samples one triplanar axis with two distance-based detail sizes. + This restores the "detail upscale with distance" effect without returning + to the original 7-projection and 2x2 bombing cost. +*/ +float4 SampleDetailAxisLOD +( + UnityTexture2D DetailTex, + float2 BaseUV, + float DetailSizeAA, + float DetailSizeAB, + float LODBlend +) +{ + float4 detailA = SampleBombedTexture + ( + DetailTex, + BaseUV / max(DetailSizeAA, 1e-5) + ); + + float4 detailB = SampleBombedTexture + ( + DetailTex, + BaseUV / max(DetailSizeAB, 1e-5) + ); + + return lerp(detailA, detailB, LODBlend); +} + +/* + Optimized projected detail sampling with smoother distance LOD. + + Cost: + 3 triplanar axes * 2 LOD samples = 6 texture samples. + + The old version also added per-projection jitter. + This version uses one stable object-space jitter for the whole sample. + That keeps the transition less synchronized without reintroducing too much cost. +*/ float4 SampleProjectedDetailLOD ( UnityTexture2D DetailTex, @@ -158,57 +272,72 @@ float4 SampleProjectedDetailLOD float Depth ) { - const float lodJitterStrength = .8; - const float lodJitterSize = 1.5; + float detailSize = max(DetailSizeA, 1e-5); - float4 detail = 0; - float totalMask = 0; + float3 weights = GetTriplanarWeights(NormalOS, ProjectionBlend); - ProjectionData projections = GetProjections + /* + Stable spatial jitter. + + This prevents the whole screen from switching detail scale at exactly + the same camera distance. + + Keep this value low. + Too much jitter makes the transition patchy. + */ + float lodJitter = (Hash1From2D(floor(PositionOS.xz * 0.75)) - 0.5) * 0.35; + + float DetailSizeAA; + float DetailSizeAB; + float lodBlend; + + GetDetailLOD ( - PositionOS, - NormalOS, - ProjectionBlend + Depth, + detailSize, + lodJitter, + DetailSizeAA, + DetailSizeAB, + lodBlend ); - [unroll] - for (int i = 0; i < 7; i++) - { - float mask = projections.mask[i]; + /* + Triplanar base UVs in object space. + */ + float2 uvX = PositionOS.zy; + float2 uvY = PositionOS.xz; + float2 uvZ = PositionOS.xy; - float lodJitter = (Hash1From2D(floor(projections.uv[i] * lodJitterSize) + i * 17.13) - .5) * lodJitterStrength; + float4 sampleX = SampleDetailAxisLOD + ( + DetailTex, + uvX, + DetailSizeAA, + DetailSizeAB, + lodBlend + ); - float DetailSizeAA; - float DetailSizeAB; - float lodBlend; + float4 sampleY = SampleDetailAxisLOD + ( + DetailTex, + uvY, + DetailSizeAA, + DetailSizeAB, + lodBlend + ); - GetDetailLOD - ( - Depth, - DetailSizeA, - lodJitter, - DetailSizeAA, - DetailSizeAB, - lodBlend - ); + float4 sampleZ = SampleDetailAxisLOD + ( + DetailTex, + uvZ, + DetailSizeAA, + DetailSizeAB, + lodBlend + ); - float4 detailA = SampleBombedTexture - ( - DetailTex, - projections.uv[i] / DetailSizeAA - ); - - float4 detailB = SampleBombedTexture - ( - DetailTex, - projections.uv[i] / DetailSizeAB - ); - - detail += lerp(detailA, detailB, lodBlend) * mask; - totalMask += mask; - } - - return detail / max(totalMask, 1e-5); + return sampleX * weights.x + + sampleY * weights.y + + sampleZ * weights.z; } -#endif +#endif \ No newline at end of file diff --git a/Assets/_Content/Shaders/Include/Original.meta b/Assets/_Content/Shaders/Include/Original.meta new file mode 100644 index 00000000..4d4e60de --- /dev/null +++ b/Assets/_Content/Shaders/Include/Original.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e3d6911aa39004b4a88bf6731817967c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_Content/Shaders/Include/Original/Details.hlsl b/Assets/_Content/Shaders/Include/Original/Details.hlsl new file mode 100644 index 00000000..a48f466e --- /dev/null +++ b/Assets/_Content/Shaders/Include/Original/Details.hlsl @@ -0,0 +1,214 @@ +#ifndef DETAILS_HLSL +#define DETAILS_HLSL + +#include "Assets/_Content/Shaders/Include/Utilities.hlsl" + +void GetDetailLOD +( + float Depth, + float DetailSizeA, + float LODJitter, + out float DetailSizeAA, + out float DetailSizeAB, + out float LODBlend +) +{ + const float lodRatio = 4; + const float lodSize = DetailSizeA / lodRatio * 2; + + float dist = max(Depth, 1e-5); + float lod = log(dist) / log(lodRatio) + LODJitter; // log2(dist); + + float lodFloor = floor(lod); + float lodFrac = lod - lodFloor; + + LODBlend = lodFrac * lodFrac * (3 - 2 * lodFrac); + + DetailSizeAA = lodSize * pow(lodRatio, lodFloor); + DetailSizeAB = lodSize * pow(lodRatio, lodFloor + 1); +} + +float4 SampleBombedTexture +( + UnityTexture2D Tex, + float2 UV +) +{ + const float cellBlend = 4; + + float2 cell = floor(UV); + float2 local = frac(UV); + + float4 result = 0; + float weightSum = 0; + + [unroll] + for (int y = 0; y < 2; y++) + { + [unroll] + for (int x = 0; x < 2; x++) + { + float2 currentCell = cell + float2(x, y); + + float2 randomOffset = (Hash2D(currentCell) - .5) * .35; + float randomAngle = Hash1From2D(currentCell) * TWO_PI; + + float2 center = float2(x, y) + randomOffset; + float2 delta = local - center; + + float weight = + pow(saturate(1 - abs(delta.x)), cellBlend) * + pow(saturate(1 - abs(delta.y)), cellBlend); + + float2 sampleUV = UV + randomOffset; + + sampleUV = RotateUV + ( + sampleUV, + currentCell + .5, + randomAngle + ); + + result += Tex.tex.Sample + ( + Tex.samplerstate, + sampleUV + ) * weight; + + weightSum += weight; + } + } + + return result / max(weightSum, 1e-5); +} + +struct ProjectionData +{ + float2 uv[7]; + float mask[7]; +}; + +ProjectionData GetProjections +( + float3 PositionOS, + float3 NormalOS, + float ProjectionBlend +) +{ + ProjectionData data; + + float3 normal = normalize(NormalOS); + + float3 projectionNormals[7] = + { + normalize(float3(1, 1, 1)), + normalize(float3(-1, 1, 1)), + normalize(float3(1, -1, 1)), + normalize(float3(-1, -1, 1)), + float3(1, 0, 0), + float3(0, 1, 0), + float3(0, 0, 1) + }; + + float sharpness = lerp(2, 32, saturate(ProjectionBlend)); + + float maskSum = 0; + + [unroll] + for (int i = 0; i < 7; i++) + { + float3 n = projectionNormals[i]; + + float d = abs(dot(normal, n)); + + data.mask[i] = pow(saturate(d), sharpness); + maskSum += data.mask[i]; + + float3 up = abs(n.y) < .999 + ? float3(0, 1, 0) + : float3(1, 0, 0); + + float3 tangent = normalize(cross(up, n)); + float3 bitangent = normalize(cross(n, tangent)); + + data.uv[i] = float2 + ( + dot(PositionOS, tangent), + dot(PositionOS, bitangent) + ); + } + + maskSum = max(maskSum, 1e-5); + + [unroll] + for (int i = 0; i < 7; i++) + data.mask[i] /= maskSum; + + return data; +} + + +float4 SampleProjectedDetailLOD +( + UnityTexture2D DetailTex, + float3 PositionOS, + float3 NormalOS, + float ProjectionBlend, + float DetailSizeA, + float Depth +) +{ + const float lodJitterStrength = .8; + const float lodJitterSize = 1.5; + + float4 detail = 0; + float totalMask = 0; + + ProjectionData projections = GetProjections + ( + PositionOS, + NormalOS, + ProjectionBlend + ); + + [unroll] + for (int i = 0; i < 7; i++) + { + float mask = projections.mask[i]; + + float lodJitter = (Hash1From2D(floor(projections.uv[i] * lodJitterSize) + i * 17.13) - .5) * lodJitterStrength; + + float DetailSizeAA; + float DetailSizeAB; + float lodBlend; + + GetDetailLOD + ( + Depth, + DetailSizeA, + lodJitter, + DetailSizeAA, + DetailSizeAB, + lodBlend + ); + + float4 detailA = SampleBombedTexture + ( + DetailTex, + projections.uv[i] / DetailSizeAA + ); + + float4 detailB = SampleBombedTexture + ( + DetailTex, + projections.uv[i] / DetailSizeAB + ); + + detail += lerp(detailA, detailB, lodBlend) * mask; + totalMask += mask; + } + + return detail / max(totalMask, 1e-5); +} + +#endif diff --git a/Assets/_Content/Shaders/Include/Original/Details.hlsl.meta b/Assets/_Content/Shaders/Include/Original/Details.hlsl.meta new file mode 100644 index 00000000..25905ef0 --- /dev/null +++ b/Assets/_Content/Shaders/Include/Original/Details.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a4dfd3fe541362f4f8143c626427c71f +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/manifest.json b/Packages/manifest.json index afba9e24..49cecc88 100644 --- a/Packages/manifest.json +++ b/Packages/manifest.json @@ -16,7 +16,6 @@ "com.unity.visualeffectgraph": "17.3.0", "com.unity.visualscripting": "1.9.9", "com.unity.modules.accessibility": "1.0.0", - "com.unity.modules.adaptiveperformance": "1.0.0", "com.unity.modules.ai": "1.0.0", "com.unity.modules.androidjni": "1.0.0", "com.unity.modules.animation": "1.0.0", diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json index b67a8391..3383cb17 100644 --- a/Packages/packages-lock.json +++ b/Packages/packages-lock.json @@ -258,14 +258,6 @@ "source": "builtin", "dependencies": {} }, - "com.unity.modules.adaptiveperformance": { - "version": "1.0.0", - "depth": 0, - "source": "builtin", - "dependencies": { - "com.unity.modules.subsystems": "1.0.0" - } - }, "com.unity.modules.ai": { "version": "1.0.0", "depth": 0, diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset index baa5b417..01d54fdb 100644 --- a/ProjectSettings/ProjectSettings.asset +++ b/ProjectSettings/ProjectSettings.asset @@ -154,7 +154,7 @@ PlayerSettings: vrSettings: enable360StereoCapture: 0 isWsaHolographicRemotingEnabled: 0 - enableFrameTimingStats: 0 + enableFrameTimingStats: 1 enableOpenGLProfilerGPURecorders: 1 allowHDRDisplaySupport: 0 useHDRDisplay: 0 diff --git a/ProjectSettings/QualitySettings.asset b/ProjectSettings/QualitySettings.asset index 49144749..4a934136 100644 --- a/ProjectSettings/QualitySettings.asset +++ b/ProjectSettings/QualitySettings.asset @@ -62,8 +62,4 @@ QualitySettings: - Android - iPhone m_TextureMipmapLimitGroupNames: [] - m_PerPlatformDefaultQuality: - Android: 0 - Nintendo Switch 2: 0 - Standalone: 0 - iPhone: 0 + m_PerPlatformDefaultQuality: {}