From fa80a739c1da6acce83f3dda9b042fb9a730c326 Mon Sep 17 00:00:00 2001 From: Nico de Poel Date: Thu, 15 May 2025 11:11:02 +0200 Subject: [PATCH] Auto-sync from SVN revision 61880 --- .../CHANGELOG.md | 19 +- .../CommandBufferGenerator.cs | 4 +- .../Editor/Debugging/DebugState.cs | 8 +- .../Debugging/DebugUIDrawer.Builtins.cs | 14 +- .../Editor/Debugging/DebugWindow.cs | 15 +- .../Editor/Deprecated.cs | 65 +- .../ProbeGIBaking.Serialization.cs | 6 +- .../Lighting/ProbeVolume/ProbeGIBaking.cs | 6 +- .../ProbeVolume/ProbeVolumeBuildProcessor.cs | 123 +- .../ProbeVolume/ProbeVolumeLightingTab.cs | 11 +- .../Editor/PropertyDrawers.meta | 8 + .../Editor/PropertyDrawers/VrsLutDrawer.cs | 60 + .../PropertyDrawers/VrsLutDrawer.cs.meta | 2 + .../RenderGraphViewer.SidePanel.cs | 65 +- .../SampleDependencyImporter.cs | 38 +- .../Editor/Volume/VolumeParameterDrawer.cs | 2 +- .../Runtime/AssemblyInfo.cs | 4 + .../Runtime/Camera/CameraHistory.cs | 22 +- .../CommandBuffers/BaseCommandBufer.cs | 23 +- .../CommandBuffers/CommandBufferHelpers.cs | 5 + .../CommandBuffers/ComputeCommandBuffer.cs | 8 + .../CommandBuffers/IComputeCommandBuffer.cs | 8 + .../CommandBuffers/IRasterCommandBuffer.cs | 9 + .../CommandBuffers/RasterCommandBuffer.cs | 9 + .../CommandBuffers/UnsafeCommandBuffer.cs | 17 + .../Runtime/Common/ReloadAttribute.cs | 90 +- .../Runtime/Common/ReloadGroupAttribute.cs | 51 +- .../Runtime/Debugging/DebugManager.cs | 60 +- .../Runtime/Debugging/DebugUI.Fields.cs | 169 +- .../Runtime/Debugging/DebugUI.cs | 62 +- .../Prefabs/Resources/DebugUICanvas.prefab | 16 +- .../DebugUIHandlerRenderingLayerField.cs | 152 + .../DebugUIHandlerRenderingLayerField.cs.meta | 11 + .../DebugUIHandlerRenderingLayerField.prefab | 12455 ++++++++++++++++ ...ugUIHandlerRenderingLayerField.prefab.meta | 7 + .../Runtime/Deprecated.cs | 48 + .../Runtime/GPUDriven/GPUResidentDrawer.cs | 27 +- .../Runtime/GPUDriven/InstanceCuller.cs | 3 + .../Runtime/GPUDriven/LODGroupDataPool.cs | 3 + .../Lighting/ProbeVolume/DecodeSH.hlsl | 6 +- .../ProbeReferenceVolume.Streaming.cs | 2 +- .../ProbeVolume/ProbeReferenceVolume.cs | 43 +- .../ProbeVolumeBakingSet.Editor.cs | 4 +- .../ProbeVolume/ProbeVolumeBakingSet.cs | 68 +- .../ProbeVolume/ProbeVolumeGIContributor.cs | 10 +- .../ProbeVolume/ProbeVolumePerSceneData.cs | 7 +- .../ProbeVolume/ProbeVolumeStreamableAsset.cs | 21 +- .../PostProcessing/IPostProcessComponent.cs | 2 +- .../PostProcessing/LensFlareCommonSRP.cs | 490 +- .../PostProcessing/LensFlareDataSRP.cs | 1 + .../Compiler/CompilerContextData.cs | 73 +- .../Compiler/NativePassCompiler.Debug.cs | 22 + .../Compiler/NativePassCompiler.cs | 114 +- .../RenderGraph/Compiler/PassesData.cs | 167 +- .../RenderGraph/Compiler/ResourcesData.cs | 54 +- .../Debug/RenderGraphDebugParams.cs | 10 + .../RenderGraph/IRenderGraphBuilder.cs | 19 + .../RenderGraph/RenderGraph.Compiler.cs | 2 +- .../Runtime/RenderGraph/RenderGraph.cs | 54 +- .../RenderGraph/RenderGraphBuilders.cs | 21 + .../RenderGraphCompilationCache.cs | 2 +- .../RenderGraphDefaultResources.cs | 29 +- .../RenderGraph/RenderGraphGlobalSettings.cs | 27 +- .../RenderGraph/RenderGraphObjectPool.cs | 7 +- .../Runtime/RenderGraph/RenderGraphPass.cs | 139 +- .../RenderGraph/RenderGraphResourcePool.cs | 2 +- .../RenderGraphResourceRegistry.cs | 2 +- .../RenderGraph/RenderGraphResourceTexture.cs | 53 +- .../RenderGraph/RenderGraphResources.cs | 23 +- .../RenderGraph/RenderGraphUtilsBlit.cs | 299 +- .../Settings/IncludeRenderPipelineAsset.cs | 34 +- .../Settings/LightmapSamplingSettings.cs | 30 + .../Settings/LightmapSamplingSettings.cs.meta | 2 + .../Settings/ShaderStrippingSetting.cs | 29 +- .../Textures/BufferedRTHandleSystem.cs | 33 +- .../Runtime/Textures/RTHandleSystem.cs | 169 +- .../Runtime/Textures/RTHandles.cs | 126 +- .../Runtime/Utilities/Blitter.cs | 1176 +- .../Runtime/Utilities/CoreUtils.cs | 162 + .../Runtime/Utilities/CullContextData.cs | 59 + .../Runtime/Utilities/CullContextData.cs.meta | 2 + .../Runtime/Utilities/HashFNV1A32.cs | 50 +- .../Runtime/Utilities/ResourceReloader.cs | 9 +- .../Runtime/Volume/IVolume.cs | 28 +- .../Runtime/Volume/VolumeComponent.cs | 66 +- .../Runtime/Volume/VolumeManager.cs | 25 +- .../Runtime/Volume/VolumeParameter.cs | 21 +- .../Runtime/Volume/VolumeStack.cs | 29 +- .../Runtime/Vrs.meta | 8 + .../Runtime/Vrs/Shaders.meta | 8 + .../Runtime/Vrs/Shaders/VrsImage.hlsl | 21 + .../Runtime/Vrs/Shaders/VrsImage.hlsl.meta | 3 + .../Runtime/Vrs/Shaders/VrsMainTex.hlsl | 23 + .../Runtime/Vrs/Shaders/VrsMainTex.hlsl.meta | 3 + .../Runtime/Vrs/Shaders/VrsShadingRates.hlsl | 45 + .../Vrs/Shaders/VrsShadingRates.hlsl.meta | 3 + .../Runtime/Vrs/Shaders/VrsTexture.compute | 69 + .../Vrs/Shaders/VrsTexture.compute.meta | 7 + .../Runtime/Vrs/Shaders/VrsTileSize.hlsl | 14 + .../Runtime/Vrs/Shaders/VrsTileSize.hlsl.meta | 3 + .../Vrs/Shaders/VrsVisualization.shader | 46 + .../Vrs/Shaders/VrsVisualization.shader.meta | 9 + .../Runtime/Vrs/Vrs.cs | 392 + .../Runtime/Vrs/Vrs.cs.meta | 2 + .../Runtime/Vrs/VrsLut.cs | 124 + .../Runtime/Vrs/VrsLut.cs.meta | 2 + .../Vrs/VrsRenderPipelineRuntimeResources.cs | 72 + .../VrsRenderPipelineRuntimeResources.cs.meta | 2 + .../Runtime/Vrs/VrsResources.cs | 173 + .../Runtime/Vrs/VrsResources.cs.meta | 2 + .../Runtime/Vrs/VrsShaders.cs | 24 + .../Runtime/Vrs/VrsShaders.cs.meta | 2 + .../Runtime/XR/XRGraphicsAutomatedTests.cs | 2 +- .../Runtime/XR/XRPass.cs | 14 + .../Runtime/XR/XRSystem.cs | 60 +- .../ShaderLibrary/API/GLES3.hlsl | 9 + .../ShaderLibrary/EntityLighting.hlsl | 34 + .../ShaderLibrary/Packing.hlsl | 6 +- .../Sampling/SampleUVMappingInternal.hlsl | 2 +- .../ShaderLibrary/Texture.hlsl | 12 + .../ShaderLibrary/TextureStack.hlsl | 2 +- .../ShaderLibrary/TextureXR.hlsl | 102 +- .../Shaders/CoreCopy.shader | 70 +- .../Tests/Editor/AssemblyInfo.cs | 3 + .../Tests/Editor/AssemblyInfo.cs.meta | 2 + .../GPUDriven/GPUDrivenRenderingUtils.cs | 4 +- .../NativePassCompilerRenderGraphTests.cs | 271 + .../Editor/RenderGraph.ComputeGraphHash.cs | 447 + .../RenderGraph.ComputeGraphHash.cs.meta | 3 + .../Tests/Editor/RenderGraphTests.cs | 452 +- .../Tests/Editor/RenderGraphViewerTests.cs | 47 + .../RenderPipeline/DummyRenderPipeline.cs | 5 +- .../DummyPipelineShader.shader | 2 +- .../ShaderStripping/ShaderExtensionsTests.cs | 2 +- .../ShaderStripping/ShaderStrippingTests.cs | 2 +- ...y.RenderPipelines.Core.Editor.Tests.asmdef | 3 +- .../Editor/Volumes/RenderPipelineTests.cs | 2 +- .../Tests/Runtime/AssemblyInfos.cs | 2 + .../Runtime/CustomRenderPipelineAsset.cs | 3 +- .../SecondCustomRenderPipelineAsset.cs | 3 +- .../Tests/Runtime/Threading/FunctionTests.cs | 1 + .../package.json | 8 +- .../CHANGELOG.md | 2 +- .../package.json | 10 +- .../CHANGELOG.md | 37 +- .../BuildProcessors/HDRPPreprocessBuild.cs | 9 +- .../BuildProcessors/HDRPPreprocessShaders.cs | 10 + .../LocalVolumetricFogEditor.cs | 13 +- .../LocalVolumetricFogUI.Drawer.cs | 2 + .../LocalVolumetricFogUI.Skin.cs | 1 + .../SerializedLocalVolumetricFog.cs | 2 + .../Editor/Material/BaseShaderPreprocessor.cs | 2 + .../DiffusionProfileSettingsEditor.cs | 2 + .../SerializedDiffusionProfileSettings.cs | 2 + .../Lit/ShaderGraph/HDLitSubTarget.cs | 2 +- .../Lit/ShaderGraph/ShaderPass.template.hlsl | 1 + .../Material/ShaderGraph/HDSubTarget.cs | 8 +- .../Editor/Material/ShaderGraph/HDTarget.cs | 9 + .../Material/ShaderGraph/LightingSubTarget.cs | 1 + .../ShaderGraph/Templates/ShaderPass.template | 2 +- .../Material/TerrainLit/TerrainLitGUI.cs | 2 +- .../Material/UIBlocks/SurfaceOptionUIBlock.cs | 11 +- .../Node/EvaluateScatteringColor_Water.cs | 10 +- .../EvaluateSimulationAdditionalData_Water.cs | 4 +- .../ShaderGraph/Node/UnpackData_Water.cs | 21 +- .../Water/ShaderGraph/Vertex.template.hlsl | 9 +- .../ShaderGraph/WaterDecalShaderPass.template | 16 +- .../Water/ShaderGraph/WaterDecalSubTarget.cs | 31 +- .../Water/ShaderGraph/WaterSubTarget.cs | 4 +- .../DrawRenderersCustomPassDrawer.cs | 12 + .../CustomPass/VrsCustomPassDrawer.cs | 49 + .../CustomPass/VrsCustomPassDrawer.cs.meta | 3 + .../RenderPipeline/HDRenderPipelineUI.Skin.cs | 7 +- .../RenderPipeline/HDRenderPipelineUI.cs | 10 + .../SerializedRenderPipelineSettings.cs | 10 +- .../VFXGraph/Outputs/VFXLitSphereOutput.cs | 2 +- .../Templates/Mesh/PassDepthOrMV.template | 2 +- .../Templates/Mesh/PassForward.template | 3 +- .../DXR/Lit/IntersectionFunctions.template | 2 +- .../DXR/Unlit/EvaluateMaterialData.template | 1 + .../DXR/Unlit/IntersectionFunctions.template | 2 +- .../PlanarPrimitive/PassDepthOrMV.template | 2 +- .../PlanarPrimitive/PassForward.template | 3 +- .../VFXPassDepthCommonFragmentLit.template | 117 + ...FXPassDepthCommonFragmentLit.template.meta | 3 + .../VFXGraph/Shaders/VFXLitVaryings.template | 1 + .../VFXGraph/Shaders/VFXPasses.template | 135 +- .../Shaders/VFXSixWayIncludes.template | 6 + .../Shaders/VFXSixWayIncludes.template.meta | 3 + .../Shaders/VFXVertexProbeSampling.template | 10 - .../WaterDecalSurfaceOptionsUIBlock.cs | 11 +- .../WaterSurface/VFX/SampleWaterSurface.cs | 8 +- .../Editor/Wizard/HDWizard.UserSettings.cs | 9 +- .../Runtime/Compositor/CompositionLayer.cs | 18 +- .../Runtime/Debug/DebugDisplay.cs | 44 +- .../Runtime/Debug/HDVolumeDebugSettings.cs | 48 +- .../Runtime/Deprecated.cs | 23 +- .../Light/HDAdditionalLightData.Types.cs | 29 +- .../Runtime/Lighting/LightLoop/HDShadow.hlsl | 20 +- .../Runtime/Lighting/LightLoop/LightLoop.hlsl | 5 +- .../Reflection/ReflectionProbeTextureCache.cs | 4 +- .../Lighting/Shadow/HDShadowManager.cs | 5 +- ...Pipeline.VolumetricCloudsFullResolution.cs | 12 - .../VolumetricClouds/VolumetricClouds.compute | 5 +- .../HDRenderPipeline.VolumetricLighting.cs | 10 +- .../VolumetricLighting/LocalVolumetricFog.cs | 37 +- .../LocalVolumetricFogManager.cs | 6 +- .../Runtime/Material/AxF/AxF.shader | 4 + .../Runtime/Material/BuiltinGIUtilities.hlsl | 4 + .../Runtime/Material/Decal/DecalData.hlsl | 2 +- .../Material/Decal/DecalUtilities.hlsl | 2 +- .../DiffusionProfileSettings.cs | 18 + .../Material/LayeredLit/LayeredLit.shader | 7 + .../Material/LayeredLit/LayeredLitData.hlsl | 3 +- .../LayeredLit/LayeredLitTessellation.shader | 7 + .../Runtime/Material/Lit/Lit.hlsl | 10 +- .../Runtime/Material/Lit/Lit.shader | 7 + .../Runtime/Material/Lit/LitBuiltinData.hlsl | 4 +- .../Material/Lit/LitDataIndividualLayer.hlsl | 5 +- .../Material/Lit/LitTessellation.shader | 7 + .../Material/Lit/ShaderPass/LitDepthPass.hlsl | 2 +- .../CombineLighting.shader | 8 +- .../SubsurfaceScattering.compute | 101 +- .../SubsurfaceScattering.hlsl | 14 +- .../Material/TerrainLit/TerrainLit.shader | 5 + .../TerrainLit/TerrainLit_Basemap.shader | 5 + .../TerrainLit/TerrainLit_Splatmap.hlsl | 2 +- .../Runtime/RenderPipeline/Camera/HDCamera.cs | 10 +- .../Camera/HDCameraFrameHistoryType.cs | 2 + .../Runtime/RenderPipeline/HDProfileId.cs | 2 +- .../HDRenderPipeline.PostProcess.cs | 7 +- .../HDRenderPipeline.Prepass.cs | 7 +- .../HDRenderPipeline.RenderGraph.cs | 8 +- .../HDRenderPipeline.SubsurfaceScattering.cs | 43 +- .../RenderPipeline/HDRenderPipeline.Vrs.cs | 73 + .../HDRenderPipeline.Vrs.cs.meta | 3 + .../RenderPipeline/HDRenderPipeline.cs | 40 +- .../HDRenderPipelineAsset.Prefiltering.cs | 6 + .../RenderPipeline/HDStringConstants.cs | 1 + .../RenderPipeline/PathTracing/PathTracing.cs | 18 +- .../RenderPass/CustomPass/CustomPass.cs | 35 +- .../CustomPass/CustomPassContext.cs | 7 + .../RenderPass/DrawRenderersCustomPass.cs | 10 + .../FSR/Runtime/FSR3/Fsr3Upscaler.cs | 11 +- .../FSR/Runtime/FSR3/Fsr3UpscalerContext.cs | 8 + .../ffx_fsr3upscaler_accumulate.h | 10 +- .../ffx_fsr3upscaler_callbacks_hlsl.h | 29 +- .../ffx_fsr3upscaler_prepare_reactivity.h | 19 +- .../RenderPass/VrsCustomPass.cs | 110 + .../RenderPass/VrsCustomPass.cs.meta | 3 + .../RenderPipeline/Settings/FrameSettings.cs | 7 + .../Settings/FrameSettingsDefaults.cs | 1 + .../Settings/RenderPipelineSettings.cs | 9 + .../RenderPipeline/ShaderPass/VertMesh.hlsl | 10 + .../HDRPDefaultVolumeProfileSetting.cs | 30 +- .../Settings/LookDevVolumeProfileSettings.cs | 32 +- .../ShaderLibrary/ShaderVariablesGlobal.cs | 2 + .../ShaderVariablesGlobal.cs.hlsl | 1 + .../PhysicallyBasedSkyRenderer.cs | 24 +- .../Runtime/Sky/SkyManager.cs | 6 + .../Runtime/Utilities/CameraSettings.cs | 59 +- .../Utilities/VolumeComponentWithQuality.cs | 50 +- .../Runtime/VFXGraph/Shaders/VFXDefines.hlsl | 1 - .../Runtime/VFXGraph/Shaders/VFXLit.hlsl | 2 +- .../HDRenderPipeline.WaterSystem.Decals.cs | 62 +- ...HDRenderPipeline.WaterSystem.Underwater.cs | 5 +- .../Water/HDRenderPipeline.WaterSystem.cs | 8 +- .../Water/Shaders/SampleWaterSurface.hlsl | 35 +- .../Water/Shaders/ShaderPassWaterMask.hlsl | 2 +- .../Runtime/Water/Shaders/WaterDecal.shader | 8 +- .../Water/Shaders/WaterDeformation.compute | 48 +- .../Water/Shaders/WaterSimulation.compute | 5 - .../Runtime/Water/Shaders/WaterUtilities.hlsl | 27 +- .../Runtime/Water/WaterDecal/WaterDecal.cs | 9 +- .../WaterSurface/WaterSurface.Deformation.cs | 10 +- .../Water/WaterSurface/WaterSurface.cs | 1 + .../Runtime/Water/WaterSystemDef.cs | 3 +- .../Runtime/Water/WaterSystemDef.cs.hlsl | 3 +- .../Editor/HDAnalyticsTests_Defaults.txt | 3 + .../package.json | 18 +- Packages/com.unity.shadergraph/CHANGELOG.md | 32 +- .../AssetCallbacks/CreateShaderSubGraph.cs | 2 +- .../Editor/Data/Graphs/ColorShaderProperty.cs | 1 + .../Editor/Data/Graphs/GraphConcretization.cs | 12 +- .../Editor/Data/Graphs/GraphData.cs | 25 +- .../Data/Graphs/Texture2DShaderProperty.cs | 30 +- .../Editor/Data/Implementation/NodeUtils.cs | 8 +- .../Data/Nodes/Input/Lighting/BakedGINode.cs | 2 +- .../Editor/Data/Nodes/Input/Scene/FogNode.cs | 4 +- .../Nodes/Input/Texture/TextureStackNode.cs | 2 - .../Editor/Data/SubGraph/SubGraphAsset.cs | 2 + .../Editor/Data/Util/GraphUtil.cs | 4 +- .../Blackboard/SGBlackboardCategory.cs | 39 +- .../BlackboardCategoryController.cs | 25 +- .../Controllers/BlackboardController.cs | 26 +- .../Editor/Drawing/EdgeConnectorListener.cs | 18 +- .../Editor/Drawing/Inspector/InspectorView.cs | 11 - .../Drawing/Inspector/MasterPreviewView.cs | 65 +- .../AbstractMaterialNodePropertyDrawer.cs | 2 +- .../GraphDataPropertyDrawer.cs | 10 +- .../SampleVirtualTextureNodePropertyDrawer.cs | 9 +- .../ShaderInputPropertyDrawer.cs | 62 +- .../Editor/Drawing/Interfaces/IResizable.cs | 3 + .../Drawing/Manipulators/ElementResizer.cs | 178 +- .../Manipulators/MasterPreviewManipulator.cs | 41 + .../MasterPreviewManipulator.cs.meta | 2 + .../ShaderGraphPropertyDrawers.cs | 2 +- .../Editor/Drawing/MaterialGraphEditWindow.cs | 25 +- .../Editor/Drawing/PreviewManager.cs | 25 +- .../Editor/Drawing/Views/GraphEditorView.cs | 31 +- .../Editor/Drawing/Views/GraphSubWindow.cs | 3 + .../Editor/Drawing/Views/HelpBoxRow.cs | 143 +- .../Editor/Drawing/Views/MaterialGraphView.cs | 7 +- .../Editor/Drawing/Views/MaterialNodeView.cs | 34 +- .../Editor/Drawing/Views/ResizableElement.cs | 3 +- .../Contexts/TargetPropertyGUIContext.cs | 3 +- .../Descriptors/PragmaDescriptor.cs | 3 + .../Generation/Processors/GenerationUtils.cs | 82 +- .../Editor/Generation/Processors/Generator.cs | 9 +- .../Processors/PropertyCollector.cs | 17 +- .../Generation/Processors/ShaderSpliceUtil.cs | 76 +- .../Processors/ShaderStringBuilder.cs | 9 + .../Editor/Generation/ShaderGraphVfxAsset.cs | 5 + .../Generation/TargetResources/Fields.cs | 1 + .../BuiltIn/Editor/ShaderPreprocessor.cs | 8 + .../Targets/BuiltIn/ShaderLibrary/Input.hlsl | 4 +- .../BuiltIn/ShaderLibrary/Shadows.hlsl | 12 +- .../CustomTextureGraph.hlsl | 6 +- .../Editor/Importers/ShaderGraphImporter.cs | 9 +- .../Importers/ShaderSubGraphImporter.cs | 7 +- .../Resources/Icons/sg_graph_icon@2x.png | Bin 0 -> 1426 bytes .../Resources/Icons/sg_graph_icon@2x.png.meta | 117 + .../Resources/Icons/sg_subgraph_icon@2x.png | Bin 0 -> 1635 bytes .../Icons/sg_subgraph_icon@2x.png.meta | 117 + .../Editor/Resources/Styles/InspectorView.uss | 5 + .../Resources/Styles/MasterPreviewView.uss | 18 +- .../UXML/Blackboard/SGBlackboard.uxml | 4 +- .../Editor/Resources/UXML/GraphInspector.uxml | 2 +- .../Editor/Serialization/MultiJsonInternal.cs | 3 +- .../Editor/ShaderGraphProjectSettings.cs | 8 +- .../Editor/Util/CopyPasteGraph.cs | 16 + .../Editor/Util/UIUtilities.cs | 12 + Packages/com.unity.shadergraph/README.md | 2 +- ...eedTree8InterpolatedNormals.shadersubgraph | 1124 +- Packages/com.unity.shadergraph/package.json | 8 +- .../Editor/TMP/TMP_InputFieldEditor.cs | 4 +- .../TMP/TMPro_FontAssetCreatorWindow.cs | 2 +- .../TMP/Unity.TextMeshPro.Editor.asmdef | 2 +- .../TMP Examples & Extras.unitypackage | 4 +- .../Runtime/TMP/TMP_FontAssetUtilities.cs | 19 +- .../Runtime/TMP/TMP_InputField.cs | 8 +- .../Runtime/TMP/TMP_InputValidator.cs | 7 + .../com.unity.ugui/Runtime/TMP/TMP_Text.cs | 20 +- .../Runtime/TMP/TMP_TextUtilities.cs | 1 + .../com.unity.ugui/Runtime/TMP/TextMeshPro.cs | 5 +- .../Runtime/TMP/TextMeshProUGUI.cs | 4 +- .../EventSystem/EventData/PointerEventData.cs | 2 +- .../InputModules/BaseInputModule.cs | 54 + .../UIElements/PanelEventHandler.cs | 21 +- .../EventSystem/UIElements/PanelRaycaster.cs | 9 +- .../Runtime/UGUI/UI/Core/GraphicRaycaster.cs | 6 + .../Runtime/UGUI/UI/Core/Image.cs | 97 +- .../Runtime/UGUI/UI/Core/InputField.cs | 4 +- .../UGUI/UI/Core/MultipleDisplayUtilities.cs | 59 +- .../Tests/Runtime/UGUI/CanvasRenderer.meta | 8 + .../CanvasRenderer/CanvasRendererTests.cs | 119 + .../CanvasRendererTests.cs.meta | 2 + .../Tests/Runtime/UGUI/Image/ImageTests.cs | 148 +- .../Tests/Runtime/UGUI/Image/TestableImage.cs | 7 + .../UGUI/InputField/GenericInputFieldTests.cs | 2 +- Packages/com.unity.ugui/package.json | 2 +- .../com.unity.visualeffectgraph/CHANGELOG.md | 47 +- .../Editor/Compiler/VFXCodeGenerator.cs | 359 +- .../Editor/Compiler/VFXExpressionGraph.cs | 8 +- .../Editor/Compiler/VFXGraphCompiledData.cs | 16 +- .../Editor/Compiler/VFXShaderSnippets.cs | 373 + .../Editor/Compiler/VFXShaderSnippets.cs.meta | 3 + .../Editor/Compiler/VFXShaderWriter.cs | 54 +- .../Editor/Controls/VFXSliderField.cs | 7 +- .../Editor/Core/VFXLibrary.cs | 6 +- .../Editor/Data/VFXDataParticle.cs | 120 +- .../Expressions/VFXExpressionContext.cs | 23 +- .../Editor/Expressions/VFXExpressionHLSL.cs | 46 +- .../Expressions/VFXExpressionTextureValues.cs | 45 +- .../Editor/FilterPopup/VFXFilterWindow.cs | 3 +- .../GraphView/Blackboard/VFXBlackboard.cs | 5 + .../Blackboard/VFXBlackboardFieldBase.cs | 5 + .../Controllers/VFXParameterController.cs | 12 +- .../Editor/GraphView/Elements/VFXBlockUI.cs | 7 +- .../Views/Controller/VFXViewController.cs | 15 +- .../GraphView/Views/Properties/PropertyRM.cs | 13 +- .../GraphView/Views/VFXHelpDropdownButton.cs | 7 +- .../Editor/GraphView/Views/VFXPaste.cs | 2 +- .../Editor/Inspector/VFXContextEditor.cs | 10 +- .../Editor/Inspector/VFXManagerEditor.cs | 2 + .../Implementations/GPUEvent/TriggerEvent.cs | 47 +- .../Blocks/Implementations/HLSL/CustomHLSL.cs | 31 +- .../Blocks/Implementations/HLSL/HLSLParser.cs | 109 +- .../Implementations/Position/PositionCone.cs | 8 +- .../Blocks/Implementations/VFXBlockUtility.cs | 40 - .../Editor/Models/Blocks/VFXBlock.cs | 6 + .../Implementations/VFXBasicGPUEvent.cs | 2 +- .../Implementations/VFXBasicInitialize.cs | 2 +- .../Implementations/VFXBasicUpdate.cs | 17 +- .../Implementations/VFXComposedShading.cs | 30 +- .../VFXAbstractComposedParticleOutput.cs | 6 + .../Contexts/VFXAbstractParticleOutput.cs | 3 +- .../Editor/Models/Contexts/VFXContext.cs | 24 + .../Operators/Implementations/CustomHLSL.cs | 49 +- .../Implementations/RandomSelector.cs | 2 +- .../Operators/Implementations/SampleBuffer.cs | 2 +- .../Parameters/VFXAttributeParameter.cs | 27 +- .../Slots/Implementations/VFXSlotTexture3D.cs | 2 +- .../Implementations/VFXSlotTextureCube.cs | 2 +- .../Editor/Models/VFXAttributesManager.cs | 104 +- .../Editor/Models/VFXErrorManager.cs | 5 +- .../SamplesLinkPackageManagerExtension.cs | 28 +- .../Templates/VFXConfig.template.hlsl | 7 +- .../VFXConfigPlanarPrimitive.template.hlsl | 83 +- .../VFXConfigRaytracing.template.hlsl | 91 + .../VFXConfigRaytracing.template.hlsl.meta | 3 + .../ShaderGraph/VFXOldShaderGraphHelpers.cs | 61 +- .../VFXShaderGraphParticleOutput.cs | 2 +- .../Editor/ShaderGraph/VFXSubTarget.cs | 20 +- .../TemplateWindow/VFXTemplateDescriptor.cs | 12 +- .../TemplateWindow/VFXTemplateWindow.cs | 22 +- .../Editor/Types/VFXBoxGizmos.cs | 6 + .../Editor/Types/VFXCircleGizmos.cs | 9 + .../Editor/Types/VFXConeGizmos.cs | 9 + .../Editor/Types/VFXLineGizmos.cs | 3 + .../Editor/Types/VFXPlaneGizmos.cs | 3 + .../Editor/Types/VFXPropertyAttribute.cs | 10 +- .../Editor/Types/VFXSphereGizmos.cs | 13 + .../Editor/Types/VFXTorusGizmos.cs | 9 + .../Editor/Types/VFXTransformGizmos.cs | 3 + .../Editor/Types/VFXTypeUtility.cs | 94 +- .../Editor/Types/VFXTypesGizmos.cs | 9 + .../UIResources/VFX/NodeChevronDown@2x.png | Bin 0 -> 252 bytes .../VFX/NodeChevronDown@2x.png.meta | 117 + .../Editor/UIResources/uss/VFXContext.uss | 2 +- .../Editor/UIResources/uss/VFXNode.uss | 7 +- .../UIResources/uss/VFXTemplateWindow.uss | 4 - .../Editor/Utils/VFXHelpURLAttribute.cs | 73 +- .../Editor/VisualEffectGraphShortcuts.cs | 14 +- .../ParticleHexahedron/PassDepthOrMV.template | 4 +- .../ParticleLines/PassDepthOrMV.template | 2 +- .../ParticleLinesSW/PassDepthOrMV.template | 2 +- .../ParticleMeshes/PassDepthOrMV.template | 2 +- .../PassDepthOrMV.template | 2 +- .../ParticlePoints/PassDepthOrMV.template | 2 +- .../Shaders/SixWay/SixWayVaryings.template | 91 +- .../Shaders/VFXCommonOutput.hlsl | 2 +- .../Shaders/VFXCopyBuffer.compute | 9 + .../Shaders/VFXGPUEvent.hlsl | 60 + .../Shaders/VFXGPUEvent.hlsl.meta | 7 + .../Shaders/VFXInit.template | 62 +- .../Shaders/VFXInstancing.hlsl | 60 +- .../Shaders/VFXOutputUpdate.template | 5 +- .../Shaders/VFXParticleCommon.template | 121 +- .../Shaders/VFXParticleHeader.template | 1 + .../VFXPassDepthCommonFragmentUnlit.template | 105 + ...PassDepthCommonFragmentUnlit.template.meta | 3 + .../Shaders/VFXPrefixSum.compute | 146 + .../Shaders/VFXPrefixSum.compute.meta | 7 + .../Shaders/VFXRayTracingCommon.hlsl | 151 + .../Shaders/VFXRayTracingCommon.hlsl.meta | 7 + .../Shaders/VFXUpdate.template | 8 +- .../Shaders/VFXVolumetricFogUpdate.template | 1 + .../com.unity.visualeffectgraph/package.json | 10 +- 469 files changed, 25087 insertions(+), 3614 deletions(-) create mode 100644 Packages/com.unity.render-pipelines.core/Editor/PropertyDrawers.meta create mode 100644 Packages/com.unity.render-pipelines.core/Editor/PropertyDrawers/VrsLutDrawer.cs create mode 100644 Packages/com.unity.render-pipelines.core/Editor/PropertyDrawers/VrsLutDrawer.cs.meta create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Debugging/Prefabs/Scripts/DebugUIHandlerRenderingLayerField.cs create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Debugging/Prefabs/Scripts/DebugUIHandlerRenderingLayerField.cs.meta create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Debugging/Prefabs/Widgets/DebugUIHandlerRenderingLayerField.prefab create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Debugging/Prefabs/Widgets/DebugUIHandlerRenderingLayerField.prefab.meta create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Settings/LightmapSamplingSettings.cs create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Settings/LightmapSamplingSettings.cs.meta create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Utilities/CullContextData.cs create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Utilities/CullContextData.cs.meta create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Vrs.meta create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders.meta create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsImage.hlsl create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsImage.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsMainTex.hlsl create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsMainTex.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsShadingRates.hlsl create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsShadingRates.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsTexture.compute create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsTexture.compute.meta create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsTileSize.hlsl create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsTileSize.hlsl.meta create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsVisualization.shader create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsVisualization.shader.meta create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Vrs/Vrs.cs create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Vrs/Vrs.cs.meta create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsLut.cs create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsLut.cs.meta create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsRenderPipelineRuntimeResources.cs create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsRenderPipelineRuntimeResources.cs.meta create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsResources.cs create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsResources.cs.meta create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsShaders.cs create mode 100644 Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsShaders.cs.meta create mode 100644 Packages/com.unity.render-pipelines.core/Tests/Editor/AssemblyInfo.cs create mode 100644 Packages/com.unity.render-pipelines.core/Tests/Editor/AssemblyInfo.cs.meta create mode 100644 Packages/com.unity.render-pipelines.core/Tests/Editor/RenderGraph.ComputeGraphHash.cs create mode 100644 Packages/com.unity.render-pipelines.core/Tests/Editor/RenderGraph.ComputeGraphHash.cs.meta create mode 100644 Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/CustomPass/VrsCustomPassDrawer.cs create mode 100644 Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/CustomPass/VrsCustomPassDrawer.cs.meta create mode 100644 Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/VFXPassDepthCommonFragmentLit.template create mode 100644 Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/VFXPassDepthCommonFragmentLit.template.meta create mode 100644 Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/VFXSixWayIncludes.template create mode 100644 Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/VFXSixWayIncludes.template.meta create mode 100644 Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.Vrs.cs create mode 100644 Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.Vrs.cs.meta create mode 100644 Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/VrsCustomPass.cs create mode 100644 Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/VrsCustomPass.cs.meta create mode 100644 Packages/com.unity.shadergraph/Editor/Drawing/Manipulators/MasterPreviewManipulator.cs create mode 100644 Packages/com.unity.shadergraph/Editor/Drawing/Manipulators/MasterPreviewManipulator.cs.meta create mode 100644 Packages/com.unity.shadergraph/Editor/Resources/Icons/sg_graph_icon@2x.png create mode 100644 Packages/com.unity.shadergraph/Editor/Resources/Icons/sg_graph_icon@2x.png.meta create mode 100644 Packages/com.unity.shadergraph/Editor/Resources/Icons/sg_subgraph_icon@2x.png create mode 100644 Packages/com.unity.shadergraph/Editor/Resources/Icons/sg_subgraph_icon@2x.png.meta create mode 100644 Packages/com.unity.ugui/Tests/Runtime/UGUI/CanvasRenderer.meta create mode 100644 Packages/com.unity.ugui/Tests/Runtime/UGUI/CanvasRenderer/CanvasRendererTests.cs create mode 100644 Packages/com.unity.ugui/Tests/Runtime/UGUI/CanvasRenderer/CanvasRendererTests.cs.meta create mode 100644 Packages/com.unity.visualeffectgraph/Editor/Compiler/VFXShaderSnippets.cs create mode 100644 Packages/com.unity.visualeffectgraph/Editor/Compiler/VFXShaderSnippets.cs.meta create mode 100644 Packages/com.unity.visualeffectgraph/Editor/ShaderGraph/Templates/VFXConfigRaytracing.template.hlsl create mode 100644 Packages/com.unity.visualeffectgraph/Editor/ShaderGraph/Templates/VFXConfigRaytracing.template.hlsl.meta create mode 100644 Packages/com.unity.visualeffectgraph/Editor/UIResources/VFX/NodeChevronDown@2x.png create mode 100644 Packages/com.unity.visualeffectgraph/Editor/UIResources/VFX/NodeChevronDown@2x.png.meta create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/VFXGPUEvent.hlsl create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/VFXGPUEvent.hlsl.meta create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/VFXPassDepthCommonFragmentUnlit.template create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/VFXPassDepthCommonFragmentUnlit.template.meta create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/VFXPrefixSum.compute create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/VFXPrefixSum.compute.meta create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/VFXRayTracingCommon.hlsl create mode 100644 Packages/com.unity.visualeffectgraph/Shaders/VFXRayTracingCommon.hlsl.meta diff --git a/Packages/com.unity.render-pipelines.core/CHANGELOG.md b/Packages/com.unity.render-pipelines.core/CHANGELOG.md index ac6e577b..0e7d310e 100644 --- a/Packages/com.unity.render-pipelines.core/CHANGELOG.md +++ b/Packages/com.unity.render-pipelines.core/CHANGELOG.md @@ -12,12 +12,15 @@ The version number for this package has increased due to a version update of a r ## [17.0.3] - 2025-02-13 -This version is compatible with Unity 6000.0.39f1. +This version is compatible with Unity 6000.2.0a1. ### Added +- Added Variable Rate Shading API support for (Raster)CommandBuffer(s), RenderGraph and RTHandles. +Various VRS utilities. - helper functions to Render Graph. ### Changed +- Improved Depth usage performance for some platforms. - Improved the Native Render Pass CPU performance by implementing a Render Pass pooling system (URP RG). - Reworked the additional properties. - Improved Render Graph warning message in URP when missing RecordRenderGraph implementation. @@ -27,6 +30,20 @@ This version is compatible with Unity 6000.0.39f1. - Added What's New in Unity 6 to SRP Core Package. ### Fixed +- Fixed render graph incorrectly handling rendering to array slices and mipmaps other than 0 in some cases. +- Fixed an issue where Lens Flare was not rendering properly in OpenGLES3. +- Fixed missing STP shaders & visual artifacts when targeting GLCore renderer. +- Render Graph Viewer - Improved UI lock when searching on side panels. +- Render Graph Viewer - Padding corrected on burger menu on the side panels. +- Fixed the crash happening when APV tried to stream in block data. +- Fixed VRS initialization errors. Now init may fail explicitly and must be checked by the user code. +- Fixed Rendering Debugger - Silent crash when selecting a Volume component with public RTHandles. +- Fixed Transient Resources support in Native RenderPass Render Graph (used in URP). +- Fixed an issue where the Adaptive Probe Volume (APV) streaming buffer could leak into the current pool when chunk sizes were mismatched, leading to memory contamination and potential crashes. +- Fixed an issue in the Render Graph Viewer where text overlapped after performing a search in the Pass List. +- Fixed an issue in pass culling where resources were not deallocated if the last pass using them was culled. +- Fixed `RenderGraphObjectPool` and `GetTempMaterialPropertyBlock()` usage in URP RenderGraph. +- Fixed an issue in URP Render Graph where, in an async compute edge case, it was waiting for a resource that was not written by any pass. - Added messaging to the Rendering Debugger UI to make it clearer that GPU Resident Drawer settings do not work if GPU Resident Drawer is not enabled. - GPU Resident Drawer: Changed BatchRendererGroup variants was not reinitializing the system. - Improved the compiler logic that detects if the current render target is being used outside the current native render pass (e.g., when the pass is broken up by an unsafe pass), and determines the store action for this case. The fix now ensures that the `StoreAndResolve` action is used when the resource is read by an Unsafe Pass. diff --git a/Packages/com.unity.render-pipelines.core/Editor/CommandBuffers/CommandBufferGenerator/CommandBufferGenerator.cs b/Packages/com.unity.render-pipelines.core/Editor/CommandBuffers/CommandBufferGenerator/CommandBufferGenerator.cs index a0fe400d..74075baf 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/CommandBuffers/CommandBufferGenerator/CommandBufferGenerator.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/CommandBuffers/CommandBufferGenerator/CommandBufferGenerator.cs @@ -110,7 +110,9 @@ namespace UnityEditor.Rendering new FunctionInfo("SetFoveatedRenderingMode", textureArg: "", modifiesGlobalState: true), new FunctionInfo("ConfigureFoveatedRendering", textureArg: "", modifiesGlobalState: true), new FunctionInfo("SetWireframe", textureArg: "", modifiesGlobalState: true), - }; + new FunctionInfo("SetShadingRateFragmentSize", textureArg: "", modifiesGlobalState: false), + new FunctionInfo("SetShadingRateCombiner", textureArg: "", modifiesGlobalState: false), + }; // Functions for unsafe (wrapper around Commandbuffer) only static List unsafeFunctions = new List { diff --git a/Packages/com.unity.render-pipelines.core/Editor/Debugging/DebugState.cs b/Packages/com.unity.render-pipelines.core/Editor/Debugging/DebugState.cs index 0c7e971b..5a57ad95 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Debugging/DebugState.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/Debugging/DebugState.cs @@ -237,9 +237,15 @@ namespace UnityEditor.Rendering /// /// Unsigned Integer Debug State. /// - [Serializable, DebugState(typeof(DebugUI.UIntField), typeof(DebugUI.MaskField))] + [Serializable, DebugState(typeof(DebugUI.UIntField))] public sealed class DebugStateUInt : DebugState { } + /// + /// Rendering layer mask state. + /// + [Serializable, DebugState(typeof(DebugUI.RenderingLayerField))] + public sealed class DebugStateRenderingLayer : DebugState { } + /// /// Float Debug State. /// diff --git a/Packages/com.unity.render-pipelines.core/Editor/Debugging/DebugUIDrawer.Builtins.cs b/Packages/com.unity.render-pipelines.core/Editor/Debugging/DebugUIDrawer.Builtins.cs index f5bed0d0..ca52e10e 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Debugging/DebugUIDrawer.Builtins.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/Debugging/DebugUIDrawer.Builtins.cs @@ -398,12 +398,11 @@ namespace UnityEditor.Rendering } } - /// /// Builtin Drawer for Maskfield Debug Items. /// - [DebugUIDrawer(typeof(DebugUI.MaskField))] - public sealed class DebugUIDrawerMaskField : DebugUIFieldDrawer + [DebugUIDrawer(typeof(DebugUI.RenderingLayerField))] + public sealed class DebugUIDrawerRenderingLayerField : DebugUIFieldDrawer { /// /// Does the field of the given type @@ -413,15 +412,10 @@ namespace UnityEditor.Rendering /// The field /// The state /// The current value from the UI - protected override uint DoGUI(Rect rect, GUIContent label, DebugUI.MaskField field, DebugStateUInt state) + protected override RenderingLayerMask DoGUI(Rect rect, GUIContent label, DebugUI.RenderingLayerField field, DebugStateRenderingLayer state) { uint value = field.GetValue(); - - var enumNames = new string[field.enumNames.Length]; - for (int i = 0; i < enumNames.Length; i++) - enumNames[i] = field.enumNames[i].text; - var mask = EditorGUI.MaskField(rect, label, (int)value, enumNames); - + var mask = EditorGUI.MaskField(rect, label, (int)value, field.renderingLayersNames); return (uint)mask; } } diff --git a/Packages/com.unity.render-pipelines.core/Editor/Debugging/DebugWindow.cs b/Packages/com.unity.render-pipelines.core/Editor/Debugging/DebugWindow.cs index 1ca095c6..9547e9e6 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Debugging/DebugWindow.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/Debugging/DebugWindow.cs @@ -43,7 +43,7 @@ namespace UnityEditor.Rendering hideFlags = HideFlags.HideAndDontSave; } } - + [CoreRPHelpURL("Rendering-Debugger")] sealed class DebugWindow : EditorWindowWithHelpButton, IHasCustomMenu { @@ -478,22 +478,22 @@ namespace UnityEditor.Rendering using (new EditorGUILayout.VerticalScope()) { var selectedPanel = panels[m_Settings.selectedPanel]; - + using (new EditorGUILayout.HorizontalScope()) { var style = new GUIStyle(CoreEditorStyles.sectionHeaderStyle) { fontStyle = FontStyle.Bold }; EditorGUILayout.LabelField(new GUIContent(selectedPanel.displayName), style); - + // Context menu var rect = GUILayoutUtility.GetLastRect(); var contextMenuRect = new Rect(rect.xMax, rect.y + 4f, 16f, 16f); - + CoreEditorUtils.ShowHelpButton(contextMenuRect, selectedPanel.documentationUrl, new GUIContent($"{selectedPanel.displayName} panel.")); } const float leftMargin = 4f; GUILayout.Space(leftMargin); - + using (var scrollScope = new EditorGUILayout.ScrollViewScope(m_ContentScroll)) { TraverseContainerGUI(selectedPanel); @@ -544,6 +544,11 @@ namespace UnityEditor.Rendering if (widget.isInactiveInEditor || widget.isHidden) return; + if (widget.queryPath == null) + { + Debug.LogError($"Widget {widget.GetType()} query path is null"); + return; + } // State will be null for stateless widget m_WidgetStates.TryGetValue(widget.queryPath, out DebugState state); diff --git a/Packages/com.unity.render-pipelines.core/Editor/Deprecated.cs b/Packages/com.unity.render-pipelines.core/Editor/Deprecated.cs index e1bdc6b6..cea5bdd6 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Deprecated.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/Deprecated.cs @@ -15,25 +15,47 @@ namespace UnityEditor.Rendering } /// - /// This attributes tells a class which type of - /// it's an editor for. - /// When you make a custom editor for a component, you need put this attribute on the editor - /// class. + /// This attribute tells the class which type of + /// it is an editor for. It is used to associate a custom editor + /// with a specific volume component, enabling the editor to handle its custom properties and settings. /// + /// + /// When creating a custom editor for a , this attribute must be applied + /// to the editor class to ensure it targets the appropriate component. This functionality has been deprecated, + /// and developers are encouraged to use the attribute instead for newer versions. + /// + /// The attribute specifies which type the editor class is responsible for. + /// Typically, it is used in conjunction with custom editor UI drawing and handling logic for the specified volume component. + /// This provides a way for developers to create custom editing tools for their volume components in the Unity Inspector. + /// + /// Since Unity 2022.2, this functionality has been replaced by the attribute, and as such, + /// it is advised to update any existing custom editors to use the newer approach. + /// /// + /// [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] [Obsolete("VolumeComponentEditor property has been deprecated. Please use CustomEditor. #from(2022.2)")] public sealed class VolumeComponentEditorAttribute : CustomEditor { /// - /// A type derived from . + /// A type derived from that this editor is responsible for. /// + /// + /// This field holds the type of the volume component that the editor class will handle. + /// The type should be a subclass of and is used to associate the editor + /// with the specific component type. + /// public readonly Type componentType; /// /// Creates a new instance. /// - /// A type derived from + /// A type derived from that the editor is responsible for. + /// + /// This constructor initializes the attribute with the component type that the editor will target. + /// The component type is a subclass of and provides the necessary + /// context for the editor class to function properly within the Unity Editor. + /// public VolumeComponentEditorAttribute(Type componentType) : base(componentType, true) { @@ -41,6 +63,7 @@ namespace UnityEditor.Rendering } } + /// /// Interface that should be used with [ScriptableRenderPipelineExtension(type))] attribute to dispatch ContextualMenu calls on the different SRPs /// @@ -158,4 +181,34 @@ namespace UnityEditor.Rendering m_TargetSerializedObject = baseEditor.serializedObject; } } + + + + /// + /// Builtin Drawer for Maskfield Debug Items. + /// + [DebugUIDrawer(typeof(DebugUI.MaskField))] + [Obsolete("DebugUI.MaskField has been deprecated and is not longer supported, please use BitField instead. #from(6000.2)", false)] + public sealed class DebugUIDrawerMaskField : DebugUIFieldDrawer + { + /// + /// Does the field of the given type + /// + /// The rect to draw the field + /// The label for the field + /// The field + /// The state + /// The current value from the UI + protected override uint DoGUI(Rect rect, GUIContent label, DebugUI.MaskField field, DebugStateUInt state) + { + uint value = field.GetValue(); + + var enumNames = new string[field.enumNames.Length]; + for (int i = 0; i < enumNames.Length; i++) + enumNames[i] = field.enumNames[i].text; + var mask = EditorGUI.MaskField(rect, label, (int)value, enumNames); + + return (uint)mask; + } + } } diff --git a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.Serialization.cs b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.Serialization.cs index 12733d3c..e44748d4 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.Serialization.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.Serialization.cs @@ -1070,7 +1070,11 @@ namespace UnityEngine.Rendering AssetDatabase.ImportAsset(cellDataFilename); AssetDatabase.ImportAsset(cellOptionalDataFilename); - AssetDatabase.ImportAsset(cellProbeOcclusionDataFilename); + // If we did not write a probe occlusion file (because it was zero bytes), don't try to load it (UUM-101480) + if (probeOcclusion.Length > 0) + { + AssetDatabase.ImportAsset(cellProbeOcclusionDataFilename); + } AssetDatabase.ImportAsset(cellBricksDataFilename); AssetDatabase.ImportAsset(cellSharedDataFilename); AssetDatabase.ImportAsset(cellSupportDataFilename); diff --git a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.cs b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.cs index 922c77f8..245fb5c2 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.cs @@ -748,8 +748,7 @@ namespace UnityEngine.Rendering for (int i = 0; i < perSceneData.Count; ++i) { var data = perSceneData[i]; - var scene = data.gameObject.scene; - var sceneGUID = scene.GetGUID(); + var sceneGUID = data.sceneGUID; var bakingSet = ProbeVolumeBakingSet.GetBakingSetForScene(sceneGUID); if (bakingSet == null) @@ -757,7 +756,8 @@ namespace UnityEngine.Rendering if (isBakingSingleScene) continue; - Debug.LogError($"Scene '{scene.name}' does not belong to any Baking Set. Please add it to a Baking Set in the Adaptive Probe Volumes tab of the Lighting Window."); + var sceneName = data.gameObject.scene.name; + Debug.LogError($"Scene '{sceneName}' does not belong to any Baking Set. Please add it to a Baking Set in the Adaptive Probe Volumes tab of the Lighting Window."); return false; } diff --git a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeVolumeBuildProcessor.cs b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeVolumeBuildProcessor.cs index 65fbc502..cf041304 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeVolumeBuildProcessor.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeVolumeBuildProcessor.cs @@ -4,11 +4,10 @@ using UnityEditor.Build; using UnityEditor.Build.Reporting; using UnityEngine; using UnityEngine.Rendering; -using UnityEngine.SceneManagement; namespace UnityEditor.Rendering { - class ProbeVolumeBuildProcessor : BuildPlayerProcessor, IProcessSceneWithReport + class ProbeVolumeBuildProcessor : BuildPlayerProcessor, IPostprocessBuildWithReport { const string kTempAPVStreamingAssetsPath = "TempAPVStreamingAssets"; @@ -18,15 +17,27 @@ namespace UnityEditor.Rendering return Path.Combine(libraryPath, kTempAPVStreamingAssetsPath); } - void PrepareStreamableAsset(ProbeVolumeStreamableAsset asset, string basePath, bool useStreamingAsset) + // Include an asset in the build. The mechanism for doing so depends on whether we are using StreamingAssets path. + static void IncludeStreamableAsset(ProbeVolumeStreamableAsset asset, string basePath, bool useStreamingAsset) { - asset.UpdateAssetReference(useStreamingAsset); - if (useStreamingAsset) + { + asset.ClearAssetReferenceForBuild(); CopyStreamableAsset(asset, basePath); + } + else + { + asset.EnsureAssetLoaded(); + } + } + + // Ensure that an asset is not included in the build. + static void StripStreambleAsset(ProbeVolumeStreamableAsset asset) + { + asset.ClearAssetReferenceForBuild(); } - void CopyStreamableAsset(ProbeVolumeStreamableAsset asset, string basePath) + static void CopyStreamableAsset(ProbeVolumeStreamableAsset asset, string basePath) { var assetPath = asset.GetAssetPath(); if (!File.Exists(assetPath)) @@ -60,6 +71,9 @@ namespace UnityEditor.Rendering } } + // Keep track of which assets we touched during the build, so we can restore them after the build. + private static HashSet s_BakingSetsProcessedLastBuild = new(); + public override void PrepareForBuild(BuildPlayerContext buildPlayerContext) { GetProbeVolumeProjectSettings(buildPlayerContext.BuildPlayerOptions.target, out bool supportProbeVolume, out var maxSHBands); @@ -89,8 +103,7 @@ namespace UnityEditor.Rendering Directory.CreateDirectory(tempStreamingAssetsPath); - HashSet processedBakingSets = new HashSet(); - + s_BakingSetsProcessedLastBuild.Clear(); foreach (var scene in buildPlayerContext.BuildPlayerOptions.scenes) { var sceneGUID = AssetDatabase.AssetPathToGUID(scene); @@ -98,7 +111,7 @@ namespace UnityEditor.Rendering if (bakingSet != null) { // Already processed (different scenes can belong to the same baking set). - if (processedBakingSets.Contains(bakingSet)) + if (s_BakingSetsProcessedLastBuild.Contains(bakingSet)) continue; if (!bakingSet.cellSharedDataAsset.IsValid()) // Not baked @@ -111,89 +124,57 @@ namespace UnityEditor.Rendering bool useStreamingAsset = !GraphicsSettings.GetRenderPipelineSettings().probeVolumeDisableStreamingAssets; - PrepareStreamableAsset(bakingSet.cellSharedDataAsset, basePath, useStreamingAsset); - PrepareStreamableAsset(bakingSet.cellBricksDataAsset, basePath, useStreamingAsset); + IncludeStreamableAsset(bakingSet.cellSharedDataAsset, basePath, useStreamingAsset); + IncludeStreamableAsset(bakingSet.cellBricksDataAsset, basePath, useStreamingAsset); // For now we always strip support data in build as it's mostly unsupported. // Later we'll need a proper option to strip it or not. bool stripSupportData = true; - if (!stripSupportData) - PrepareStreamableAsset(bakingSet.cellSupportDataAsset, basePath, useStreamingAsset); + if (stripSupportData) + StripStreambleAsset(bakingSet.cellSupportDataAsset); + else + IncludeStreamableAsset(bakingSet.cellSupportDataAsset, basePath, useStreamingAsset); foreach (var scenario in bakingSet.scenarios) { - PrepareStreamableAsset(scenario.Value.cellDataAsset, basePath, useStreamingAsset); + IncludeStreamableAsset(scenario.Value.cellDataAsset, basePath, useStreamingAsset); if (maxSHBands == ProbeVolumeSHBands.SphericalHarmonicsL2) - PrepareStreamableAsset(scenario.Value.cellOptionalDataAsset, basePath, useStreamingAsset); - PrepareStreamableAsset(scenario.Value.cellProbeOcclusionDataAsset, basePath, useStreamingAsset); + IncludeStreamableAsset(scenario.Value.cellOptionalDataAsset, basePath, useStreamingAsset); + else + StripStreambleAsset(scenario.Value.cellOptionalDataAsset); + + if (bakingSet.bakedProbeOcclusion) + IncludeStreamableAsset(scenario.Value.cellProbeOcclusionDataAsset, basePath, useStreamingAsset); + else + StripStreambleAsset(scenario.Value.cellProbeOcclusionDataAsset); } - processedBakingSets.Add(bakingSet); + s_BakingSetsProcessedLastBuild.Add(bakingSet); } } buildPlayerContext.AddAdditionalPathToStreamingAssets(tempStreamingAssetsPath, AdaptiveProbeVolumes.kAPVStreamingAssetsPath); } - private static bool IsBundleBuild(BuildReport report, bool isPlaying) - { - // We are entering playmode, so not building a bundle. - if (isPlaying) - return false; - - // Addressable builds do not provide a BuildReport. Because the Addressables package - // only supports AssetBundle builds, we infer that this is not a player build. - if (report == null) - return true; - - return report.summary.buildType == BuildType.AssetBundle; - } - - // This codepath handles the case of building asset bundles, i.e. not a full player build. It updates the references - // to individual data assets in the baking sets for each scene, such that the assets are included in the bundle. - public override int callbackOrder => 1; - public void OnProcessScene(Scene scene, BuildReport report) + public void OnPostprocessBuild(BuildReport report) { - // Only run for bundle builds. - if (!IsBundleBuild(report, Application.isPlaying)) - return; - - // Only run when APV is enabled. - GetProbeVolumeProjectSettings(EditorUserBuildSettings.activeBuildTarget, out bool supportProbeVolume, out var maxSHBands); - if (!supportProbeVolume) - return; - - // Reload the map from scene to baking set if we couldn't find the specific baking set. - if (ProbeVolumeBakingSet.sceneToBakingSet == null || ProbeVolumeBakingSet.sceneToBakingSet.Count == 0) - ProbeVolumeBakingSet.SyncBakingSets(); - - // Get the baking set for the scene. - var bakingSet = ProbeVolumeBakingSet.GetBakingSetForScene(scene.GetGUID()); - if (bakingSet == null || !bakingSet.cellSharedDataAsset.IsValid()) + if (s_BakingSetsProcessedLastBuild == null || s_BakingSetsProcessedLastBuild.Count == 0) return; - bool useStreamingAsset = !GraphicsSettings.GetRenderPipelineSettings().probeVolumeDisableStreamingAssets; - if (useStreamingAsset) + // Go over each asset reference we touched during the last build, make sure asset references are intact. + foreach (var bakingSet in s_BakingSetsProcessedLastBuild) { - Debug.LogWarning( - "Attempted to build an Asset Bundle containing Adaptive Probe Volume data, but streaming assets are enabled. This is unsupported. " + - "To use Adaptive Probe Volumes with Asset Bundles, please check 'Probe Volume Disable Streaming Assets' under Graphics Settings."); + bakingSet.cellBricksDataAsset.EnsureAssetLoaded(); + bakingSet.cellSharedDataAsset.EnsureAssetLoaded(); + bakingSet.cellSupportDataAsset.EnsureAssetLoaded(); + foreach (var scenario in bakingSet.scenarios) + { + scenario.Value.cellDataAsset.EnsureAssetLoaded(); + scenario.Value.cellOptionalDataAsset.EnsureAssetLoaded(); + scenario.Value.cellProbeOcclusionDataAsset.EnsureAssetLoaded(); + } } - // Update all the asset references. - bakingSet.cellSharedDataAsset.UpdateAssetReference(useStreamingAsset); - bakingSet.cellBricksDataAsset.UpdateAssetReference(useStreamingAsset); - - bool stripSupportData = true; - if (!stripSupportData) - bakingSet.cellSupportDataAsset.UpdateAssetReference(false); - - foreach (var scenario in bakingSet.scenarios) - { - scenario.Value.cellDataAsset.UpdateAssetReference(useStreamingAsset); - if (maxSHBands == ProbeVolumeSHBands.SphericalHarmonicsL2) - scenario.Value.cellOptionalDataAsset.UpdateAssetReference(useStreamingAsset); - scenario.Value.cellProbeOcclusionDataAsset.UpdateAssetReference(useStreamingAsset); - } + s_BakingSetsProcessedLastBuild.Clear(); } } } diff --git a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeVolumeLightingTab.cs b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeVolumeLightingTab.cs index 8aaa605c..fcd6253a 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeVolumeLightingTab.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeVolumeLightingTab.cs @@ -221,6 +221,7 @@ namespace UnityEngine.Rendering Initialize(); var prv = ProbeReferenceVolume.instance; + // In single scene mode, user can't control active set, so we automatically create a new one // in case the active scene doesn't have a baking set so that we can display baking settings // Clone the current activeSet if possible so that it's seamless when eg. duplicating a scene @@ -787,10 +788,14 @@ namespace UnityEngine.Rendering // Find the set in which the new active scene belongs var set = ProbeVolumeBakingSet.GetBakingSetForScene(scene); - if (set != null) - { - activeSet = set; + activeSet = set; + if (set == null) + { + m_SingleSceneMode = true; + } + else + { // If we load a new scene that doesn't have the current scenario, change it if (!set.m_LightingScenarios.Contains(prv.lightingScenario)) prv.SetActiveScenario(set.m_LightingScenarios[0], false); diff --git a/Packages/com.unity.render-pipelines.core/Editor/PropertyDrawers.meta b/Packages/com.unity.render-pipelines.core/Editor/PropertyDrawers.meta new file mode 100644 index 00000000..c2f69514 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Editor/PropertyDrawers.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5f6f204246726d84a87fac671dba9b53 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Editor/PropertyDrawers/VrsLutDrawer.cs b/Packages/com.unity.render-pipelines.core/Editor/PropertyDrawers/VrsLutDrawer.cs new file mode 100644 index 00000000..7a6675e1 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Editor/PropertyDrawers/VrsLutDrawer.cs @@ -0,0 +1,60 @@ +using System; +using System.Reflection; +using UnityEngine; +using UnityEngine.Rendering; +using UnityEditor.UIElements; +using UnityEngine.UIElements; + +namespace UnityEditor.Rendering +{ + /// + /// Displays UI for a VrsLut lookup table. Each entry is a + /// ShadingRateFragmentSize enum value that maps to a Color. + /// + [CustomPropertyDrawer(typeof(VrsLut))] + sealed class VrsLutDrawer : PropertyDrawer + { + /// + public override VisualElement CreatePropertyGUI(SerializedProperty property) + { + var foldout = new Foldout() + { + text = property.displayName, + value = property.isExpanded, + }; + + var vrsLutData = GetVrsLutData(property); + VrsLutDataGUI(foldout.contentContainer, vrsLutData); + + VisualElement root = new(); + root.Add(foldout); + return root; + } + + /// + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) + { + if (property.isExpanded) + return (GetVrsLutData(property).arraySize + 1) * EditorGUIUtility.singleLineHeight; + + return EditorGUIUtility.singleLineHeight; + } + + void VrsLutDataGUI(VisualElement contentContainer, SerializedProperty vrsLutData) + { + foreach (var fragmentSizeInfo in shadingRateFragmentSizeFields) + { + var fragmentSizeValue = (ShadingRateFragmentSize) fragmentSizeInfo.GetValue(null); + var inspectorNameAttribute = fragmentSizeInfo.GetCustomAttribute(); + var displayName = inspectorNameAttribute == null ? ObjectNames.NicifyVariableName(fragmentSizeValue.ToString()) : inspectorNameAttribute.displayName; + var lutProp = vrsLutData.GetArrayElementAtIndex((int) fragmentSizeValue); + var propertyField = new PropertyField(lutProp, displayName); + contentContainer.Add(propertyField); + } + } + + static SerializedProperty GetVrsLutData(SerializedProperty property) => property.FindPropertyRelative("m_Data"); + + static FieldInfo[] shadingRateFragmentSizeFields => typeof(ShadingRateFragmentSize).GetFields(BindingFlags.Static | BindingFlags.Public); + } +} diff --git a/Packages/com.unity.render-pipelines.core/Editor/PropertyDrawers/VrsLutDrawer.cs.meta b/Packages/com.unity.render-pipelines.core/Editor/PropertyDrawers/VrsLutDrawer.cs.meta new file mode 100644 index 00000000..4eb1244d --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Editor/PropertyDrawers/VrsLutDrawer.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: f271dd66b05804343bbd8ff052f767a0 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Editor/RenderGraph/RenderGraphViewer.SidePanel.cs b/Packages/com.unity.render-pipelines.core/Editor/RenderGraph/RenderGraphViewer.SidePanel.cs index 37419dc3..8ae75375 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/RenderGraph/RenderGraphViewer.SidePanel.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/RenderGraph/RenderGraphViewer.SidePanel.cs @@ -39,9 +39,8 @@ namespace UnityEditor.Rendering public const string kCustomFoldoutArrow = "custom-foldout-arrow"; } - static readonly System.Text.RegularExpressions.Regex k_TagRegex = new ("<[^>]*>"); - const string k_SelectionColorBeginTag = ""; - const string k_SelectionColorEndTag = ""; + internal const string k_SelectionColorBeginTag = ""; + internal const string k_SelectionColorEndTag = ""; TwoPaneSplitView m_SidePanelSplitView; bool m_ResourceListExpanded = true; @@ -109,12 +108,37 @@ namespace UnityEditor.Rendering passSearchField.RegisterValueChangedCallback(evt => OnSearchFilterChanged(m_PassDescendantCache, evt.newValue)); } - bool IsSearchFilterMatch(string str, string searchString, out int startIndex, out int endIndex) + static bool IsInsideTag(string input, int index) + { + int openTagIndex = input.LastIndexOf('<', index); + int closeTagIndex = input.LastIndexOf('>', index); + return openTagIndex > closeTagIndex; + } + + static bool IsSearchFilterMatch(string str, string searchString, out int startIndex, out int endIndex) { startIndex = -1; endIndex = -1; - startIndex = str.IndexOf(searchString, 0, StringComparison.CurrentCultureIgnoreCase); + if (searchString.Length == 0) + return true; + + int searchStartIndex = 0; + for (;;) + { + startIndex = str.IndexOf(searchString, searchStartIndex, StringComparison.CurrentCultureIgnoreCase); + + // If we found a match but it is inside another tag, ignore it and continue + if (startIndex != -1 && IsInsideTag(str, startIndex)) + { + searchStartIndex = startIndex + 1; + continue; + } + + // Either valid match (not inside another tag) or no match + break; + } + if (startIndex == -1) return false; @@ -134,6 +158,9 @@ namespace UnityEditor.Rendering Debug.LogWarning("[Render Graph Viewer] Search string limit exceeded: " + k_SearchStringLimit); } + // Sanitize to not match rich text tags + searchString = searchString.Replace("<", string.Empty).Replace(">", string.Empty); + // If the search string hasn't changed, avoid repeating the same search if (m_PendingSearchString == searchString) return; @@ -147,12 +174,12 @@ namespace UnityEditor.Rendering .schedule .Execute(() => { - PerformSearchAsync(elementCache, searchString); + PerformSearch(elementCache, searchString); }) .StartingIn(5); // Avoid spamming multiple search if the user types really fast } - private void PerformSearchAsync(Dictionary> elementCache, string searchString) + internal static void PerformSearch(Dictionary> elementCache, string searchString) { // Display filter foreach (var (foldout, descendants) in elementCache) @@ -160,20 +187,28 @@ namespace UnityEditor.Rendering bool anyDescendantMatchesSearch = false; foreach (var elem in descendants) { - // Remove any existing highlight var text = elem.text; - var hasHighlight = k_TagRegex.IsMatch(text); - text = k_TagRegex.Replace(text, string.Empty); + + // Remove existing match highlight tags + var hasHighlight = text.IndexOf(k_SelectionColorBeginTag, StringComparison.Ordinal) >= 0; + if (hasHighlight) + { + text = text.Replace(k_SelectionColorBeginTag, string.Empty); + text = text.Replace(k_SelectionColorEndTag, string.Empty); + } + if (!IsSearchFilterMatch(text, searchString, out int startHighlight, out int endHighlight)) { - if (hasHighlight) - elem.text = text; + // Reset original text + elem.text = text; continue; } - - text = text.Insert(startHighlight, k_SelectionColorBeginTag); - text = text.Insert(endHighlight + k_SelectionColorBeginTag.Length + 1, k_SelectionColorEndTag); + if (startHighlight >= 0 && endHighlight >= 0) + { + text = text.Insert(startHighlight, k_SelectionColorBeginTag); + text = text.Insert(endHighlight + k_SelectionColorBeginTag.Length + 1, k_SelectionColorEndTag); + } elem.text = text; anyDescendantMatchesSearch = true; } diff --git a/Packages/com.unity.render-pipelines.core/Editor/SampleDependencyImportSystem/SampleDependencyImporter.cs b/Packages/com.unity.render-pipelines.core/Editor/SampleDependencyImportSystem/SampleDependencyImporter.cs index 65043e20..56d25b9a 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/SampleDependencyImportSystem/SampleDependencyImporter.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/SampleDependencyImportSystem/SampleDependencyImporter.cs @@ -48,7 +48,9 @@ class SampleDependencyImporter : IPackageManagerExtension PackageManagerExtensions.RegisterExtension(new SampleDependencyImporter()); } - const string k_srpPrefixPackage = "com.unity."; + const string k_unityPrefixPackage = "com.unity."; + bool importingTextMeshProEssentialResources = false; + PackageInfo m_PackageInfo; List m_Samples; SampleList m_SampleList; @@ -63,11 +65,15 @@ class SampleDependencyImporter : IPackageManagerExtension /// void IPackageManagerExtension.OnPackageSelectionChange(PackageInfo packageInfo) { - var isSrpPackage = packageInfo != null && packageInfo.name.StartsWith(k_srpPrefixPackage); + var isUnityPackage = packageInfo != null && packageInfo.name.StartsWith(k_unityPrefixPackage); - if (isSrpPackage) + if (isUnityPackage) { - m_PackageInfo = packageInfo; + + + + + m_PackageInfo = packageInfo; m_Samples = GetSamples(packageInfo); if (TryLoadSampleConfiguration(m_PackageInfo, out m_SampleList)) { @@ -104,6 +110,9 @@ class SampleDependencyImporter : IPackageManagerExtension /// void LoadAssetDependencies(string assetPath) { + + ImportTextMeshProEssentialResources(); + if (m_SampleList != null) { var assetsImported = false; @@ -126,11 +135,32 @@ class SampleDependencyImporter : IPackageManagerExtension } } } + + if (assetsImported) AssetDatabase.Refresh(); } } + + /// + /// Import TMP Essential Resources folder to avoid having a popup on scene open. + /// + public void ImportTextMeshProEssentialResources() + { + string essentialResourcesFolder = Path.GetFullPath("Assets/TextMesh Pro"); + bool essentialResourcesImported = Directory.Exists(essentialResourcesFolder); + // If the folder exists and we were importing, this means the import is done. + if (importingTextMeshProEssentialResources && essentialResourcesImported) + importingTextMeshProEssentialResources = false; + + string packageFullPath = Path.GetFullPath("Packages/com.unity.ugui"); + if (Directory.Exists(packageFullPath) && !importingTextMeshProEssentialResources && !essentialResourcesImported) + { + importingTextMeshProEssentialResources = true; + AssetDatabase.ImportPackage(packageFullPath + "/Package Resources/TMP Essential Resources.unitypackage", interactive: false); + } + } /// /// Returns the properties of the samples based on the sample displayName diff --git a/Packages/com.unity.render-pipelines.core/Editor/Volume/VolumeParameterDrawer.cs b/Packages/com.unity.render-pipelines.core/Editor/Volume/VolumeParameterDrawer.cs index 4cbf334f..a463ad4f 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Volume/VolumeParameterDrawer.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/Volume/VolumeParameterDrawer.cs @@ -35,7 +35,7 @@ namespace UnityEditor.Rendering /// parameter this drawer is for. /// /// - /// If you do not provide a custom editor for a , Unity uses the buil-in property drawers to draw the + /// If you do not provide a custom editor for a , Unity uses the built-in property drawers to draw the /// property as-is. /// /// diff --git a/Packages/com.unity.render-pipelines.core/Runtime/AssemblyInfo.cs b/Packages/com.unity.render-pipelines.core/Runtime/AssemblyInfo.cs index 8bf49b24..96162f18 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/AssemblyInfo.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/AssemblyInfo.cs @@ -5,3 +5,7 @@ using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("Unity.RenderPipelines.Core.Runtime.Tests")] [assembly: InternalsVisibleTo("Unity.GraphicTests.Performance.RPCore.Runtime")] [assembly: InternalsVisibleTo("Unity.GraphicTests.Performance.Universal.Runtime")] // access to internal ProfileIds + +// Smoke test project visibility +[assembly: InternalsVisibleTo("SRPSmoke.Runtime.Tests")] +[assembly: InternalsVisibleTo("SRPSmoke.Editor.Tests")] diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Camera/CameraHistory.cs b/Packages/com.unity.render-pipelines.core/Runtime/Camera/CameraHistory.cs index 8c45638e..d21c9317 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Camera/CameraHistory.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Camera/CameraHistory.cs @@ -151,11 +151,29 @@ namespace UnityEngine.Rendering protected RTHandle AllocHistoryFrameRT(int id, int count, ref RenderTextureDescriptor desc, string name = "") { - RenderTextureDescriptor d = desc; // Simplified for typical history textures: // Sampling is usually bilinear & clamp. Point sample can be a texture.Load() or done with inline samplers. + return AllocHistoryFrameRT(id, count, ref desc, FilterMode.Bilinear, name); + } + + /// + /// Allocate a history frame RTHandle[] using a descriptor. + /// + /// Id for the history RTHandle storage. + /// Number of RTHandles allocated for the id. + /// Texture descriptor used for each RTHandle in the allocation. + /// Filtering mode of the texture. + /// User visible debug name of the texture. + /// Current frame RTHandle in the allocation. + protected RTHandle AllocHistoryFrameRT(int id, int count, + ref RenderTextureDescriptor desc, + FilterMode filterMode, + string name = "") + { + RenderTextureDescriptor d = desc; + // Simplified for typical history textures: // No shadows, no mipmaps, no aniso. - m_owner.AllocBuffer(id, count, ref desc, FilterMode.Bilinear, TextureWrapMode.Clamp, false, 0, 0, name); + m_owner.AllocBuffer(id, count, ref desc, filterMode, TextureWrapMode.Clamp, false, 0, 0, name); return GetCurrentFrameRT(0); } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/BaseCommandBufer.cs b/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/BaseCommandBufer.cs index 966c22cb..047f8da0 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/BaseCommandBufer.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/BaseCommandBufer.cs @@ -50,7 +50,7 @@ namespace UnityEngine.Rendering [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] protected internal void ThrowIfRasterNotAllowed() { - if (m_ExecutingPass != null && !m_ExecutingPass.HasRenderAttachments()) throw new InvalidOperationException($"{m_ExecutingPass.name}: Using raster commands from a pass with no active render targets is not allowed as it will use an undefined render target state. Please set-up the pass's render targets using SetRenderAttachments."); + if (m_ExecutingPass != null && !m_ExecutingPass.HasRenderAttachments()) throw new InvalidOperationException($"{m_ExecutingPass.name}: Using raster commands from a pass with no active render target is not allowed as it will use an undefined render target state. Please set up pass render targets using SetRenderAttachments."); } /// @@ -71,13 +71,13 @@ namespace UnityEngine.Rendering if (h.IsBuiltin()) return; - if (!m_ExecutingPass.IsRead(h.handle) && !m_ExecutingPass.IsWritten(h.handle)) + if (!m_ExecutingPass.IsRead(h.handle) && !m_ExecutingPass.IsWritten(h.handle) && !m_ExecutingPass.IsTransient(h.handle)) { - throw new Exception("Pass '" + m_ExecutingPass.name + "' is trying to use a texture on the command buffer that was never registered with the pass builder. Please indicate the texture use to the pass builder."); + throw new Exception($"Pass '{m_ExecutingPass.name}' is trying to bind a texture on the command buffer that is not registered by its builder. Please indicate to the pass builder how the texture is used (UseTexture/CreateTransientTexture)."); } if (m_ExecutingPass.IsAttachment(h)) { - throw new Exception("Pass '" + m_ExecutingPass.name + "' is using a texture as a fragment attachment (SetRenderAttachment/SetRenderAttachmentDepth) but is also trying to bind it as regular texture. Please fix this pass. "); + throw new Exception($"Pass '{m_ExecutingPass.name}' is trying to bind a texture on the command buffer that is already set as a fragment attachment (SetRenderAttachment/SetRenderAttachmentDepth). A texture cannot be used as both in one pass, please fix its usage in the pass builder."); } } } @@ -93,17 +93,17 @@ namespace UnityEngine.Rendering [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] protected internal void ValidateTextureHandleRead(TextureHandle h) { - if(RenderGraph.enableValidityChecks) + if (RenderGraph.enableValidityChecks) { if (m_ExecutingPass == null) return; - if (!m_ExecutingPass.IsRead(h.handle)) + if (!m_ExecutingPass.IsRead(h.handle) && !m_ExecutingPass.IsTransient(h.handle)) { - throw new Exception("Pass '" + m_ExecutingPass.name + "' is trying to read a texture on the command buffer that was never registered with the pass builder. Please indicate the texture as read to the pass builder."); + throw new Exception($"Pass '{m_ExecutingPass.name}' is trying to read a texture on the command buffer that is not registered by its builder. Please indicate to the pass builder that the texture is read (UseTexture/CreateTransientTexture)."); } if (m_ExecutingPass.IsAttachment(h)) { - throw new Exception("Pass '" + m_ExecutingPass.name + "' is using a texture as a fragment attachment (SetRenderAttachment/SetRenderAttachmentDepth) but is also trying to bind it as regular texture. Please fix this pass. "); + throw new Exception($"Pass '{m_ExecutingPass.name}' is trying to bind a texture on the command buffer that is already set as a fragment attachment (SetRenderAttachment/SetRenderAttachmentDepth). A texture cannot be used as both in one pass, please fix its usage in the pass builder."); } } } @@ -129,13 +129,14 @@ namespace UnityEngine.Rendering throw new Exception("Pass '" + m_ExecutingPass.name + "' is trying to write to a built-in texture. This is not allowed built-in textures are small default resources like `white` or `black` that cannot be written to."); } - if (!m_ExecutingPass.IsWritten(h.handle)) + if (!m_ExecutingPass.IsWritten(h.handle) && !m_ExecutingPass.IsTransient(h.handle)) { - throw new Exception("Pass '" + m_ExecutingPass.name + "' is trying to write a texture on the command buffer that was never registered with the pass builder. Please indicate the texture as written to the pass builder."); + throw new Exception($"Pass '{m_ExecutingPass.name}' is trying to write a texture on the command buffer that is not registered by its builder. Please indicate to the pass builder that the texture is written (UseTexture/CreateTransientTexture)."); } if (m_ExecutingPass.IsAttachment(h)) { - throw new Exception("Pass '" + m_ExecutingPass.name + "' is using a texture as a fragment attachment (SetRenderAttachment/SetRenderAttachmentDepth) but is also trying to bind it as regular texture. Please fix this pass. "); + throw new Exception($"Pass '{m_ExecutingPass.name}' is trying to bind a texture on the command buffer that is already set as a fragment attachment (SetRenderAttachment/SetRenderAttachmentDepth). A texture cannot be used as both in one pass, please fix its usage in the pass builder."); + } } } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/CommandBufferHelpers.cs b/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/CommandBufferHelpers.cs index 3db10803..3f7ddbc3 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/CommandBufferHelpers.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/CommandBufferHelpers.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.CompilerServices; using UnityEngine.VFX; namespace UnityEngine.Rendering @@ -17,6 +18,7 @@ namespace UnityEngine.Rendering /// /// The CommandBuffer the RasterCommandBuffer should record it's commands to. /// A RasterCommandBuffer that will record its commands to the given buffer. + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RasterCommandBuffer GetRasterCommandBuffer(CommandBuffer baseBuffer) { rasterCmd.m_WrappedCommandBuffer = baseBuffer; @@ -28,6 +30,7 @@ namespace UnityEngine.Rendering /// /// The CommandBuffer the RasterCommandBuffer should record it's commands to. /// A ComputeCommandBuffer that will record its commands to the given buffer. + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ComputeCommandBuffer GetComputeCommandBuffer(CommandBuffer baseBuffer) { computeCmd.m_WrappedCommandBuffer = baseBuffer; @@ -39,6 +42,7 @@ namespace UnityEngine.Rendering /// /// The CommandBuffer the UnsafeCommandBuffer should record its commands to. /// A UnsafeCommandBuffer that will record its commands to the given buffer. + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static UnsafeCommandBuffer GetUnsafeCommandBuffer(CommandBuffer baseBuffer) { unsafeCmd.m_WrappedCommandBuffer = baseBuffer; @@ -51,6 +55,7 @@ namespace UnityEngine.Rendering /// /// The UnsafeCommandBuffer you want to get the engine commandbuffer from. /// A CommandBuffer that will record its commands to the given buffer. + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static CommandBuffer GetNativeCommandBuffer(UnsafeCommandBuffer baseBuffer) { return baseBuffer.m_WrappedCommandBuffer; diff --git a/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/ComputeCommandBuffer.cs b/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/ComputeCommandBuffer.cs index 05a98a3c..f074eca5 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/ComputeCommandBuffer.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/ComputeCommandBuffer.cs @@ -763,6 +763,14 @@ namespace UnityEngine.Rendering /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DispatchRays.html) public void DispatchRays(RayTracingShader rayTracingShader, string rayGenName, uint width, uint height, uint depth, Camera camera) { m_WrappedCommandBuffer.DispatchRays(rayTracingShader, rayGenName, width, height, depth, camera); } + /// Wraps [DispatchRays](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DispatchRays.html) on a CommandBuffer. + /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DispatchRays.html) + /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DispatchRays.html) + /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DispatchRays.html) + /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DispatchRays.html) + /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DispatchRays.html) + public void DispatchRays(RayTracingShader rayTracingShader, string rayGenName, GraphicsBuffer argsBuffer, uint argsOffset, Camera camera) { m_WrappedCommandBuffer.DispatchRays(rayTracingShader, rayGenName, argsBuffer, argsOffset, camera); } + /// Wraps [CopyCounterValue](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.CopyCounterValue.html) on a CommandBuffer. /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.CopyCounterValue.html) /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.CopyCounterValue.html) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/IComputeCommandBuffer.cs b/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/IComputeCommandBuffer.cs index 061e776c..a3c70668 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/IComputeCommandBuffer.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/IComputeCommandBuffer.cs @@ -588,6 +588,14 @@ namespace UnityEngine.Rendering /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DispatchRays.html) public void DispatchRays(RayTracingShader rayTracingShader, string rayGenName, uint width, uint height, uint depth, Camera camera) ; + /// Wraps [DispatchRays](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DispatchRays.html) on a CommandBuffer. + /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DispatchRays.html) + /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DispatchRays.html) + /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DispatchRays.html) + /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DispatchRays.html) + /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DispatchRays.html) + public void DispatchRays(RayTracingShader rayTracingShader, string rayGenName, GraphicsBuffer argsBuffer, uint argsOffset, Camera camera) ; + /// Wraps [CopyCounterValue](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.CopyCounterValue.html) on a CommandBuffer. /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.CopyCounterValue.html) /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.CopyCounterValue.html) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/IRasterCommandBuffer.cs b/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/IRasterCommandBuffer.cs index 853393be..07fea04e 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/IRasterCommandBuffer.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/IRasterCommandBuffer.cs @@ -83,6 +83,15 @@ namespace UnityEngine.Rendering /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.ConfigureFoveatedRendering.html) public void ConfigureFoveatedRendering(IntPtr platformData) ; + /// Wraps [SetShadingRateFragmentSize](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.SetShadingRateFragmentSize.html) on a CommandBuffer. + /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.SetShadingRateFragmentSize.html) + public void SetShadingRateFragmentSize(ShadingRateFragmentSize shadingRateFragmentSize) ; + + /// Wraps [SetShadingRateCombiner](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.SetShadingRateCombiner.html) on a CommandBuffer. + /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.SetShadingRateCombiner.html) + /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.SetShadingRateCombiner.html) + public void SetShadingRateCombiner(ShadingRateCombinerStage stage, ShadingRateCombiner combiner) ; + /// Wraps [DrawMesh](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DrawMesh.html) on a CommandBuffer. /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DrawMesh.html) /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DrawMesh.html) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/RasterCommandBuffer.cs b/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/RasterCommandBuffer.cs index bba9327e..9adcb5aa 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/RasterCommandBuffer.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/RasterCommandBuffer.cs @@ -258,6 +258,15 @@ namespace UnityEngine.Rendering public void InvokeOnRenderObjectCallbacks() { m_WrappedCommandBuffer.InvokeOnRenderObjectCallbacks(); } + /// Wraps [SetShadingRateFragmentSize](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.SetShadingRateFragmentSize.html) on a CommandBuffer. + /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.SetShadingRateFragmentSize.html) + public void SetShadingRateFragmentSize(ShadingRateFragmentSize shadingRateFragmentSize) { m_WrappedCommandBuffer.SetShadingRateFragmentSize(shadingRateFragmentSize); } + + /// Wraps [SetShadingRateCombiner](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.SetShadingRateCombiner.html) on a CommandBuffer. + /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.SetShadingRateCombiner.html) + /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.SetShadingRateCombiner.html) + public void SetShadingRateCombiner(ShadingRateCombinerStage stage, ShadingRateCombiner combiner) { m_WrappedCommandBuffer.SetShadingRateCombiner(stage, combiner); } + /// Wraps [DrawMesh](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DrawMesh.html) on a CommandBuffer. /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DrawMesh.html) /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DrawMesh.html) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/UnsafeCommandBuffer.cs b/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/UnsafeCommandBuffer.cs index 6141d802..bbea01e9 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/UnsafeCommandBuffer.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/CommandBuffers/UnsafeCommandBuffer.cs @@ -598,6 +598,15 @@ namespace UnityEngine.Rendering public void InvokeOnRenderObjectCallbacks() { m_WrappedCommandBuffer.InvokeOnRenderObjectCallbacks(); } + /// Wraps [SetShadingRateFragmentSize](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.SetShadingRateFragmentSize.html) on a CommandBuffer. + /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.SetShadingRateFragmentSize.html) + public void SetShadingRateFragmentSize(ShadingRateFragmentSize shadingRateFragmentSize) { m_WrappedCommandBuffer.SetShadingRateFragmentSize(shadingRateFragmentSize); } + + /// Wraps [SetShadingRateCombiner](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.SetShadingRateCombiner.html) on a CommandBuffer. + /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.SetShadingRateCombiner.html) + /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.SetShadingRateCombiner.html) + public void SetShadingRateCombiner(ShadingRateCombinerStage stage, ShadingRateCombiner combiner) { m_WrappedCommandBuffer.SetShadingRateCombiner(stage, combiner); } + /// Wraps [SetComputeFloatParam](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.SetComputeFloatParam.html) on a CommandBuffer. /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.SetComputeFloatParam.html) /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.SetComputeFloatParam.html) @@ -1022,6 +1031,14 @@ namespace UnityEngine.Rendering /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DispatchRays.html) public void DispatchRays(RayTracingShader rayTracingShader, string rayGenName, uint width, uint height, uint depth, Camera camera) { m_WrappedCommandBuffer.DispatchRays(rayTracingShader, rayGenName, width, height, depth, camera); } + /// Wraps [DispatchRays](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DispatchRays.html) on a CommandBuffer. + /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DispatchRays.html) + /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DispatchRays.html) + /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DispatchRays.html) + /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DispatchRays.html) + /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DispatchRays.html) + public void DispatchRays(RayTracingShader rayTracingShader, string rayGenName, GraphicsBuffer argsBuffer, uint argsOffset, Camera camera) { m_WrappedCommandBuffer.DispatchRays(rayTracingShader, rayGenName, argsBuffer, argsOffset, camera); } + /// Wraps [DrawMesh](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DrawMesh.html) on a CommandBuffer. /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DrawMesh.html) /// [See CommandBuffer documentation](https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DrawMesh.html) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Common/ReloadAttribute.cs b/Packages/com.unity.render-pipelines.core/Runtime/Common/ReloadAttribute.cs index da035b25..6be37a21 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Common/ReloadAttribute.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Common/ReloadAttribute.cs @@ -3,11 +3,52 @@ using System; namespace UnityEngine.Rendering { /// - /// Attribute specifying information to reload with . This is only - /// used in the editor and doesn't have any effect at runtime. + /// The attribute specifies paths for loading or reloading resources and has no direct action. + /// Used with the to define where to load data for null fields. /// + /// + /// This attribute is designed for use in the Unity Editor and has no effect at runtime. + /// + /// have their own attribute to do this. + /// When using them, resource reloading is handled automatically by the engine and does not require calling ResourceReloader. + /// + /// While ResourceReloader was originally created for handling Scriptable Render Pipeline (SRP) resources, it has been replaced by . + /// The , and remain available for for user-defined assets. + /// /// /// + /// + /// This shows how to use the attribute in the expected scenario. This is particularly useful for content creators. + /// Adding a new field to a class that defines an asset results in null values for existing instances missing the field in their serialized data. Therefore, when a new field is added, a system for reloading null values may be necessary. + /// + ///using UnityEngine; + ///using UnityEditor; + /// + ///public class MyResourcesAsset : ScriptableObject + ///{ + /// [Reload("Shaders/Blit.shader")] + /// public Shader blit; + /// + /// // Added in version 2 + /// [Reload("Shaders/betterBlit.shader")] + /// public Shader betterBlit; + ///} + /// + ///public static class MyResourceHandler + ///{ + /// public static MyResourcesAsset GetAndReload() + /// { + /// var resources = AssetDatabase.LoadAssetAtPath<MyResourcesAsset>("MyResources.asset"); + /// + /// // Ensure that update of the data layout of MyResourcesAsset + /// // will not result in null value for asset already existing. + /// // (e.g.: added betterBlit in the case above) + /// ResourceReloader.ReloadAllNullIn(resources, "Packages/com.my-custom-package/"); + /// return resources; + /// } + ///} + /// + /// [AttributeUsage(AttributeTargets.Field)] public sealed class ReloadAttribute : Attribute { @@ -52,6 +93,23 @@ namespace UnityEngine.Rendering /// /// Search paths /// The lookup method + /// + /// This example demonstrates how to handle arrays with different resource paths. + /// + ///using UnityEngine; + /// + ///public class MyResourcesAsset : ScriptableObject + ///{ + /// [ResourcePaths(new[] + /// { + /// "Texture/FilmGrain/Thin.png", + /// "Texture/FilmGrain/Medium.png", + /// "Texture/FilmGrain/Large.png", + /// })] + /// public Texture[] filmGrains; + ///} + /// + /// public ReloadAttribute(string[] paths, Package package = Package.Root) { #if UNITY_EDITOR @@ -65,6 +123,18 @@ namespace UnityEngine.Rendering /// /// Search path /// The lookup method + /// + /// This example shows how to directly specify the path of an asset. + /// + ///using UnityEngine; + /// + ///public class MyResourcesAsset : ScriptableObject + ///{ + /// [Reload("Shaders/Blit.shader")] + /// public Shader blit; + ///} + /// + /// public ReloadAttribute(string path, Package package = Package.Root) : this(new[] { path }, package) { } @@ -77,6 +147,22 @@ namespace UnityEngine.Rendering /// The array start index (inclusive) /// The array end index (exclusive) /// The lookup method + /// + /// This example demonstrates handling arrays with resource paths that share a common format, differing only by an index. + /// + ///using UnityEngine; + /// + ///public class MyResourcesAsset : ScriptableObject + ///{ + /// // The following will seek for resources: + /// // - Texture/FilmGrain/Thin1.png + /// // - Texture/FilmGrain/Thin2.png + /// // - Texture/FilmGrain/Thin3.png + /// [ResourcePaths("Texture/FilmGrain/Thin{0}.png", 1, 4)] + /// public Texture[] thinGrains; + ///} + /// + /// public ReloadAttribute(string pathFormat, int rangeMin, int rangeMax, Package package = Package.Root) { diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Common/ReloadGroupAttribute.cs b/Packages/com.unity.render-pipelines.core/Runtime/Common/ReloadGroupAttribute.cs index 98861e1b..65c9235b 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Common/ReloadGroupAttribute.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Common/ReloadGroupAttribute.cs @@ -1,14 +1,57 @@ using System; +using UnityEditor; +using static UnityEngine.Rendering.DebugUI.Table; namespace UnityEngine.Rendering { /// - /// Attribute specifying that it contains element that should be reloaded. - /// If the instance of the class is null, the system will try to recreate - /// it with the default constructor. - /// Be sure classes using it have default constructor! + /// Attribute specifying that fields of this type should be inspected in depth by the . + /// If the associated class instance is null, the system attempts to recreate it using its default constructor. /// + /// + /// Make sure classes using it have a default constructor! + /// + /// /// + /// + /// This shows how to use the attribute in the expected scenario. This is particularly useful for content creators. + /// Adding a new field to a class that defines an asset results in null values for existing instances missing the field in their serialized data. Therefore, when a new field is added, a system for reloading null values may be necessary. + /// + ///using UnityEngine; + ///using UnityEditor; + /// + ///[ReloadGroup] + ///public class MyShaders + ///{ + /// [Reload("Shaders/Blit.shader")] + /// public Shader blit; + ///} + /// + ///public class MyResourcesAsset : ScriptableObject + ///{ + /// // Object used for contextualizing would resolve to be null in already existing + /// // instance of MyResourcesAsset that already exists. + /// public MyShaders shaders; + /// + /// [Reload("Textures/BayerMatrix.png")] + /// public Texture2D bayerMatrixTex; + ///} + /// + ///public static class MyResourceHandler + ///{ + /// public static MyResourcesAsset GetAndReload() + /// { + /// var resources = AssetDatabase.LoadAssetAtPath<MyResourcesAsset>("MyResources.asset"); + /// + /// // Ensure that update of the data layout of MyResourcesAsset + /// // will not result in null value for asset already existing. + /// // (e.g.: adding new field in MyResourcesAsset or MyShaders classes) + /// ResourceReloader.ReloadAllNullIn(resources, "Packages/com.my-custom-package/"); + /// return resources; + /// } + ///} + /// + /// [AttributeUsage(AttributeTargets.Class)] public sealed class ReloadGroupAttribute : Attribute { } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugManager.cs b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugManager.cs index 846edd43..b90eed0d 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugManager.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugManager.cs @@ -11,20 +11,70 @@ namespace UnityEngine.Rendering using UnityObject = UnityEngine.Object; /// - /// IDebugData interface. + /// Implementing this interface enables integration with Unity's Rendering debugger, providing a way to manage and control the state of debug data. /// + /// + /// + /// Use the `IDebugData` interface to register custom debug data. You can reset the data when necessary, which makes it suitable for debugging scenarios + /// where you need to clear or reset specific data. For example, when the application state changes or during gameplay session resets, + /// or when the **Reset** button is selected in the **Rendering Debugger** window in the Editor or at runtime. + /// + /// + /// + /// + /// public class MyDebugData : IDebugData + /// { + /// private int _value; + /// + /// /// Constructor of the debug data that will receive the reset callback + /// public MyDebugData() + /// { + /// _value = 0; + /// } + /// + /// public Action GetReset() + /// { + /// /// Specify the callback when the reset operation is being called. + /// return () => _value = 0; // Resets the value to 0 + /// } + /// } + /// + /// public interface IDebugData { - /// Get the reset callback for this DebugData + /// Provides the reset callback for resetting the debug data. /// The reset callback Action GetReset(); - //Action GetLoad(); - //Action GetSave(); } /// - /// Manager class for the Debug Window. + /// The class provides a centralized manager for handling Unity's Rendering debugger. /// + /// + /// The DebugManager allows you to register, unregister, and manipulate debug data, panels, and widgets for runtime or editor debugging. + /// - Register and manage debug panels and widgets. + /// - Refresh and reset the debug UI based on runtime changes. + /// - Provides a global instance for easy access from anywhere in the codebase. + /// + /// + /// + /// + /// { + /// /// Create a list to store the new DebugUI widgets + /// /// by creating different DebugUI.Values that display a label with a value. + /// var list = new System.Collections.Generic.List<DebugUI.Widget> + /// { + /// new DebugUI.Value { displayName = "Lighting Intensity", getter = () => 1.0f, setter = value => Debug.Log($"Lighting Intensity set to {value}") }, + /// new DebugUI.Value { displayName = "Light Color", getter = () => Color.white, setter = value => Debug.Log($"Light Color set to {value}") } + /// }; + /// var items = list.ToArray(); + /// + /// /// Obtain the panel from the DebugManager instance, and add the Widgets that we want to display there. + /// var panel = DebugManager.instance.GetPanel("Lighting", true); + /// panel.children.AddRange(items); + /// } + /// + /// public sealed partial class DebugManager { static readonly Lazy s_Instance = new Lazy(() => new DebugManager()); diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugUI.Fields.cs b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugUI.Fields.cs index db504af0..7c6c0495 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugUI.Fields.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugUI.Fields.cs @@ -242,6 +242,134 @@ namespace UnityEngine.Rendering } } + /// + /// Field that displays + /// + public class RenderingLayerField : Field, IContainer + { + static readonly NameAndTooltip s_RenderingLayerColors = new() + { + name = "Layers Color", + tooltip = "Select the display color for each Rendering Layer" + }; + + private string[] m_RenderingLayersNames = Array.Empty(); + + private int m_DefinedRenderingLayersCount = -1; + + private int maxRenderingLayerCount + { + get + { +#if UNITY_EDITOR + if (UnityEditor.Rendering.EditorGraphicsSettings. + TryGetFirstRenderPipelineSettingsFromInterface(out var settings)) + return Mathf.Min(settings.maxSupportedRenderingLayers, RenderingLayerMask.GetRenderingLayerCount()); +#endif + + return RenderingLayerMask.GetRenderingLayerCount(); + } + } + + private void Resize() + { + m_DefinedRenderingLayersCount = RenderingLayerMask.GetDefinedRenderingLayerCount(); + + // Fill layer names + m_RenderingLayersNames = new string[maxRenderingLayerCount]; + for (int i = 0; i < maxRenderingLayerCount; i++) + { + var definedLayerName = RenderingLayerMask.RenderingLayerToName(i); + if (string.IsNullOrEmpty(definedLayerName)) + definedLayerName = $"Unused Rendering Layer {i}"; + m_RenderingLayersNames[i] = definedLayerName; + } + + // Foldout + Color for each layer + m_RenderingLayersColors.Clear(); + var layersColor = new DebugUI.Foldout() + { + nameAndTooltip = s_RenderingLayerColors, + flags = Flags.EditorOnly, + parent = this, + }; + m_RenderingLayersColors.Add(layersColor); + + for (int i = 0; i < m_RenderingLayersNames.Length; i++) + { + var index = i; // capture the variable for the color field index + layersColor.children.Add(new DebugUI.ColorField + { + displayName = m_RenderingLayersNames[index], + getter = () => + { + Assert.IsNotNull(getRenderingLayerColor, "Please specify a method for getting the rendering layer color"); + return getRenderingLayerColor(index); + }, + setter = value => + { + Assert.IsNotNull(setRenderingLayerColor, "Please specify a method for setting the rendering layer color"); + setRenderingLayerColor(value, index); + } + }); + } + + GenerateQueryPath(); + } + + /// + /// Obtains the list of the available rendering layer names + /// + public string[] renderingLayersNames + { + get + { + if (m_DefinedRenderingLayersCount != RenderingLayerMask.GetDefinedRenderingLayerCount()) + { + Resize(); + } + + return m_RenderingLayersNames; + } + } + + private ObservableList m_RenderingLayersColors = new ObservableList(); + + /// + /// Gets the list of widgets representing the rendering layer colors. + /// + public ObservableList children + { + get + { + if (m_DefinedRenderingLayersCount != RenderingLayerMask.GetDefinedRenderingLayerCount()) + { + Resize(); + } + + return m_RenderingLayersColors; + } + } + + /// + /// Obtains the color in a given index + /// + public Func getRenderingLayerColor { get; set; } + /// + /// Sets the color for a given index + /// + public Action setRenderingLayerColor { get; set; } + + internal override void GenerateQueryPath() + { + base.GenerateQueryPath(); + + int numChildren = children.Count; + for (int i = 0; i < numChildren; i++) + children[i].GenerateQueryPath(); + } + } + /// /// Generic that stores enumNames and enumValues /// @@ -446,47 +574,6 @@ namespace UnityEngine.Rendering } } - /// - /// Maskfield enumeration field. - /// - public class MaskField : EnumField - { - /// - /// Fills the enum using the provided names - /// - /// names to fill the enum - public void Fill(string[] names) - { - using (ListPool.Get(out var tmpNames)) - using (ListPool.Get(out var tmpValues)) - { - for (int i=0; i<(names.Length); ++i) - { - tmpNames.Add(new GUIContent(names[i])); - tmpValues.Add(i); - } - enumNames = tmpNames.ToArray(); - enumValues = tmpValues.ToArray(); - } - } - - /// - /// Assigns a value to the maskfield. - /// - /// value for the maskfield - public override void SetValue(uint value) - { - Assert.IsNotNull(setter); - var validValue = ValidateValue(value); - - if (!validValue.Equals(getter())) - { - setter(validValue); - onValueChanged?.Invoke(this, validValue); - } - } - } - /// /// Color field. /// diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugUI.cs b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugUI.cs index 862f90c7..ecd19161 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugUI.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugUI.cs @@ -5,8 +5,68 @@ using UnityEngine.Assertions; namespace UnityEngine.Rendering { /// - /// Debug UI Class + /// The `DebugUI` class defines a collection of debug UI components that are useful for debugging and profiling Rendering features /// + /// + /// Widgets can be added to the UI, customized, and manipulated at runtime or during editor sessions. The class supports various + /// widget types, including buttons, read-only value fields, and progress bars. It also provides mechanisms for organizing these + /// widgets into containers. Each widget has a set of flags to control its visibility and behavior depending on whether it is + /// used in the editor or at runtime. The widgets can also contain callbacks for conditional visibility at runtime. + /// Important Notes: + /// - Widgets can be nested inside containers, allowing for organized groupings of debug UI elements. + /// - Widgets may be runtime-only, editor-only, or both, allowing them to behave differently depending on the application's + /// state (e.g., whether it is in the editor or playing at runtime). + /// - `DebugUI` also includes helper methods for widget initialization, such as compact initialization using the `NameAndTooltip` struct. + /// + /// This API lets you do the following: + /// - Specify widget behavior such as "EditorOnly", "RuntimeOnly", "EditorForceUpdate", and "FrequentlyUsed". + /// - Show dynamic data with optional formatting. + /// - Specify delegate functions to show or hide widgets + /// + /// Related Resources: + /// - [Debug UI Overview](https://docs.unity3d.com/6000.0/Documentation/Manual/urp/features/rendering-debugger.html) + /// - [Rendering Debugger Controls](https://docs.unity3d.com/6000.0/Documentation/Manual/urp/features/rendering-debugger-add-controls.html). + /// - [Using Rendering Debugger](https://docs.unity.cn/Packages/com.unity.render-pipelines.high-definition@16.0/manual/use-the-rendering-debugger.html). + /// + /// + /// + /// using UnityEngine; + /// using UnityEngine.Rendering; + /// + /// public class DebugUIExample : MonoBehaviour + /// { + /// private DebugUI.Button button; + /// private DebugUI.Value timeValue; + /// + /// void Start() + /// { + /// // Create a button widget that logs a message when you select it + /// button = new DebugUI.Button + /// { + /// displayName = "Log Message Button", + /// action = () => Debug.Log("Button selected"), + /// isHiddenCallback = () => true, + /// }; + /// + /// // Create a value widget that displays the current time + /// timeValue = new DebugUI.Value + /// { + /// // Set the display label + /// displayName = "Current Time", + /// + /// // Set the format for the time + /// getter = () => System.DateTime.Now.ToString("HH:mm:ss"), + /// + /// // Set the value to refresh every second + /// refreshRate = 1f + /// }; + /// + /// // Add widgets to the UI (assuming a panel or container exists) + /// // .... + /// } + /// } + /// + /// public partial class DebugUI { /// diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/Prefabs/Resources/DebugUICanvas.prefab b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/Prefabs/Resources/DebugUICanvas.prefab index e6f951c9..37aaf8c0 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/Prefabs/Resources/DebugUICanvas.prefab +++ b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/Prefabs/Resources/DebugUICanvas.prefab @@ -114,7 +114,8 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 76db615e524a19c4990482d75a475543, type: 3} m_Name: m_EditorClassIdentifier: - panelPrefab: {fileID: 224481716535368988, guid: daa46a58178a6ad41ae1ddc2dc7f856d, type: 3} + panelPrefab: {fileID: 224481716535368988, guid: daa46a58178a6ad41ae1ddc2dc7f856d, + type: 3} prefabs: - type: UnityEngine.Rendering.DebugUI+Value, Unity.RenderPipelines.Core.Runtime, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null @@ -163,13 +164,15 @@ MonoBehaviour: prefab: {fileID: 224284813447651300, guid: 38a07789c9e87004dad98c2909f58369, type: 3} - type: UnityEngine.Rendering.DebugUI+BitField, Unity.RenderPipelines.Core.Runtime, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null - prefab: {fileID: 5833802642077810669, guid: 7c78b588b2e1f7c4a86ca4a985cf6e4a, type: 3} + prefab: {fileID: 5833802642077810669, guid: 7c78b588b2e1f7c4a86ca4a985cf6e4a, + type: 3} - type: UnityEngine.Rendering.DebugUI+HistoryBoolField, Unity.RenderPipelines.Core.Runtime, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null prefab: {fileID: 108402283379224504, guid: 5088d0220f0c4df439cf06c5c270eacb, type: 3} - type: UnityEngine.Rendering.DebugUI+HistoryEnumField, Unity.RenderPipelines.Core.Runtime, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null - prefab: {fileID: 8535926254376877601, guid: b2da6b27df236b144b3516ed8e7d36ac, type: 3} + prefab: {fileID: 8535926254376877601, guid: b2da6b27df236b144b3516ed8e7d36ac, + type: 3} - type: UnityEngine.Rendering.DebugUI+Table, Unity.RenderPipelines.Core.Runtime, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null prefab: {fileID: 224284813447651300, guid: 38a07789c9e87004dad98c2909f58369, type: 3} @@ -193,7 +196,12 @@ MonoBehaviour: prefab: {fileID: 224224135738715566, guid: ad83bc56407925d44a77a5bd01cd6783, type: 3} - type: UnityEngine.Rendering.DebugUI+ObjectPopupField, Unity.RenderPipelines.Core.Runtime, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null - prefab: {fileID: 4224455051203994714, guid: 48fb043c850cadc4a883b53785e14c6e, type: 3} + prefab: {fileID: 4224455051203994714, guid: 48fb043c850cadc4a883b53785e14c6e, + type: 3} - type: UnityEngine.Rendering.DebugUI+RuntimeDebugShadersMessageBox, Unity.RenderPipelines.Core.Runtime, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null prefab: {fileID: 224053494956566916, guid: 10a25524b0986f9488b430e2829bbbe8, type: 3} + - type: UnityEngine.Rendering.DebugUI+RenderingLayerField, Unity.RenderPipelines.Core.Runtime, + Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + prefab: {fileID: 5833802642077810669, guid: 928d1ca04af80c84e8d5dabc18095d79, + type: 3} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/Prefabs/Scripts/DebugUIHandlerRenderingLayerField.cs b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/Prefabs/Scripts/DebugUIHandlerRenderingLayerField.cs new file mode 100644 index 00000000..7516c581 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/Prefabs/Scripts/DebugUIHandlerRenderingLayerField.cs @@ -0,0 +1,152 @@ +using System.Collections.Generic; +using UnityEngine.Assertions; +using UnityEngine.UI; + +namespace UnityEngine.Rendering.UI +{ + /// + /// DebugUIHandler for RenderingLayerField widget. + /// + public class DebugUIHandlerRenderingLayerField : DebugUIHandlerWidget + { + /// Name of the widget. + public Text nameLabel; + /// Value toggle. + public UIFoldout valueToggle; + + /// Toggles for the RenderingLayerField. + public List toggles; + + DebugUI.RenderingLayerField m_Field; + DebugUIHandlerContainer m_Container; + + internal override void SetWidget(DebugUI.Widget widget) + { + base.SetWidget(widget); + m_Field = CastWidget(); + m_Container = GetComponent(); + nameLabel.text = m_Field.displayName; + + int toggleIndex = 0; + var count = m_Field.renderingLayersNames.Length - 1; + foreach (var layerName in m_Field.renderingLayersNames) + { + if (toggleIndex >= toggles.Count) + continue; + + var toggle = toggles[toggleIndex]; + toggle.getter = GetValue; + toggle.setter = SetValue; + toggle.nextUIHandler = toggleIndex < count ? toggles[toggleIndex + 1] : null; + toggle.previousUIHandler = toggleIndex > 0 ? toggles[toggleIndex - 1] : null; + toggle.parentUIHandler = this; + toggle.index = toggleIndex; + toggle.nameLabel.text = layerName; + toggle.Init(); + toggleIndex++; + } + + // Destroy the remaining toggles outside of the range of the displayed enum. + for (; toggleIndex < toggles.Count; ++toggleIndex) + { + CoreUtils.Destroy(toggles[toggleIndex].gameObject); + toggles[toggleIndex] = null; + } + } + + bool GetValue(int index) + { + var mask = m_Field.GetValue(); + return (mask & (1u << index)) != 0; + } + + void SetValue(int index, bool value) + { + var mask = m_Field.GetValue(); + if (value) + mask |= 1 << index; + else + mask &= ~(1 << index); + m_Field.SetValue(mask); + } + + /// + /// OnSelection implementation. + /// + /// True if the selection wrapped around. + /// Previous widget. + /// True if the selection is allowed. + public override bool OnSelection(bool fromNext, DebugUIHandlerWidget previous) + { + if (fromNext || valueToggle.isOn == false) + { + nameLabel.color = colorSelected; + } + else if (valueToggle.isOn) + { + if (m_Container.IsDirectChild(previous)) + { + nameLabel.color = colorSelected; + } + else + { + var lastItem = m_Container.GetLastItem(); + DebugManager.instance.ChangeSelection(lastItem, false); + } + } + + return true; + } + + /// + /// OnDeselection implementation. + /// + public override void OnDeselection() + { + nameLabel.color = colorDefault; + } + + /// + /// OnIncrement implementation. + /// + /// True if incrementing fast. + public override void OnIncrement(bool fast) + { + valueToggle.isOn = true; + } + + /// + /// OnDecrement implementation. + /// + /// Trye if decrementing fast. + public override void OnDecrement(bool fast) + { + valueToggle.isOn = false; + } + + /// + /// OnAction implementation. + /// + public override void OnAction() + { + valueToggle.isOn = !valueToggle.isOn; + } + + /// + /// Next implementation. + /// + /// Next widget UI handler, parent if there is none. + public override DebugUIHandlerWidget Next() + { + if (!valueToggle.isOn || m_Container == null) + return base.Next(); + + var firstChild = m_Container.GetFirstItem(); + + if (firstChild == null) + return base.Next(); + + return firstChild; + } + } +} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/Prefabs/Scripts/DebugUIHandlerRenderingLayerField.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/Prefabs/Scripts/DebugUIHandlerRenderingLayerField.cs.meta new file mode 100644 index 00000000..600e05f1 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/Prefabs/Scripts/DebugUIHandlerRenderingLayerField.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ea44ef5968bb44a48b7855c36dae02c4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/Prefabs/Widgets/DebugUIHandlerRenderingLayerField.prefab b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/Prefabs/Widgets/DebugUIHandlerRenderingLayerField.prefab new file mode 100644 index 00000000..f75ebd75 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/Prefabs/Widgets/DebugUIHandlerRenderingLayerField.prefab @@ -0,0 +1,12455 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &74822769193199464 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1958888752443160004} + - component: {fileID: 6679106303399258962} + - component: {fileID: 5050348896946348867} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1958888752443160004 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 74822769193199464} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 8356148564785885022} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &6679106303399258962 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 74822769193199464} + m_CullTransparentMesh: 0 +--- !u!114 &5050348896946348867 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 74822769193199464} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &198308496328705422 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7290923337117366102} + - component: {fileID: 8069964854434385667} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &7290923337117366102 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 198308496328705422} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 6075760728334120815} + m_Father: {fileID: 3747482945603663964} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &8069964854434385667 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 198308496328705422} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 2700416459006292345} + toggleTransition: 1 + graphic: {fileID: 5802453145572142467} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &210585996295577721 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5983516410954562191} + - component: {fileID: 2707655605294999502} + - component: {fileID: 4746959147978535488} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5983516410954562191 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 210585996295577721} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 5833546809406971014} + m_Father: {fileID: 3807659439045052884} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &2707655605294999502 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 210585996295577721} + m_CullTransparentMesh: 0 +--- !u!114 &4746959147978535488 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 210585996295577721} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &235513122320341711 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1483444589931372990} + - component: {fileID: 1448067562088378152} + - component: {fileID: 3439658608168239967} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1483444589931372990 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 235513122320341711} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 3626888406440555363} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &1448067562088378152 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 235513122320341711} + m_CullTransparentMesh: 0 +--- !u!114 &3439658608168239967 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 235513122320341711} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &246970216348187374 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8356148564785885022} + - component: {fileID: 2749009075916353680} + - component: {fileID: 5002250424606232238} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8356148564785885022 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 246970216348187374} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1958888752443160004} + m_Father: {fileID: 1670263807047702912} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &2749009075916353680 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 246970216348187374} + m_CullTransparentMesh: 0 +--- !u!114 &5002250424606232238 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 246970216348187374} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &273425814977816694 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4976284874825399851} + - component: {fileID: 3545676079014388947} + - component: {fileID: 1546348349704106882} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &4976284874825399851 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 273425814977816694} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1425864700568453755} + m_Father: {fileID: 7432866224741430686} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &3545676079014388947 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 273425814977816694} + m_CullTransparentMesh: 0 +--- !u!114 &1546348349704106882 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 273425814977816694} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &292985107547532810 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1425864700568453755} + - component: {fileID: 8941389240832981586} + - component: {fileID: 4957790091271580714} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1425864700568453755 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 292985107547532810} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 4976284874825399851} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &8941389240832981586 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 292985107547532810} + m_CullTransparentMesh: 0 +--- !u!114 &4957790091271580714 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 292985107547532810} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &460735431326532047 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1904428486749382773} + - component: {fileID: 9003751344240168844} + m_Layer: 5 + m_Name: DebugUI Toggle 22 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1904428486749382773 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 460735431326532047} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3141594381208770657} + - {fileID: 6353858620915095577} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &9003751344240168844 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 460735431326532047} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 2284996109865033884} + valueToggle: {fileID: 3456792024118400511} + checkmarkImage: {fileID: 9060318935775576703} +--- !u!1 &600368409436158652 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8557170861926017448} + - component: {fileID: 930171243308949994} + - component: {fileID: 3955374361418223195} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8557170861926017448 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 600368409436158652} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 5001324386341305675} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &930171243308949994 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 600368409436158652} + m_CullTransparentMesh: 0 +--- !u!114 &3955374361418223195 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 600368409436158652} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &789524568955009124 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4787045164725599468} + - component: {fileID: 5387021893471557754} + - component: {fileID: 8019534688361173590} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &4787045164725599468 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 789524568955009124} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 7597631521775465986} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &5387021893471557754 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 789524568955009124} + m_CullTransparentMesh: 0 +--- !u!114 &8019534688361173590 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 789524568955009124} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &904359353859202414 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3769025729730033565} + - component: {fileID: 8271676633369491976} + - component: {fileID: 7083163093166539205} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3769025729730033565 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 904359353859202414} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1143708577816669107} + m_Father: {fileID: 7380185792925235767} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &8271676633369491976 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 904359353859202414} + m_CullTransparentMesh: 0 +--- !u!114 &7083163093166539205 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 904359353859202414} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &1255721778690630820 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1850453015581534804} + - component: {fileID: 5989295061535193187} + - component: {fileID: 6701717425365996163} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1850453015581534804 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1255721778690630820} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 8643262011863657182} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &5989295061535193187 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1255721778690630820} + m_CullTransparentMesh: 0 +--- !u!114 &6701717425365996163 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1255721778690630820} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &1257738450584450071 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2748700044399894202} + - component: {fileID: 4493443016418537037} + - component: {fileID: 3530406180247266972} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2748700044399894202 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1257738450584450071} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 3002137670299042156} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &4493443016418537037 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1257738450584450071} + m_CullTransparentMesh: 0 +--- !u!114 &3530406180247266972 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1257738450584450071} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &1337984993859421813 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3160084798452651386} + - component: {fileID: 485236091688378859} + - component: {fileID: 8209430775002992777} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3160084798452651386 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1337984993859421813} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 428045328721135137} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &485236091688378859 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1337984993859421813} + m_CullTransparentMesh: 0 +--- !u!114 &8209430775002992777 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1337984993859421813} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &1377925216867464122 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2314514058934025060} + - component: {fileID: 9179246579421883796} + - component: {fileID: 1050381230042893636} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2314514058934025060 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1377925216867464122} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 4199920854957040706} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &9179246579421883796 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1377925216867464122} + m_CullTransparentMesh: 0 +--- !u!114 &1050381230042893636 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1377925216867464122} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &1383658768669401416 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2590341387017464519} + - component: {fileID: 7090020572617868160} + m_Layer: 5 + m_Name: DebugUI Toggle 28 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2590341387017464519 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1383658768669401416} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3916575158388844691} + - {fileID: 1698301253758164178} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &7090020572617868160 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1383658768669401416} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 1736220021016928009} + valueToggle: {fileID: 5352515433852677119} + checkmarkImage: {fileID: 4818644045601654872} +--- !u!1 &1401422664981114516 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1994050603111272669} + - component: {fileID: 7150958925909432444} + - component: {fileID: 1133652755111259454} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1994050603111272669 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1401422664981114516} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 8625410696850161855} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &7150958925909432444 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1401422664981114516} + m_CullTransparentMesh: 0 +--- !u!114 &1133652755111259454 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1401422664981114516} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &1408560429885557106 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6386133981247227809} + - component: {fileID: 2451434126944430322} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6386133981247227809 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1408560429885557106} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 8351659506645333476} + m_Father: {fileID: 3954105840611946110} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2451434126944430322 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1408560429885557106} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 4755971768771506769} + toggleTransition: 1 + graphic: {fileID: 8599129644269611419} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &1454308972692154975 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5154472422670747833} + - component: {fileID: 4353645496875133955} + - component: {fileID: 4818644045601654872} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5154472422670747833 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1454308972692154975} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1185291142442617761} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &4353645496875133955 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1454308972692154975} + m_CullTransparentMesh: 0 +--- !u!114 &4818644045601654872 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1454308972692154975} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &1486507231905896618 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 958809557181456115} + - component: {fileID: 5378385216208721069} + - component: {fileID: 5432711013158779192} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &958809557181456115 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1486507231905896618} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 3803781275079323733} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &5378385216208721069 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1486507231905896618} + m_CullTransparentMesh: 0 +--- !u!114 &5432711013158779192 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1486507231905896618} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &1512534620145188899 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6667855967321245346} + - component: {fileID: 5904973363994399480} + - component: {fileID: 164768344116107986} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6667855967321245346 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1512534620145188899} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1071186331609494896} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &5904973363994399480 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1512534620145188899} + m_CullTransparentMesh: 0 +--- !u!114 &164768344116107986 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1512534620145188899} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &1519841233505932146 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2075241552360254502} + - component: {fileID: 8562085848866449756} + m_Layer: 5 + m_Name: DebugUI Toggle 17 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2075241552360254502 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1519841233505932146} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 8235471640864529742} + - {fileID: 7432866224741430686} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &8562085848866449756 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1519841233505932146} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 7954571544824238787} + valueToggle: {fileID: 2405871519029774392} + checkmarkImage: {fileID: 4957790091271580714} +--- !u!1 &1805931634763419227 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8429224242260680381} + - component: {fileID: 3660393548531142813} + - component: {fileID: 5654365300560118476} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8429224242260680381 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1805931634763419227} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2759500403880505928} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &3660393548531142813 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1805931634763419227} + m_CullTransparentMesh: 0 +--- !u!114 &5654365300560118476 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1805931634763419227} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &1841768535940055272 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1237372008052714286} + - component: {fileID: 8189617005992343066} + - component: {fileID: 4128875111787400469} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1237372008052714286 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1841768535940055272} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 3954105840611946110} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &8189617005992343066 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1841768535940055272} + m_CullTransparentMesh: 0 +--- !u!114 &4128875111787400469 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1841768535940055272} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &1892104052310373591 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 800688055469850145} + - component: {fileID: 6391126850643013647} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &800688055469850145 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1892104052310373591} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 5283382075449741548} + m_Father: {fileID: 8643262011863657182} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &6391126850643013647 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1892104052310373591} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 3792906712613004423} + toggleTransition: 1 + graphic: {fileID: 5356581191142619947} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &1912957997510059643 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1914011185745597247} + - component: {fileID: 3243688633497074117} + - component: {fileID: 4324276223801582212} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1914011185745597247 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1912957997510059643} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 4880028377363535173} + m_Father: {fileID: 9157722414083985858} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &3243688633497074117 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1912957997510059643} + m_CullTransparentMesh: 0 +--- !u!114 &4324276223801582212 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1912957997510059643} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &1938792781808105035 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5369190403499271288} + - component: {fileID: 2958440384749385630} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5369190403499271288 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1938792781808105035} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 7956694805050852688} + m_Father: {fileID: 7816446078609134115} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2958440384749385630 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1938792781808105035} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 4189231263243852722} + toggleTransition: 1 + graphic: {fileID: 9162012530475593324} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &1971118125168773045 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1698301253758164178} + - component: {fileID: 5352515433852677119} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1698301253758164178 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1971118125168773045} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1185291142442617761} + m_Father: {fileID: 2590341387017464519} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &5352515433852677119 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1971118125168773045} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 6797895232316676442} + toggleTransition: 1 + graphic: {fileID: 4818644045601654872} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &2067454400387581445 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3747482945603663964} + - component: {fileID: 6537490383020632609} + m_Layer: 5 + m_Name: DebugUI Toggle 13 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3747482945603663964 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2067454400387581445} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 8233626477581283555} + - {fileID: 7290923337117366102} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &6537490383020632609 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2067454400387581445} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 4427599279144680947} + valueToggle: {fileID: 8069964854434385667} + checkmarkImage: {fileID: 5802453145572142467} +--- !u!1 &2067722791479922788 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5647913056700805355} + - component: {fileID: 5078048544661078628} + - component: {fileID: 7875341202550150707} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5647913056700805355 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2067722791479922788} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2652713077043660966} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &5078048544661078628 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2067722791479922788} + m_CullTransparentMesh: 0 +--- !u!114 &7875341202550150707 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2067722791479922788} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &2073291026924378913 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1189216680378437486} + - component: {fileID: 1217054267639125318} + - component: {fileID: 7495417191435204136} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1189216680378437486 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2073291026924378913} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1544810510454982857} + m_Father: {fileID: 7954316942891746433} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &1217054267639125318 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2073291026924378913} + m_CullTransparentMesh: 0 +--- !u!114 &7495417191435204136 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2073291026924378913} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &2086480278583842799 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2451940126815751474} + - component: {fileID: 6087187633097608169} + m_Layer: 5 + m_Name: DebugUI Toggle 24 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2451940126815751474 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2086480278583842799} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 6697593953020889603} + - {fileID: 4086772113621016208} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &6087187633097608169 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2086480278583842799} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 4846740409493721984} + valueToggle: {fileID: 970757129289726534} + checkmarkImage: {fileID: 6029727342443417148} +--- !u!1 &2110357719490854994 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3612299115344139013} + - component: {fileID: 5687218474045752718} + - component: {fileID: 5811605465015081675} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3612299115344139013 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2110357719490854994} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 8558628789733519512} + m_Father: {fileID: 8413373871896021635} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &5687218474045752718 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2110357719490854994} + m_CullTransparentMesh: 0 +--- !u!114 &5811605465015081675 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2110357719490854994} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &2129180063755082928 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3803781275079323733} + - component: {fileID: 7493564373867626443} + m_Layer: 5 + m_Name: DebugUI Toggle 6 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3803781275079323733 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2129180063755082928} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 958809557181456115} + - {fileID: 6644699419958076397} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &7493564373867626443 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2129180063755082928} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 5432711013158779192} + valueToggle: {fileID: 147858285169255864} + checkmarkImage: {fileID: 4127528762848208377} +--- !u!1 &2207389410027094222 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3737111891372312802} + - component: {fileID: 2037913533698422136} + - component: {fileID: 1701711077839953596} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3737111891372312802 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2207389410027094222} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 319426443455914023} + m_Father: {fileID: 906931124344334618} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &2037913533698422136 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2207389410027094222} + m_CullTransparentMesh: 0 +--- !u!114 &1701711077839953596 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2207389410027094222} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &2210364538776165098 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5076517029326469307} + - component: {fileID: 953415876542653751} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5076517029326469307 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2210364538776165098} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 428045328721135137} + m_Father: {fileID: 5081734458789119777} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &953415876542653751 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2210364538776165098} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 8813570217460717391} + toggleTransition: 1 + graphic: {fileID: 8209430775002992777} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &2260129634959441134 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 791520587265625091} + - component: {fileID: 4607543735610172353} + - component: {fileID: 5356581191142619947} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &791520587265625091 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2260129634959441134} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 5283382075449741548} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &4607543735610172353 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2260129634959441134} + m_CullTransparentMesh: 0 +--- !u!114 &5356581191142619947 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2260129634959441134} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &2312190080207680053 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5283382075449741548} + - component: {fileID: 6899205371889111843} + - component: {fileID: 3792906712613004423} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5283382075449741548 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2312190080207680053} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 791520587265625091} + m_Father: {fileID: 800688055469850145} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &6899205371889111843 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2312190080207680053} + m_CullTransparentMesh: 0 +--- !u!114 &3792906712613004423 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2312190080207680053} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &2320641401228566767 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7388519436634992578} + - component: {fileID: 1196526696592632852} + - component: {fileID: 5067439095481778869} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &7388519436634992578 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2320641401228566767} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2069466459521621409} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &1196526696592632852 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2320641401228566767} + m_CullTransparentMesh: 0 +--- !u!114 &5067439095481778869 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2320641401228566767} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &2405211379384313265 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7361462984932131187} + - component: {fileID: 3269991560789098383} + - component: {fileID: 8683242940989415304} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &7361462984932131187 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2405211379384313265} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3110659917968075140} + m_Father: {fileID: 1763134690699169346} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &3269991560789098383 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2405211379384313265} + m_CullTransparentMesh: 0 +--- !u!114 &8683242940989415304 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2405211379384313265} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &2472766322376748401 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6546067790357044605} + - component: {fileID: 3251042231684009560} + - component: {fileID: 4755439529892379193} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6546067790357044605 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2472766322376748401} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 4894700207822734448} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &3251042231684009560 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2472766322376748401} + m_CullTransparentMesh: 0 +--- !u!114 &4755439529892379193 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2472766322376748401} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &2528115446453954515 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7508261725234730334} + - component: {fileID: 4251434431392806875} + - component: {fileID: 6982057837895959611} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &7508261725234730334 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2528115446453954515} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 8995314096000718896} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &4251434431392806875 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2528115446453954515} + m_CullTransparentMesh: 0 +--- !u!114 &6982057837895959611 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2528115446453954515} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &2656729411710343347 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1670263807047702912} + - component: {fileID: 1441446908436994080} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1670263807047702912 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2656729411710343347} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 8356148564785885022} + m_Father: {fileID: 4761151331139786934} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1441446908436994080 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2656729411710343347} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 5002250424606232238} + toggleTransition: 1 + graphic: {fileID: 5050348896946348867} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &2735537141019569035 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1064151588746797128} + - component: {fileID: 5415619581143717901} + - component: {fileID: 8599129644269611419} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1064151588746797128 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2735537141019569035} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 8351659506645333476} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &5415619581143717901 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2735537141019569035} + m_CullTransparentMesh: 0 +--- !u!114 &8599129644269611419 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2735537141019569035} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &2756405507098548097 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4086772113621016208} + - component: {fileID: 970757129289726534} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &4086772113621016208 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2756405507098548097} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 591433198773945814} + m_Father: {fileID: 2451940126815751474} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &970757129289726534 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2756405507098548097} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1681414707425253133} + toggleTransition: 1 + graphic: {fileID: 6029727342443417148} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &2797151631749506656 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5124529111177426770} + - component: {fileID: 5568758194233421245} + - component: {fileID: 2270273949667200229} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5124529111177426770 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2797151631749506656} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 3680364213637305159} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &5568758194233421245 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2797151631749506656} + m_CullTransparentMesh: 0 +--- !u!114 &2270273949667200229 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2797151631749506656} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &2985614219956721450 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6551000627649811944} + - component: {fileID: 7462788929612166242} + - component: {fileID: 8907934119334727340} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6551000627649811944 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2985614219956721450} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 2336108770712772099} + m_Father: {fileID: 1869528527587065075} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &7462788929612166242 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2985614219956721450} + m_CullTransparentMesh: 0 +--- !u!114 &8907934119334727340 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2985614219956721450} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &3171115851903540441 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7954316942891746433} + - component: {fileID: 2258849323521112219} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &7954316942891746433 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3171115851903540441} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1189216680378437486} + m_Father: {fileID: 8818044284439774689} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2258849323521112219 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3171115851903540441} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 7495417191435204136} + toggleTransition: 1 + graphic: {fileID: 888460402368909444} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &3204111589982867630 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1544810510454982857} + - component: {fileID: 7980649047932582416} + - component: {fileID: 888460402368909444} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1544810510454982857 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3204111589982867630} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1189216680378437486} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &7980649047932582416 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3204111589982867630} + m_CullTransparentMesh: 0 +--- !u!114 &888460402368909444 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3204111589982867630} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &3239541957581880198 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1568876051421469522} + - component: {fileID: 6393270941446573718} + - component: {fileID: 7069956242290131492} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1568876051421469522 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3239541957581880198} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 4295031112077750847} + m_Father: {fileID: 5941713586452052334} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &6393270941446573718 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3239541957581880198} + m_CullTransparentMesh: 0 +--- !u!114 &7069956242290131492 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3239541957581880198} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &3308387163373142073 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7956694805050852688} + - component: {fileID: 3660989855823199432} + - component: {fileID: 4189231263243852722} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &7956694805050852688 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3308387163373142073} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3774037929180827509} + m_Father: {fileID: 5369190403499271288} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &3660989855823199432 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3308387163373142073} + m_CullTransparentMesh: 0 +--- !u!114 &4189231263243852722 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3308387163373142073} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &3315913571245561063 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3774037929180827509} + - component: {fileID: 3804283252385965860} + - component: {fileID: 9162012530475593324} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3774037929180827509 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3315913571245561063} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 7956694805050852688} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &3804283252385965860 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3315913571245561063} + m_CullTransparentMesh: 0 +--- !u!114 &9162012530475593324 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3315913571245561063} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &3368454694728957684 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6644699419958076397} + - component: {fileID: 147858285169255864} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6644699419958076397 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3368454694728957684} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 2567792433006010677} + m_Father: {fileID: 3803781275079323733} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &147858285169255864 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3368454694728957684} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 6640962838804556285} + toggleTransition: 1 + graphic: {fileID: 4127528762848208377} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &3369459815916386821 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7464475961458692551} + - component: {fileID: 2163830951127551774} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &7464475961458692551 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3369459815916386821} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 5001324386341305675} + m_Father: {fileID: 8625410696850161855} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2163830951127551774 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3369459815916386821} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 6925205396671069} + toggleTransition: 1 + graphic: {fileID: 3955374361418223195} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &3374982763725671149 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 699944379274011391} + - component: {fileID: 4982503990233528976} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &699944379274011391 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3374982763725671149} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 4894700207822734448} + m_Father: {fileID: 2652713077043660966} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &4982503990233528976 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3374982763725671149} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 5624070143109776842} + toggleTransition: 1 + graphic: {fileID: 4755439529892379193} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &3384862175355358611 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3954105840611946110} + - component: {fileID: 1510212987001653101} + m_Layer: 5 + m_Name: DebugUI Toggle 4 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3954105840611946110 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3384862175355358611} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1237372008052714286} + - {fileID: 6386133981247227809} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1510212987001653101 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3384862175355358611} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 4128875111787400469} + valueToggle: {fileID: 2451434126944430322} + checkmarkImage: {fileID: 8599129644269611419} +--- !u!1 &3428755322359797045 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7380185792925235767} + - component: {fileID: 8590323334709990305} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &7380185792925235767 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3428755322359797045} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3769025729730033565} + m_Father: {fileID: 3002137670299042156} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &8590323334709990305 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3428755322359797045} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 7083163093166539205} + toggleTransition: 1 + graphic: {fileID: 7629182826719062560} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &3516696314699177012 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8654207302046996467} + - component: {fileID: 3282158458090981443} + m_Layer: 5 + m_Name: DebugUI Toggle 3 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8654207302046996467 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3516696314699177012} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 49982278915739227} + - {fileID: 4397487224462890380} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &3282158458090981443 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3516696314699177012} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 2720401729764849792} + valueToggle: {fileID: 7118092976832869884} + checkmarkImage: {fileID: 4899798569211387073} +--- !u!1 &3569379677769956627 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7816446078609134115} + - component: {fileID: 7448835212396526773} + m_Layer: 5 + m_Name: DebugUI Toggle 9 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &7816446078609134115 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3569379677769956627} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 2531124078508228213} + - {fileID: 5369190403499271288} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &7448835212396526773 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3569379677769956627} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 7700455392299810905} + valueToggle: {fileID: 2958440384749385630} + checkmarkImage: {fileID: 9162012530475593324} +--- !u!1 &3571443757009416159 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3642279660512588141} + - component: {fileID: 3639759082769292463} + - component: {fileID: 3459723882786048853} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3642279660512588141 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3571443757009416159} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3641684792875398575} + m_Father: {fileID: 3641221951591520489} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &3639759082769292463 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3571443757009416159} + m_CullTransparentMesh: 0 +--- !u!114 &3459723882786048853 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3571443757009416159} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &3571527177030264211 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3641221951591520489} + - component: {fileID: 3462889519718661877} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3641221951591520489 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3571527177030264211} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3642279660512588141} + m_Father: {fileID: 3641905530822378611} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &3462889519718661877 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3571527177030264211} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 3459723882786048853} + toggleTransition: 1 + graphic: {fileID: 3459027866663724429} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &3572023702122751751 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3641174431038411831} + - component: {fileID: 3639509330965081415} + - component: {fileID: 3459080543867973199} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3641174431038411831 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3572023702122751751} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 3641905530822378611} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &3639509330965081415 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3572023702122751751} + m_CullTransparentMesh: 0 +--- !u!114 &3459080543867973199 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3572023702122751751} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &3572471841810415943 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3641905530822378611} + - component: {fileID: 3572471841810415940} + m_Layer: 5 + m_Name: DebugUI Toggle 0 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3641905530822378611 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3572471841810415943} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3641174431038411831} + - {fileID: 3641221951591520489} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -13} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &3572471841810415940 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3572471841810415943} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 3459080543867973199} + valueToggle: {fileID: 3462889519718661877} + checkmarkImage: {fileID: 3459027866663724429} +--- !u!1 &3572808593452157577 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3641684792875398575} + - component: {fileID: 3639164083858556819} + - component: {fileID: 3459027866663724429} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3641684792875398575 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3572808593452157577} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 3642279660512588141} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &3639164083858556819 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3572808593452157577} + m_CullTransparentMesh: 0 +--- !u!114 &3459027866663724429 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3572808593452157577} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &3585643264467902480 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4894700207822734448} + - component: {fileID: 5095661899487818905} + - component: {fileID: 5624070143109776842} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &4894700207822734448 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3585643264467902480} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 6546067790357044605} + m_Father: {fileID: 699944379274011391} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &5095661899487818905 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3585643264467902480} + m_CullTransparentMesh: 0 +--- !u!114 &5624070143109776842 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3585643264467902480} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &3631579074025567380 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3141594381208770657} + - component: {fileID: 9014116387579602363} + - component: {fileID: 2284996109865033884} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3141594381208770657 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3631579074025567380} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1904428486749382773} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &9014116387579602363 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3631579074025567380} + m_CullTransparentMesh: 0 +--- !u!114 &2284996109865033884 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3631579074025567380} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &3645164844498060459 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8413373871896021635} + - component: {fileID: 7471413337957999450} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8413373871896021635 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3645164844498060459} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3612299115344139013} + m_Father: {fileID: 2759500403880505928} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &7471413337957999450 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3645164844498060459} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 5811605465015081675} + toggleTransition: 1 + graphic: {fileID: 4289623129001525722} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &3657568049055452192 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8558628789733519512} + - component: {fileID: 5209445438387244003} + - component: {fileID: 4289623129001525722} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8558628789733519512 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3657568049055452192} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 3612299115344139013} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &5209445438387244003 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3657568049055452192} + m_CullTransparentMesh: 0 +--- !u!114 &4289623129001525722 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3657568049055452192} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &3712882999369957480 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1143708577816669107} + - component: {fileID: 6245370273393918545} + - component: {fileID: 7629182826719062560} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1143708577816669107 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3712882999369957480} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 3769025729730033565} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &6245370273393918545 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3712882999369957480} + m_CullTransparentMesh: 0 +--- !u!114 &7629182826719062560 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3712882999369957480} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &3765212742840115414 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4880028377363535173} + - component: {fileID: 1706073112578242183} + - component: {fileID: 7322248292256421261} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &4880028377363535173 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3765212742840115414} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1914011185745597247} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &1706073112578242183 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3765212742840115414} + m_CullTransparentMesh: 0 +--- !u!114 &7322248292256421261 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3765212742840115414} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &3880431613689876023 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7399658697125515523} + - component: {fileID: 2309084006960021099} + m_Layer: 5 + m_Name: DebugUI Toggle 25 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &7399658697125515523 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3880431613689876023} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1221176923530238434} + - {fileID: 1869528527587065075} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2309084006960021099 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3880431613689876023} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 5102590157774239751} + valueToggle: {fileID: 8562629198898424411} + checkmarkImage: {fileID: 5177354320781382892} +--- !u!1 &3884623341178589105 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4263894447749242993} + - component: {fileID: 5756384988777549420} + - component: {fileID: 6243446961833559651} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &4263894447749242993 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3884623341178589105} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 4157811473205521841} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &5756384988777549420 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3884623341178589105} + m_CullTransparentMesh: 0 +--- !u!114 &6243446961833559651 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3884623341178589105} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &3941629718707521949 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6667778054025323136} + - component: {fileID: 2456697693204756471} + - component: {fileID: 3659922831755168663} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6667778054025323136 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3941629718707521949} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1133780997644914158} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &2456697693204756471 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3941629718707521949} + m_CullTransparentMesh: 0 +--- !u!114 &3659922831755168663 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3941629718707521949} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &4027286663159150654 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6445334109479971278} + - component: {fileID: 8058732095134162664} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6445334109479971278 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4027286663159150654} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 8573571124664108074} + m_Father: {fileID: 9173084524125034988} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &8058732095134162664 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4027286663159150654} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 4482108447807922650} + toggleTransition: 1 + graphic: {fileID: 962910717536914882} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &4037875838780246769 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8818044284439774689} + - component: {fileID: 8114663146547476803} + m_Layer: 5 + m_Name: DebugUI Toggle 11 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8818044284439774689 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4037875838780246769} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 9026513043517260611} + - {fileID: 7954316942891746433} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &8114663146547476803 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4037875838780246769} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 8196305987243256177} + valueToggle: {fileID: 2258849323521112219} + checkmarkImage: {fileID: 888460402368909444} +--- !u!1 &4079825732997906742 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6353858620915095577} + - component: {fileID: 3456792024118400511} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6353858620915095577 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4079825732997906742} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 6341387859349373114} + m_Father: {fileID: 1904428486749382773} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &3456792024118400511 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4079825732997906742} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 4830864563684941362} + toggleTransition: 1 + graphic: {fileID: 9060318935775576703} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &4113300208803229572 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4278529981198013852} + - component: {fileID: 8694217767465827808} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &4278529981198013852 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4113300208803229572} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 7198286586904223138} + m_Father: {fileID: 4199920854957040706} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &8694217767465827808 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4113300208803229572} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 785927379557597115} + toggleTransition: 1 + graphic: {fileID: 8002195202206546742} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &4115723969835415551 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1763134690699169346} + - component: {fileID: 3776545304459646159} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1763134690699169346 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4115723969835415551} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 7361462984932131187} + m_Father: {fileID: 1133780997644914158} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &3776545304459646159 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4115723969835415551} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 8683242940989415304} + toggleTransition: 1 + graphic: {fileID: 7141046430449178186} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &4136008973788615843 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6520704134104925015} + - component: {fileID: 1702414852724651410} + m_Layer: 5 + m_Name: DebugUI Toggle 26 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6520704134104925015 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4136008973788615843} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 4047548843005941320} + - {fileID: 5941713586452052334} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1702414852724651410 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4136008973788615843} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 4510461617772264124} + valueToggle: {fileID: 4787017756125165782} + checkmarkImage: {fileID: 332153022343275791} +--- !u!1 &4179571699095856206 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1185291142442617761} + - component: {fileID: 2313539819687221356} + - component: {fileID: 6797895232316676442} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1185291142442617761 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4179571699095856206} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 5154472422670747833} + m_Father: {fileID: 1698301253758164178} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &2313539819687221356 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4179571699095856206} + m_CullTransparentMesh: 0 +--- !u!114 &6797895232316676442 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4179571699095856206} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &4254056818223299175 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3002137670299042156} + - component: {fileID: 7788606920463215453} + m_Layer: 5 + m_Name: DebugUI Toggle 18 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3002137670299042156 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4254056818223299175} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 2748700044399894202} + - {fileID: 7380185792925235767} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &7788606920463215453 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4254056818223299175} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 3530406180247266972} + valueToggle: {fileID: 8590323334709990305} + checkmarkImage: {fileID: 7629182826719062560} +--- !u!1 &4329563734337181686 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1413563205384497702} + - component: {fileID: 7286666392514011208} + - component: {fileID: 4509044584000312710} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1413563205384497702 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4329563734337181686} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 6872577016307684039} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &7286666392514011208 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4329563734337181686} + m_CullTransparentMesh: 0 +--- !u!114 &4509044584000312710 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4329563734337181686} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &4442289739500596448 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6697593953020889603} + - component: {fileID: 1135027492066294985} + - component: {fileID: 4846740409493721984} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6697593953020889603 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4442289739500596448} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2451940126815751474} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &1135027492066294985 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4442289739500596448} + m_CullTransparentMesh: 0 +--- !u!114 &4846740409493721984 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4442289739500596448} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &4595870184737454115 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 591433198773945814} + - component: {fileID: 6409064332323974544} + - component: {fileID: 1681414707425253133} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &591433198773945814 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4595870184737454115} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1299297123745915370} + m_Father: {fileID: 4086772113621016208} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &6409064332323974544 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4595870184737454115} + m_CullTransparentMesh: 0 +--- !u!114 &1681414707425253133 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4595870184737454115} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &4612880306164105923 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7413620405051575626} + - component: {fileID: 6285758457108715709} + - component: {fileID: 2165066025782384386} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &7413620405051575626 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4612880306164105923} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 3434169616513257095} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &6285758457108715709 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4612880306164105923} + m_CullTransparentMesh: 0 +--- !u!114 &2165066025782384386 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4612880306164105923} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &4639780946518862453 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6341387859349373114} + - component: {fileID: 3261218236385974570} + - component: {fileID: 4830864563684941362} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6341387859349373114 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4639780946518862453} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 213539999138786333} + m_Father: {fileID: 6353858620915095577} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &3261218236385974570 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4639780946518862453} + m_CullTransparentMesh: 0 +--- !u!114 &4830864563684941362 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4639780946518862453} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &4649577923568229521 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1299297123745915370} + - component: {fileID: 7678348437943295021} + - component: {fileID: 6029727342443417148} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1299297123745915370 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4649577923568229521} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 591433198773945814} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &7678348437943295021 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4649577923568229521} + m_CullTransparentMesh: 0 +--- !u!114 &6029727342443417148 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4649577923568229521} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &4849482690791000872 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6075760728334120815} + - component: {fileID: 3882171044134844897} + - component: {fileID: 2700416459006292345} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6075760728334120815 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4849482690791000872} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 6493715579490047529} + m_Father: {fileID: 7290923337117366102} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &3882171044134844897 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4849482690791000872} + m_CullTransparentMesh: 0 +--- !u!114 &2700416459006292345 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4849482690791000872} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &5014516996357532671 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5001324386341305675} + - component: {fileID: 185118308965006561} + - component: {fileID: 6925205396671069} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5001324386341305675 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5014516996357532671} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 8557170861926017448} + m_Father: {fileID: 7464475961458692551} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &185118308965006561 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5014516996357532671} + m_CullTransparentMesh: 0 +--- !u!114 &6925205396671069 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5014516996357532671} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &5041280086884305940 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8927555893094689660} + - component: {fileID: 3176317505229877131} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8927555893094689660 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5041280086884305940} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 7461098207183238788} + m_Father: {fileID: 4817301142119688916} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &3176317505229877131 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5041280086884305940} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 2358232831280620294} + toggleTransition: 1 + graphic: {fileID: 2981323361707958040} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &5069726341249081048 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4047548843005941320} + - component: {fileID: 5397351996381731281} + - component: {fileID: 4510461617772264124} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &4047548843005941320 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5069726341249081048} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 6520704134104925015} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &5397351996381731281 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5069726341249081048} + m_CullTransparentMesh: 0 +--- !u!114 &4510461617772264124 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5069726341249081048} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &5130458670307175369 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3916575158388844691} + - component: {fileID: 6082500289769078190} + - component: {fileID: 1736220021016928009} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3916575158388844691 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5130458670307175369} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2590341387017464519} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &6082500289769078190 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5130458670307175369} + m_CullTransparentMesh: 0 +--- !u!114 &1736220021016928009 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5130458670307175369} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &5202510230799889004 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3626888406440555363} + - component: {fileID: 8180736816758371908} + m_Layer: 5 + m_Name: DebugUI Toggle 8 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3626888406440555363 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5202510230799889004} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1483444589931372990} + - {fileID: 9157722414083985858} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &8180736816758371908 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5202510230799889004} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 3439658608168239967} + valueToggle: {fileID: 2214193822323440039} + checkmarkImage: {fileID: 7322248292256421261} +--- !u!1 &5216377504156040801 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5927895885435220356} + - component: {fileID: 7966387800811379961} + - component: {fileID: 3496924685570888828} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5927895885435220356 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5216377504156040801} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 4817301142119688916} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &7966387800811379961 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5216377504156040801} + m_CullTransparentMesh: 0 +--- !u!114 &3496924685570888828 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5216377504156040801} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &5267050426723971953 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5267050426723971950} + - component: {fileID: 5267050426723971948} + - component: {fileID: 5267050426723971951} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5267050426723971950 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5267050426723971953} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 5267050428775862375} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &5267050426723971948 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5267050426723971953} + m_CullTransparentMesh: 0 +--- !u!114 &5267050426723971951 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5267050426723971953} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &5267050426938384531 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5267050426938384528} + - component: {fileID: 5267050426938384529} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5267050426938384528 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5267050426938384531} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 5267050428775862375} + m_Father: {fileID: 5267050427034451046} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &5267050426938384529 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5267050426938384531} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 5267050428775862372} + toggleTransition: 1 + graphic: {fileID: 5267050426723971951} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &5267050427034451049 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5267050427034451046} + - component: {fileID: 5267050427034451047} + m_Layer: 5 + m_Name: DebugUI Toggle 1 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5267050427034451046 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5267050427034451049} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 5267050427060996203} + - {fileID: 5267050426938384528} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &5267050427034451047 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5267050427034451049} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 5267050427060996200} + valueToggle: {fileID: 5267050426938384529} + checkmarkImage: {fileID: 5267050426723971951} +--- !u!1 &5267050427060996202 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5267050427060996203} + - component: {fileID: 5267050427060996201} + - component: {fileID: 5267050427060996200} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5267050427060996203 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5267050427060996202} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 5267050427034451046} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &5267050427060996201 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5267050427060996202} + m_CullTransparentMesh: 0 +--- !u!114 &5267050427060996200 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5267050427060996202} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &5267050428775862374 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5267050428775862375} + - component: {fileID: 5267050428775862373} + - component: {fileID: 5267050428775862372} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5267050428775862375 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5267050428775862374} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 5267050426723971950} + m_Father: {fileID: 5267050426938384528} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &5267050428775862373 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5267050428775862374} + m_CullTransparentMesh: 0 +--- !u!114 &5267050428775862372 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5267050428775862374} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &5462907878922134795 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2759500403880505928} + - component: {fileID: 8677530327100967840} + m_Layer: 5 + m_Name: DebugUI Toggle 27 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2759500403880505928 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5462907878922134795} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 8429224242260680381} + - {fileID: 8413373871896021635} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &8677530327100967840 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5462907878922134795} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 5654365300560118476} + valueToggle: {fileID: 7471413337957999450} + checkmarkImage: {fileID: 4289623129001525722} +--- !u!1 &5483026217932215876 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 319426443455914023} + - component: {fileID: 2203183165023518730} + - component: {fileID: 1504294621800433182} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &319426443455914023 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5483026217932215876} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 3737111891372312802} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &2203183165023518730 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5483026217932215876} + m_CullTransparentMesh: 0 +--- !u!114 &1504294621800433182 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5483026217932215876} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &5576049767558804990 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7792108644153214049} + - component: {fileID: 6296772535290834005} + - component: {fileID: 2353148834173414365} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &7792108644153214049 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5576049767558804990} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 7977966139789023458} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &6296772535290834005 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5576049767558804990} + m_CullTransparentMesh: 0 +--- !u!114 &2353148834173414365 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5576049767558804990} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &5661721680391056024 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2069466459521621409} + - component: {fileID: 1684022678578897709} + - component: {fileID: 8306564221555339770} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2069466459521621409 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5661721680391056024} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 7388519436634992578} + m_Father: {fileID: 1471453698717655133} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &1684022678578897709 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5661721680391056024} + m_CullTransparentMesh: 0 +--- !u!114 &8306564221555339770 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5661721680391056024} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &5713211408484041554 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8235471640864529742} + - component: {fileID: 7780419505253050479} + - component: {fileID: 7954571544824238787} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8235471640864529742 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5713211408484041554} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2075241552360254502} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &7780419505253050479 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5713211408484041554} + m_CullTransparentMesh: 0 +--- !u!114 &7954571544824238787 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5713211408484041554} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &5750870979089988624 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2336108770712772099} + - component: {fileID: 967809402997970503} + - component: {fileID: 5177354320781382892} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2336108770712772099 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5750870979089988624} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 6551000627649811944} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &967809402997970503 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5750870979089988624} + m_CullTransparentMesh: 0 +--- !u!114 &5177354320781382892 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5750870979089988624} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &5801129305911044462 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4199920854957040706} + - component: {fileID: 3036984858544632144} + m_Layer: 5 + m_Name: DebugUI Toggle 15 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &4199920854957040706 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5801129305911044462} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 2314514058934025060} + - {fileID: 4278529981198013852} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &3036984858544632144 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5801129305911044462} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 1050381230042893636} + valueToggle: {fileID: 8694217767465827808} + checkmarkImage: {fileID: 8002195202206546742} +--- !u!1 &5923712961749352638 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2542400616675058289} + - component: {fileID: 8748157484271708675} + - component: {fileID: 4127528762848208377} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2542400616675058289 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5923712961749352638} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2567792433006010677} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &8748157484271708675 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5923712961749352638} + m_CullTransparentMesh: 0 +--- !u!114 &4127528762848208377 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5923712961749352638} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &6047295618778324901 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5833403709247139747} + - component: {fileID: 5836198589662574527} + - component: {fileID: 5943836262754876151} + m_Layer: 5 + m_Name: Arrow Closed + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5833403709247139747 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6047295618778324901} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 5834238147341516467} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0.5} + m_AnchorMax: {x: 0, y: 0.5} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0, y: 0.5} +--- !u!222 &5836198589662574527 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6047295618778324901} + m_CullTransparentMesh: 0 +--- !u!114 &5943836262754876151 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6047295618778324901} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: 7a0568d5e3330b84687e307992be3030, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &6047428593800107549 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5833894441773011497} + - component: {fileID: 5836132423617176489} + - component: {fileID: 5944573348398787477} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5833894441773011497 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6047428593800107549} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 5834238147341516467} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 10, y: 0} + m_SizeDelta: {x: -20, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &5836132423617176489 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6047428593800107549} + m_CullTransparentMesh: 0 +--- !u!114 &5944573348398787477 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6047428593800107549} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: 'BitField + +' +--- !u!1 &6047464508828073067 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5833912162122428113} + - component: {fileID: 5836418015764029031} + - component: {fileID: 5944727394572058481} + m_Layer: 5 + m_Name: Arrow Opened + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 0 +--- !u!224 &5833912162122428113 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6047464508828073067} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 5834238147341516467} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0.5} + m_AnchorMax: {x: 0, y: 0.5} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0, y: 0.5} +--- !u!222 &5836418015764029031 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6047464508828073067} + m_CullTransparentMesh: 0 +--- !u!114 &5944727394572058481 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6047464508828073067} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: a674720496c1ed248a5b7ea3e22a11fd, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &6047609828951176373 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5834238147341516467} + - component: {fileID: 5943742358506384225} + m_Layer: 5 + m_Name: Header + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5834238147341516467 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6047609828951176373} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 5833912162122428113} + - {fileID: 5833403709247139747} + - {fileID: 5833894441773011497} + m_Father: {fileID: 5833802642077810669} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &5943742358506384225 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6047609828951176373} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: e4786b5477cac0a42855b21fdaa2242f, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 0} + toggleTransition: 0 + graphic: {fileID: 0} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 0 + content: {fileID: 6048264713057143749} + arrowOpened: {fileID: 6047464508828073067} + arrowClosed: {fileID: 6047295618778324901} +--- !u!1 &6048035622621399599 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3110659917968075140} + - component: {fileID: 5134166864003699706} + - component: {fileID: 7141046430449178186} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3110659917968075140 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6048035622621399599} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 7361462984932131187} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &5134166864003699706 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6048035622621399599} + m_CullTransparentMesh: 0 +--- !u!114 &7141046430449178186 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6048035622621399599} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &6048135192916836887 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5833802642077810669} + - component: {fileID: 5943726395919352301} + - component: {fileID: 5940633483949707567} + - component: {fileID: 5944332278156944397} + - component: {fileID: 4742033028387346344} + m_Layer: 0 + m_Name: DebugUIHandlerRenderingLayerField + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5833802642077810669 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6048135192916836887} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 5834238147341516467} + - {fileID: 5832985335166806795} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 293.5, y: 0} + m_SizeDelta: {x: 577, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &5943726395919352301 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6048135192916836887} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59f8146938fff824cb5fd77236b75775, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_ChildAlignment: 0 + m_Spacing: 0 + m_ChildForceExpandWidth: 1 + m_ChildForceExpandHeight: 1 + m_ChildControlWidth: 1 + m_ChildControlHeight: 0 + m_ChildScaleWidth: 0 + m_ChildScaleHeight: 0 + m_ReverseArrangement: 0 +--- !u!114 &5940633483949707567 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6048135192916836887} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3} + m_Name: + m_EditorClassIdentifier: + m_HorizontalFit: 0 + m_VerticalFit: 2 +--- !u!114 &5944332278156944397 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6048135192916836887} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2bd470ffc0c0fe54faddbf8d466bf519, type: 3} + m_Name: + m_EditorClassIdentifier: + contentHolder: {fileID: 5832985335166806795} +--- !u!114 &4742033028387346344 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6048135192916836887} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: ea44ef5968bb44a48b7855c36dae02c4, type: 3} + m_Name: + m_EditorClassIdentifier: Unity.RenderPipelines.Core.Runtime::UnityEngine.Rendering.UI.DebugUIHandlerRenderingLayerField + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 5944573348398787477} + valueToggle: {fileID: 5943742358506384225} + toggles: + - {fileID: 3572471841810415940} + - {fileID: 5267050427034451047} + - {fileID: 8451891156616883890} + - {fileID: 3282158458090981443} + - {fileID: 1510212987001653101} + - {fileID: 6392172160440368498} + - {fileID: 7493564373867626443} + - {fileID: 4371419930628413674} + - {fileID: 8180736816758371908} + - {fileID: 7448835212396526773} + - {fileID: 3618360561353404684} + - {fileID: 8114663146547476803} + - {fileID: 1735825134769845716} + - {fileID: 6537490383020632609} + - {fileID: 2462861946137041447} + - {fileID: 3036984858544632144} + - {fileID: 3757811077270860227} + - {fileID: 8562085848866449756} + - {fileID: 7788606920463215453} + - {fileID: 6603789859038349866} + - {fileID: 9022096370556916318} + - {fileID: 5317882346756600920} + - {fileID: 9003751344240168844} + - {fileID: 8192731229695085962} + - {fileID: 6087187633097608169} + - {fileID: 2309084006960021099} + - {fileID: 1702414852724651410} + - {fileID: 8677530327100967840} + - {fileID: 7090020572617868160} + - {fileID: 6749636456503821663} + - {fileID: 1654229716869570161} + - {fileID: 4713833427757240811} +--- !u!1 &6048264713057143749 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5832985335166806795} + - component: {fileID: 5944589737316668415} + - component: {fileID: 5943701092258004071} + - component: {fileID: 5836253473327886437} + - component: {fileID: 5940597155278695931} + m_Layer: 5 + m_Name: Content + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 0 +--- !u!224 &5832985335166806795 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6048264713057143749} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3641905530822378611} + - {fileID: 5267050427034451046} + - {fileID: 5081734458789119777} + - {fileID: 8654207302046996467} + - {fileID: 3954105840611946110} + - {fileID: 1071186331609494896} + - {fileID: 3803781275079323733} + - {fileID: 8930712156476357657} + - {fileID: 3626888406440555363} + - {fileID: 7816446078609134115} + - {fileID: 8625410696850161855} + - {fileID: 8818044284439774689} + - {fileID: 1133780997644914158} + - {fileID: 3747482945603663964} + - {fileID: 4761151331139786934} + - {fileID: 4199920854957040706} + - {fileID: 4817301142119688916} + - {fileID: 2075241552360254502} + - {fileID: 3002137670299042156} + - {fileID: 9173084524125034988} + - {fileID: 4157811473205521841} + - {fileID: 3434169616513257095} + - {fileID: 1904428486749382773} + - {fileID: 8643262011863657182} + - {fileID: 2451940126815751474} + - {fileID: 7399658697125515523} + - {fileID: 6520704134104925015} + - {fileID: 2759500403880505928} + - {fileID: 2590341387017464519} + - {fileID: 7977966139789023458} + - {fileID: 2652713077043660966} + - {fileID: 3680364213637305159} + m_Father: {fileID: 5833802642077810669} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 288.5, y: -52.5} + m_SizeDelta: {x: 577, y: 53} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &5944589737316668415 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6048264713057143749} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59f8146938fff824cb5fd77236b75775, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: + m_Left: 25 + m_Right: 0 + m_Top: 0 + m_Bottom: 4 + m_ChildAlignment: 0 + m_Spacing: 1 + m_ChildForceExpandWidth: 1 + m_ChildForceExpandHeight: 0 + m_ChildControlWidth: 1 + m_ChildControlHeight: 0 + m_ChildScaleWidth: 0 + m_ChildScaleHeight: 0 + m_ReverseArrangement: 0 +--- !u!114 &5943701092258004071 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6048264713057143749} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3} + m_Name: + m_EditorClassIdentifier: + m_HorizontalFit: 0 + m_VerticalFit: 1 +--- !u!222 &5836253473327886437 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6048264713057143749} + m_CullTransparentMesh: 0 +--- !u!114 &5940597155278695931 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6048264713057143749} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0, g: 0, b: 0, a: 0.2509804} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: 127279d577f25ac4ea17dae3782e5074, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &6054211915192511925 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3434169616513257095} + - component: {fileID: 5317882346756600920} + m_Layer: 5 + m_Name: DebugUI Toggle 21 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3434169616513257095 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6054211915192511925} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 7413620405051575626} + - {fileID: 906931124344334618} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &5317882346756600920 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6054211915192511925} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 2165066025782384386} + valueToggle: {fileID: 171724460343184333} + checkmarkImage: {fileID: 1504294621800433182} +--- !u!1 &6255634095443365774 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1617024272870076377} + - component: {fileID: 1463420292870698296} + - component: {fileID: 2981323361707958040} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1617024272870076377 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6255634095443365774} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 7461098207183238788} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &1463420292870698296 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6255634095443365774} + m_CullTransparentMesh: 0 +--- !u!114 &2981323361707958040 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6255634095443365774} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &6319982235128125421 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5941713586452052334} + - component: {fileID: 4787017756125165782} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5941713586452052334 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6319982235128125421} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1568876051421469522} + m_Father: {fileID: 6520704134104925015} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &4787017756125165782 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6319982235128125421} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 7069956242290131492} + toggleTransition: 1 + graphic: {fileID: 332153022343275791} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &6393401694846712333 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5784938561067271187} + - component: {fileID: 4365777817241233862} + - component: {fileID: 3314591442341821866} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5784938561067271187 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6393401694846712333} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 8930712156476357657} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &4365777817241233862 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6393401694846712333} + m_CullTransparentMesh: 0 +--- !u!114 &3314591442341821866 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6393401694846712333} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &6398709037057264613 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2652713077043660966} + - component: {fileID: 1654229716869570161} + m_Layer: 5 + m_Name: DebugUI Toggle 30 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2652713077043660966 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6398709037057264613} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 5647913056700805355} + - {fileID: 699944379274011391} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1654229716869570161 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6398709037057264613} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 7875341202550150707} + valueToggle: {fileID: 4982503990233528976} + checkmarkImage: {fileID: 4755439529892379193} +--- !u!1 &6434403705248118292 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2531124078508228213} + - component: {fileID: 6369504825566277162} + - component: {fileID: 7700455392299810905} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2531124078508228213 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6434403705248118292} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 7816446078609134115} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &6369504825566277162 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6434403705248118292} + m_CullTransparentMesh: 0 +--- !u!114 &7700455392299810905 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6434403705248118292} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &6435836762835265831 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3912983369996595199} + - component: {fileID: 8673800743758914287} + - component: {fileID: 4899798569211387073} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3912983369996595199 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6435836762835265831} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 4700199911600101284} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &8673800743758914287 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6435836762835265831} + m_CullTransparentMesh: 0 +--- !u!114 &4899798569211387073 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6435836762835265831} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &6457266601126856795 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3807659439045052884} + - component: {fileID: 4529595284317267641} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3807659439045052884 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6457266601126856795} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 5983516410954562191} + m_Father: {fileID: 1071186331609494896} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &4529595284317267641 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6457266601126856795} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 4746959147978535488} + toggleTransition: 1 + graphic: {fileID: 4947107805862492328} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &6647650129815640830 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2414531926316930725} + - component: {fileID: 6013907816282172337} + - component: {fileID: 962910717536914882} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2414531926316930725 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6647650129815640830} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 8573571124664108074} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &6013907816282172337 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6647650129815640830} + m_CullTransparentMesh: 0 +--- !u!114 &962910717536914882 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6647650129815640830} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &6716624449677664242 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 906931124344334618} + - component: {fileID: 171724460343184333} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &906931124344334618 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6716624449677664242} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3737111891372312802} + m_Father: {fileID: 3434169616513257095} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &171724460343184333 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6716624449677664242} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1701711077839953596} + toggleTransition: 1 + graphic: {fileID: 1504294621800433182} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &6761454948229671359 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7597631521775465986} + - component: {fileID: 289195601024694387} + - component: {fileID: 367787215377800833} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &7597631521775465986 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6761454948229671359} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 4787045164725599468} + m_Father: {fileID: 8139433324506673700} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &289195601024694387 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6761454948229671359} + m_CullTransparentMesh: 0 +--- !u!114 &367787215377800833 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6761454948229671359} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &6770269405074232191 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2567792433006010677} + - component: {fileID: 715164927613047327} + - component: {fileID: 6640962838804556285} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2567792433006010677 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6770269405074232191} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 2542400616675058289} + m_Father: {fileID: 6644699419958076397} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &715164927613047327 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6770269405074232191} + m_CullTransparentMesh: 0 +--- !u!114 &6640962838804556285 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6770269405074232191} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &6865668874098640108 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8625410696850161855} + - component: {fileID: 3618360561353404684} + m_Layer: 5 + m_Name: DebugUI Toggle 10 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8625410696850161855 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6865668874098640108} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1994050603111272669} + - {fileID: 7464475961458692551} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &3618360561353404684 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6865668874098640108} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 1133652755111259454} + valueToggle: {fileID: 2163830951127551774} + checkmarkImage: {fileID: 3955374361418223195} +--- !u!1 &6960760094989099012 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4817301142119688916} + - component: {fileID: 3757811077270860227} + m_Layer: 5 + m_Name: DebugUI Toggle 16 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &4817301142119688916 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6960760094989099012} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 5927895885435220356} + - {fileID: 8927555893094689660} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &3757811077270860227 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6960760094989099012} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 3496924685570888828} + valueToggle: {fileID: 3176317505229877131} + checkmarkImage: {fileID: 2981323361707958040} +--- !u!1 &6970906156153676647 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 9157722414083985858} + - component: {fileID: 2214193822323440039} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &9157722414083985858 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6970906156153676647} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1914011185745597247} + m_Father: {fileID: 3626888406440555363} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2214193822323440039 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6970906156153676647} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 4324276223801582212} + toggleTransition: 1 + graphic: {fileID: 7322248292256421261} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &6993641499757403295 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8930712156476357657} + - component: {fileID: 4371419930628413674} + m_Layer: 5 + m_Name: DebugUI Toggle 7 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8930712156476357657 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6993641499757403295} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 5784938561067271187} + - {fileID: 1471453698717655133} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &4371419930628413674 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6993641499757403295} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 3314591442341821866} + valueToggle: {fileID: 2933965054200657782} + checkmarkImage: {fileID: 5067439095481778869} +--- !u!1 &7107229098804190366 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7432866224741430686} + - component: {fileID: 2405871519029774392} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &7432866224741430686 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7107229098804190366} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 4976284874825399851} + m_Father: {fileID: 2075241552360254502} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2405871519029774392 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7107229098804190366} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1546348349704106882} + toggleTransition: 1 + graphic: {fileID: 4957790091271580714} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &7116855287743012930 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7461098207183238788} + - component: {fileID: 3657859447761797027} + - component: {fileID: 2358232831280620294} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &7461098207183238788 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7116855287743012930} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1617024272870076377} + m_Father: {fileID: 8927555893094689660} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &3657859447761797027 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7116855287743012930} + m_CullTransparentMesh: 0 +--- !u!114 &2358232831280620294 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7116855287743012930} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &7334754811724867571 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7198286586904223138} + - component: {fileID: 926128736222914170} + - component: {fileID: 785927379557597115} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &7198286586904223138 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7334754811724867571} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 4305866066951985147} + m_Father: {fileID: 4278529981198013852} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &926128736222914170 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7334754811724867571} + m_CullTransparentMesh: 0 +--- !u!114 &785927379557597115 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7334754811724867571} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &7358121168254530163 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8643262011863657182} + - component: {fileID: 8192731229695085962} + m_Layer: 5 + m_Name: DebugUI Toggle 23 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8643262011863657182 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7358121168254530163} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1850453015581534804} + - {fileID: 800688055469850145} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &8192731229695085962 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7358121168254530163} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 6701717425365996163} + valueToggle: {fileID: 6391126850643013647} + checkmarkImage: {fileID: 5356581191142619947} +--- !u!1 &7362354665106149521 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6872577016307684039} + - component: {fileID: 4617364959482326908} + - component: {fileID: 6744668526965383060} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6872577016307684039 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7362354665106149521} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1413563205384497702} + m_Father: {fileID: 5346538742984764208} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &4617364959482326908 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7362354665106149521} + m_CullTransparentMesh: 0 +--- !u!114 &6744668526965383060 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7362354665106149521} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &7449666261731372048 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5080179768469462520} + - component: {fileID: 3283613025475625064} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5080179768469462520 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7449666261731372048} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 8995314096000718896} + m_Father: {fileID: 4157811473205521841} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &3283613025475625064 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7449666261731372048} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 4021666774289769486} + toggleTransition: 1 + graphic: {fileID: 6982057837895959611} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &7479290689902784385 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4700199911600101284} + - component: {fileID: 105621480128343845} + - component: {fileID: 2426528291183551289} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &4700199911600101284 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7479290689902784385} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3912983369996595199} + m_Father: {fileID: 4397487224462890380} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &105621480128343845 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7479290689902784385} + m_CullTransparentMesh: 0 +--- !u!114 &2426528291183551289 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7479290689902784385} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &7529363791104559946 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 49982278915739227} + - component: {fileID: 3336377035561475108} + - component: {fileID: 2720401729764849792} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &49982278915739227 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7529363791104559946} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 8654207302046996467} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &3336377035561475108 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7529363791104559946} + m_CullTransparentMesh: 0 +--- !u!114 &2720401729764849792 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7529363791104559946} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &7586276679416498961 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1071186331609494896} + - component: {fileID: 6392172160440368498} + m_Layer: 5 + m_Name: DebugUI Toggle 5 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1071186331609494896 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7586276679416498961} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 6667855967321245346} + - {fileID: 3807659439045052884} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &6392172160440368498 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7586276679416498961} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 164768344116107986} + valueToggle: {fileID: 4529595284317267641} + checkmarkImage: {fileID: 4947107805862492328} +--- !u!1 &7597021854849206998 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 428045328721135137} + - component: {fileID: 9195918111891992531} + - component: {fileID: 8813570217460717391} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &428045328721135137 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7597021854849206998} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 3160084798452651386} + m_Father: {fileID: 5076517029326469307} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &9195918111891992531 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7597021854849206998} + m_CullTransparentMesh: 0 +--- !u!114 &8813570217460717391 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7597021854849206998} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &7668809704783364795 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4157811473205521841} + - component: {fileID: 9022096370556916318} + m_Layer: 5 + m_Name: DebugUI Toggle 20 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &4157811473205521841 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7668809704783364795} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 4263894447749242993} + - {fileID: 5080179768469462520} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &9022096370556916318 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7668809704783364795} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 6243446961833559651} + valueToggle: {fileID: 3283613025475625064} + checkmarkImage: {fileID: 6982057837895959611} +--- !u!1 &7679443995315107407 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3680364213637305159} + - component: {fileID: 4713833427757240811} + m_Layer: 5 + m_Name: DebugUI Toggle 31 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3680364213637305159 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7679443995315107407} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 5124529111177426770} + - {fileID: 8139433324506673700} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &4713833427757240811 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7679443995315107407} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 2270273949667200229} + valueToggle: {fileID: 6819208608482539135} + checkmarkImage: {fileID: 8019534688361173590} +--- !u!1 &7715904839202416233 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5833546809406971014} + - component: {fileID: 2537786671583968872} + - component: {fileID: 4947107805862492328} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5833546809406971014 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7715904839202416233} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 5983516410954562191} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &2537786671583968872 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7715904839202416233} + m_CullTransparentMesh: 0 +--- !u!114 &4947107805862492328 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7715904839202416233} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &7818452579344612254 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1133780997644914158} + - component: {fileID: 1735825134769845716} + m_Layer: 5 + m_Name: DebugUI Toggle 12 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1133780997644914158 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7818452579344612254} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 6667778054025323136} + - {fileID: 1763134690699169346} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1735825134769845716 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7818452579344612254} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 3659922831755168663} + valueToggle: {fileID: 3776545304459646159} + checkmarkImage: {fileID: 7141046430449178186} +--- !u!1 &7843109833182365029 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4295031112077750847} + - component: {fileID: 8702525542202927311} + - component: {fileID: 332153022343275791} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &4295031112077750847 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7843109833182365029} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1568876051421469522} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &8702525542202927311 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7843109833182365029} + m_CullTransparentMesh: 0 +--- !u!114 &332153022343275791 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7843109833182365029} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &7898878042900185760 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1869528527587065075} + - component: {fileID: 8562629198898424411} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1869528527587065075 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7898878042900185760} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 6551000627649811944} + m_Father: {fileID: 7399658697125515523} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &8562629198898424411 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7898878042900185760} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 8907934119334727340} + toggleTransition: 1 + graphic: {fileID: 5177354320781382892} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &7939045417989815978 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5346538742984764208} + - component: {fileID: 6804859282518200063} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5346538742984764208 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7939045417989815978} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 6872577016307684039} + m_Father: {fileID: 7977966139789023458} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &6804859282518200063 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7939045417989815978} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 6744668526965383060} + toggleTransition: 1 + graphic: {fileID: 4509044584000312710} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &8098599426082517356 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 9173084524125034988} + - component: {fileID: 6603789859038349866} + m_Layer: 5 + m_Name: DebugUI Toggle 19 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &9173084524125034988 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8098599426082517356} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 6378496972948662163} + - {fileID: 6445334109479971278} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &6603789859038349866 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8098599426082517356} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 5787119873324982712} + valueToggle: {fileID: 8058732095134162664} + checkmarkImage: {fileID: 962910717536914882} +--- !u!1 &8229421512619543525 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4761151331139786934} + - component: {fileID: 2462861946137041447} + m_Layer: 5 + m_Name: DebugUI Toggle 14 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &4761151331139786934 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8229421512619543525} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 9130896057738824197} + - {fileID: 1670263807047702912} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2462861946137041447 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8229421512619543525} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 2966172492667721896} + valueToggle: {fileID: 1441446908436994080} + checkmarkImage: {fileID: 5050348896946348867} +--- !u!1 &8382174878446464441 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8573571124664108074} + - component: {fileID: 3541859132605311333} + - component: {fileID: 4482108447807922650} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8573571124664108074 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8382174878446464441} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 2414531926316930725} + m_Father: {fileID: 6445334109479971278} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &3541859132605311333 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8382174878446464441} + m_CullTransparentMesh: 0 +--- !u!114 &4482108447807922650 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8382174878446464441} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &8418424508630208074 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 9026513043517260611} + - component: {fileID: 704724795174701787} + - component: {fileID: 8196305987243256177} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &9026513043517260611 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8418424508630208074} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 8818044284439774689} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &704724795174701787 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8418424508630208074} + m_CullTransparentMesh: 0 +--- !u!114 &8196305987243256177 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8418424508630208074} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &8419724988180278695 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8139433324506673700} + - component: {fileID: 6819208608482539135} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8139433324506673700 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8419724988180278695} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 7597631521775465986} + m_Father: {fileID: 3680364213637305159} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &6819208608482539135 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8419724988180278695} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 367787215377800833} + toggleTransition: 1 + graphic: {fileID: 8019534688361173590} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &8544218448054256101 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1471453698717655133} + - component: {fileID: 2933965054200657782} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1471453698717655133 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8544218448054256101} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 2069466459521621409} + m_Father: {fileID: 8930712156476357657} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2933965054200657782 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8544218448054256101} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 8306564221555339770} + toggleTransition: 1 + graphic: {fileID: 5067439095481778869} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &8629100503664999682 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1221176923530238434} + - component: {fileID: 7824910029803158027} + - component: {fileID: 5102590157774239751} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1221176923530238434 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8629100503664999682} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 7399658697125515523} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &7824910029803158027 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8629100503664999682} + m_CullTransparentMesh: 0 +--- !u!114 &5102590157774239751 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8629100503664999682} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &8677633347016963363 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 213539999138786333} + - component: {fileID: 7192581332987687273} + - component: {fileID: 9060318935775576703} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &213539999138786333 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8677633347016963363} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 6341387859349373114} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &7192581332987687273 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8677633347016963363} + m_CullTransparentMesh: 0 +--- !u!114 &9060318935775576703 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8677633347016963363} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &8685390622490100011 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7977966139789023458} + - component: {fileID: 6749636456503821663} + m_Layer: 5 + m_Name: DebugUI Toggle 29 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &7977966139789023458 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8685390622490100011} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 7792108644153214049} + - {fileID: 5346538742984764208} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &6749636456503821663 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8685390622490100011} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 2353148834173414365} + valueToggle: {fileID: 6804859282518200063} + checkmarkImage: {fileID: 4509044584000312710} +--- !u!1 &8802377152758538674 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6378496972948662163} + - component: {fileID: 8757688739712324464} + - component: {fileID: 5787119873324982712} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6378496972948662163 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8802377152758538674} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 9173084524125034988} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &8757688739712324464 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8802377152758538674} + m_CullTransparentMesh: 0 +--- !u!114 &5787119873324982712 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8802377152758538674} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &8891641694798509794 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4305866066951985147} + - component: {fileID: 795277854931234843} + - component: {fileID: 8002195202206546742} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &4305866066951985147 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8891641694798509794} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 7198286586904223138} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &795277854931234843 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8891641694798509794} + m_CullTransparentMesh: 0 +--- !u!114 &8002195202206546742 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8891641694798509794} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &8907353874709907600 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8233626477581283555} + - component: {fileID: 8128548266341100821} + - component: {fileID: 4427599279144680947} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8233626477581283555 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8907353874709907600} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 3747482945603663964} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &8128548266341100821 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8907353874709907600} + m_CullTransparentMesh: 0 +--- !u!114 &4427599279144680947 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8907353874709907600} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &8934854630699155733 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4397487224462890380} + - component: {fileID: 7118092976832869884} + m_Layer: 5 + m_Name: Toggle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &4397487224462890380 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8934854630699155733} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 4700199911600101284} + m_Father: {fileID: 8654207302046996467} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &7118092976832869884 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8934854630699155733} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 0 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 0 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Highlighted + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 2426528291183551289} + toggleTransition: 1 + graphic: {fileID: 4899798569211387073} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &8938513161468718541 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6493715579490047529} + - component: {fileID: 3501081499322488200} + - component: {fileID: 5802453145572142467} + m_Layer: 5 + m_Name: Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6493715579490047529 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8938513161468718541} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 6075760728334120815} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: -1, y: 0} + m_SizeDelta: {x: 11, y: 11} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &3501081499322488200 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8938513161468718541} + m_CullTransparentMesh: 0 +--- !u!114 &5802453145572142467 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8938513161468718541} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: b346b2a2df1d290438be3287b6419408, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &8941056226660783832 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 9130896057738824197} + - component: {fileID: 1608539554958489079} + - component: {fileID: 2966172492667721896} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &9130896057738824197 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8941056226660783832} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 4761151331139786934} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &1608539554958489079 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8941056226660783832} + m_CullTransparentMesh: 0 +--- !u!114 &2966172492667721896 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8941056226660783832} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!1 &9046698730679528549 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5081734458789119777} + - component: {fileID: 8451891156616883890} + m_Layer: 5 + m_Name: DebugUI Toggle 2 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5081734458789119777 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9046698730679528549} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 6885379471270306523} + - {fileID: 5076517029326469307} + m_Father: {fileID: 5832985335166806795} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 301, y: -40} + m_SizeDelta: {x: 552, y: 26} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &8451891156616883890 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9046698730679528549} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0012fc4688b5d5342a441aa32c0e099e, type: 3} + m_Name: + m_EditorClassIdentifier: + colorDefault: {r: 0.8, g: 0.8, b: 0.8, a: 1} + colorSelected: {r: 0.25, g: 0.65, b: 0.8, a: 1} + nameLabel: {fileID: 7894181582057877634} + valueToggle: {fileID: 953415876542653751} + checkmarkImage: {fileID: 8209430775002992777} +--- !u!1 &9109294533507219646 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8351659506645333476} + - component: {fileID: 2982061304914416535} + - component: {fileID: 4755971768771506769} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8351659506645333476 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9109294533507219646} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1064151588746797128} + m_Father: {fileID: 6386133981247227809} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &2982061304914416535 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9109294533507219646} + m_CullTransparentMesh: 0 +--- !u!114 &4755971768771506769 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9109294533507219646} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &9147698509246440744 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8995314096000718896} + - component: {fileID: 3459244149561950068} + - component: {fileID: 4021666774289769486} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8995314096000718896 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9147698509246440744} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 7508261725234730334} + m_Father: {fileID: 5080179768469462520} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 10, y: -12} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &3459244149561950068 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9147698509246440744} + m_CullTransparentMesh: 0 +--- !u!114 &4021666774289769486 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9147698509246440744} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: d49e78756811bfa4aafb8b6535417991, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &9156468530069850769 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6885379471270306523} + - component: {fileID: 8455131147975850754} + - component: {fileID: 7894181582057877634} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6885379471270306523 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9156468530069850769} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 5081734458789119777} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0.5, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 1} +--- !u!222 &8455131147975850754 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9156468530069850769} + m_CullTransparentMesh: 0 +--- !u!114 &7894181582057877634 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 9156468530069850769} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.8, g: 0.8, b: 0.8, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 12800000, guid: 74a5091d8707f334b9a5c31ef71a64ba, type: 3} + m_FontSize: 16 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 1 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/Prefabs/Widgets/DebugUIHandlerRenderingLayerField.prefab.meta b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/Prefabs/Widgets/DebugUIHandlerRenderingLayerField.prefab.meta new file mode 100644 index 00000000..4efc01a7 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/Prefabs/Widgets/DebugUIHandlerRenderingLayerField.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 928d1ca04af80c84e8d5dabc18095d79 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Deprecated.cs b/Packages/com.unity.render-pipelines.core/Runtime/Deprecated.cs index 9046879c..a0b1cc9c 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Deprecated.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Deprecated.cs @@ -2,6 +2,8 @@ using System; using System.Collections.Generic; using System.Linq; using System.Reflection; +using UnityEngine.Assertions; +using static UnityEngine.Rendering.DebugUI; namespace UnityEngine.Rendering { @@ -153,4 +155,50 @@ namespace UnityEngine.Rendering Unregister(volume); } } + + + public partial class DebugUI + { + /// + /// Maskfield enumeration field. + /// + [Obsolete("Mask field is not longer supported. Please use a BitField or implement your own Widget. #from(6000.2)", false)] + public class MaskField : EnumField + { + /// + /// Fills the enum using the provided names + /// + /// names to fill the enum + public void Fill(string[] names) + { + using (ListPool.Get(out var tmpNames)) + using (ListPool.Get(out var tmpValues)) + { + for (int i = 0; i < (names.Length); ++i) + { + tmpNames.Add(new GUIContent(names[i])); + tmpValues.Add(i); + } + enumNames = tmpNames.ToArray(); + enumValues = tmpValues.ToArray(); + } + } + + /// + /// Assigns a value to the maskfield. + /// + /// value for the maskfield + public override void SetValue(uint value) + { + Assert.IsNotNull(setter); + var validValue = ValidateValue(value); + + if (!validValue.Equals(getter())) + { + setter(validValue); + onValueChanged?.Invoke(this, validValue); + } + } + } + } } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/GPUResidentDrawer.cs b/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/GPUResidentDrawer.cs index 666a7cb3..aabf6728 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/GPUResidentDrawer.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/GPUResidentDrawer.cs @@ -334,7 +334,7 @@ namespace UnityEngine.Rendering private NativeList m_FrameCameraIDs; private bool m_FrameUpdateNeeded = false; - private bool m_SelectionChanged; + private bool m_IsSelectionDirty; static GPUResidentDrawer() { @@ -399,6 +399,7 @@ namespace UnityEngine.Rendering #if UNITY_EDITOR AssemblyReloadEvents.beforeAssemblyReload += OnAssemblyReload; m_FrameCameraIDs = new NativeList(1, Allocator.Persistent); + m_IsSelectionDirty = true; // Force at least one selection update #endif SceneManager.sceneLoaded += OnSceneLoaded; @@ -429,6 +430,7 @@ namespace UnityEngine.Rendering #endif SceneManager.sceneLoaded -= OnSceneLoaded; + // Note: Those RenderPipelineManager callbacks do not run when using built-in editor debug views such as lightmap, shadowmask etc RenderPipelineManager.beginContextRendering -= OnBeginContextRendering; RenderPipelineManager.endContextRendering -= OnEndContextRendering; RenderPipelineManager.beginCameraRendering -= OnBeginCameraRendering; @@ -487,6 +489,7 @@ namespace UnityEngine.Rendering // If running in the editor the player loop might not run // In order to still have a single frame update we keep track of the camera ids // A frame update happens in case the first camera is rendered again + // Note: This doesn't run when using built-in debug views such as lightmaps, shadowmask and etc private void EditorFrameUpdate(List cameras) { bool newFrame = false; @@ -508,21 +511,16 @@ namespace UnityEngine.Rendering else m_FrameUpdateNeeded = true; } - - ProcessSelection(); } private void OnSelectionChanged() { - m_SelectionChanged = true; + m_IsSelectionDirty = true; } - private void ProcessSelection() + private void UpdateSelection() { - if(!m_SelectionChanged) - return; - - m_SelectionChanged = false; + Profiler.BeginSample("GPUResidentDrawer.UpdateSelection"); Object[] renderers = Selection.GetFiltered(typeof(MeshRenderer), SelectionMode.Deep); @@ -532,8 +530,10 @@ namespace UnityEngine.Rendering rendererIDs[i] = renderers[i] ? renderers[i].GetInstanceID() : 0; m_Batcher.UpdateSelectedRenderers(rendererIDs); - + rendererIDs.Dispose(); + + Profiler.EndSample(); } #endif @@ -612,10 +612,15 @@ namespace UnityEngine.Rendering supportedChangedPackedMaterialDatas.Dispose(); m_BatchersContext.UpdateInstanceMotions(); - m_Batcher.UpdateFrame(); #if UNITY_EDITOR + if (m_IsSelectionDirty) + { + UpdateSelection(); + m_IsSelectionDirty = false; + } + m_FrameUpdateNeeded = false; #endif } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/InstanceCuller.cs b/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/InstanceCuller.cs index 7d753421..a980a3e2 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/InstanceCuller.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/InstanceCuller.cs @@ -206,6 +206,9 @@ namespace UnityEngine.Rendering Assert.IsTrue(lodMask > 0); ref var lodGroup = ref lodGroupCullingData.ElementAt((int)lodIndex); + if (lodGroup.forceLODMask != 0) + return (lodGroup.forceLODMask & lodMask) != 0 ? k_LODPercentFullyVisible : k_LODPercentInvisible; + float cameraSqrDistToLODCenter = isOrtho ? sqrScreenRelativeMetric : LODGroupRenderingUtils.CalculateSqrPerspectiveDistance(lodGroup.worldSpaceReferencePoint, cameraPosition, sqrScreenRelativeMetric); // Remove lods that are beyond the max lod. diff --git a/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/LODGroupDataPool.cs b/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/LODGroupDataPool.cs index 2b33013a..42705f50 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/LODGroupDataPool.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/LODGroupDataPool.cs @@ -27,6 +27,7 @@ namespace UnityEngine.Rendering public fixed float transitionDistances[LODGroupData.k_MaxLODLevelsCount]; // todo - make this a separate data struct (CPUOnly, as we do not support dithering on GPU..) public float worldSpaceSize;// SpeedTree crossfade. public fixed bool percentageFlags[LODGroupData.k_MaxLODLevelsCount];// SpeedTree crossfade. + public byte forceLODMask; } [BurstCompile(DisableSafetyChecks = true, OptimizeFor = OptimizeFor.Performance)] @@ -155,6 +156,7 @@ namespace UnityEngine.Rendering var worldReferencePoint = inputData.worldSpaceReferencePoint[index]; var worldSpaceSize = inputData.worldSpaceSize[index]; var lastLODIsBillboard = inputData.lastLODIsBillboard[index]; + var forceLODMask = inputData.forceLODMask[index]; var useDitheringCrossFade = fadeMode != LODFadeMode.None && supportDitheringCrossFade; var useSpeedTreeCrossFade = fadeMode == LODFadeMode.SpeedTree; @@ -166,6 +168,7 @@ namespace UnityEngine.Rendering lodGroupData->rendererCount = useDitheringCrossFade ? renderersCount : 0; lodGroupCullingData->worldSpaceSize = worldSpaceSize; lodGroupCullingData->worldSpaceReferencePoint = worldReferencePoint; + lodGroupCullingData->forceLODMask = forceLODMask; lodGroupCullingData->lodCount = lodCount; rendererCount.Add(lodGroupData->rendererCount); diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/DecodeSH.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/DecodeSH.hlsl index dfcd7d34..3e1ea9ff 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/DecodeSH.hlsl +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/DecodeSH.hlsl @@ -74,7 +74,11 @@ float3 EncodeSH(float l0, float3 l1) #if !HALF_IS_FLOAT half3 EncodeSH(half l0, half3 l1) { - return l0 == 0.0 ? 0.5 : l1 * rcp(l0) / (2.0 * APV_L1_ENCODING_SCALE) + 0.5; + // UUM-92338: To prevent rcp(l0) from going to infinity, 1.0/l0 must be smaller than 65504 (HALF_MAX) + // => l0 must be greater than than 1.0/65504 = 0.00001526624(0x0100) which is a subnormal number + // To ensure robustness and avoid issues, we need a bigger threshold value. + // 0.00006103515625 (HALF_MIN) would be a decent choice but we select 0.0001 instead, which was already used in ProbeVolume.hlsl + return (l0 < 0.0001 ? 0.5 : l1 * rcp(l0) / (2.0 * APV_L1_ENCODING_SCALE) + 0.5); } #endif diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Streaming.cs b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Streaming.cs index 87945b9c..c956c8e9 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Streaming.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.Streaming.cs @@ -1233,7 +1233,7 @@ namespace UnityEngine.Rendering var brickDataAsset = m_CurrentBakingSet.cellBricksDataAsset; cellStreamingDesc = brickDataAsset.streamableCellDescs[cellIndex]; - request.brickStreamingRequest.AddReadCommand(cellStreamingDesc.offset, brickDataAsset.elementSize * cellStreamingDesc.elementCount, (byte*)cellData.bricks.GetUnsafePtr()); + request.brickStreamingRequest.AddReadCommand(cellStreamingDesc.offset, brickDataAsset.elementSize * Mathf.Min(cellStreamingDesc.elementCount, cellDesc.bricksCount), (byte*)cellData.bricks.GetUnsafePtr()); request.brickStreamingRequest.RunCommands(brickDataAsset.OpenFile()); // Support Data diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.cs b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.cs index a9eadd77..b3b2882a 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeReferenceVolume.cs @@ -727,6 +727,7 @@ namespace UnityEngine.Rendering List m_ActiveScenes = new List(); ProbeVolumeBakingSet m_CurrentBakingSet = null; + ProbeVolumeBakingSet m_LazyBakingSet = null; bool m_NeedLoadAsset = false; bool m_ProbeReferenceVolumeInit = false; @@ -857,6 +858,39 @@ namespace UnityEngine.Rendering } } + /// + /// Setting a BakingSet while it is uninitialized schedules it to be set after initialization. + /// + /// BakingSet to set. + /// Returns true when scheduled. + internal bool ScheduleBakingSet(ProbeVolumeBakingSet bakingSet) + { + if (m_IsInitialized) + { + return false; + } + + m_LazyBakingSet = bakingSet; + return true; + } + + /// + /// Set the scheduled BakingSet if it exists. + /// + /// Returns true if the scheduling is executed. + internal bool ProcessScheduledBakingSet() + { + if (m_LazyBakingSet == null) + { + return false; + } + + SetActiveBakingSet(m_LazyBakingSet); + m_LazyBakingSet = null; + + return true; + } + /// /// Loads the baking set the given scene is part of if it exists. /// @@ -877,6 +911,11 @@ namespace UnityEngine.Rendering if (m_CurrentBakingSet == bakingSet) return; + if (ScheduleBakingSet(bakingSet)) + { + return; + } + foreach (var data in perSceneDataList) data.QueueSceneRemoval(); @@ -1015,6 +1054,8 @@ namespace UnityEngine.Rendering foreach (var data in perSceneDataList) data.Initialize(); + + ProcessScheduledBakingSet(); } /// @@ -1347,7 +1388,7 @@ namespace UnityEngine.Rendering return; } - if (m_CurrentBakingSet != null && bakingSet != m_CurrentBakingSet) + if (m_CurrentBakingSet != null && !m_CurrentBakingSet.HasSameSceneGUIDs(bakingSet)) { // Trying to load data for a scene from a different baking set than currently loaded ones. // This should not throw an error, but it's not supported diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeBakingSet.Editor.cs b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeBakingSet.Editor.cs index 0ff45e67..3b52d8fa 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeBakingSet.Editor.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeBakingSet.Editor.cs @@ -560,9 +560,9 @@ namespace UnityEngine.Rendering } } - internal SceneBakeData GetSceneBakeData(string sceneGUID) + internal SceneBakeData GetSceneBakeData(string sceneGUID, bool addIfMissing = true) { - if (!m_SceneBakeData.TryGetValue(sceneGUID, out var bakeData)) + if (!m_SceneBakeData.TryGetValue(sceneGUID, out var bakeData) && addIfMissing) { if (m_SceneGUIDs.Contains(sceneGUID)) m_SceneBakeData[sceneGUID] = bakeData = new SceneBakeData(); diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeBakingSet.cs b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeBakingSet.cs index d6d9a6d0..e0b37ef8 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeBakingSet.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeBakingSet.cs @@ -31,7 +31,8 @@ namespace UnityEngine.Rendering internal enum Version { Initial, - RemoveProbeVolumeSceneData + RemoveProbeVolumeSceneData, + AssetsAlwaysReferenced, } [Serializable] @@ -345,6 +346,28 @@ namespace UnityEngine.Rendering #endif } + // Upgrade baking sets from before we always stored asset references. + if (version < Version.AssetsAlwaysReferenced && ProbeReferenceVolume.instance.isInitialized) + { +#if UNITY_EDITOR + cellBricksDataAsset.EnsureAssetLoaded(); + cellSharedDataAsset.EnsureAssetLoaded(); + cellSupportDataAsset.EnsureAssetLoaded(); + foreach (var scenario in scenarios) + { + scenario.Value.cellDataAsset.EnsureAssetLoaded(); + scenario.Value.cellOptionalDataAsset.EnsureAssetLoaded(); + scenario.Value.cellProbeOcclusionDataAsset.EnsureAssetLoaded(); + } + + version = Version.AssetsAlwaysReferenced; + + // Save immediately since these references must be written to disk for certain functionality + // to work, such as exporting a .unitypackage. Changing in memory is not enough. + UnityEditor.EditorUtility.SetDirty(this); + UnityEditor.AssetDatabase.SaveAssetIfDirty(this); +#endif + } #pragma warning restore 618 } @@ -645,18 +668,45 @@ namespace UnityEngine.Rendering } } + private unsafe bool FileExists(string path) + { + // Can't use System.IO.File.Exists as it doesn't work with compressed streaming assets folder (iOS, Android) + FileInfoResult infoResult; + ReadHandle h = AsyncReadManager.GetFileInfo(path, &infoResult); + h.JobHandle.Complete(); + return infoResult.FileState == FileState.Exists; + } + // Load from disk all data related to the required cells only. // This allows us to avoid loading the whole file in memory which could be a huge spike for multi scene setups. unsafe NativeArray LoadStreambleAssetData(ProbeVolumeStreamableAsset asset, List cellIndices) where T : struct { if (!m_UseStreamingAsset) { - // Only when not using Streaming Asset is this reference valid. Debug.Assert(asset.asset != null); return asset.asset.GetData().Reinterpret(1); } else { + if (!FileExists(asset.GetAssetPath())) + { + asset.RefreshAssetPath(); + if (!FileExists(asset.GetAssetPath())) + { + // If we can't load from StreamingAssets, but we have a valid asset reference, try to use the asset reference instead. + if (asset.HasValidAssetReference()) + { + return asset.asset.GetData().Reinterpret(1); + } + else + { + Debug.LogAssertion($"File {asset.GetAssetPath()} does not exist on disk. If you are trying to load Adaptive Probe Volumes from AssetBundles or Addressables, " + + "tick the \"Probe Volume Disable Streaming Assets\" project setting in the Graphics tab when building the Player."); + return default; + } + } + } + // Prepare read commands. // Reallocate read commands buffer if needed. if (!m_ReadCommandBuffer.IsCreated || m_ReadCommandBuffer.Length < cellIndices.Count) @@ -1065,5 +1115,19 @@ namespace UnityEngine.Rendering return size; } + + internal bool HasSameSceneGUIDs(ProbeVolumeBakingSet other) + { + var otherSceneGUIDs = other.sceneGUIDs; + if (m_SceneGUIDs.Count != otherSceneGUIDs.Count) + return false; + + for (var i = 0; i < m_SceneGUIDs.Count; ++i) + { + if (m_SceneGUIDs[i] != otherSceneGUIDs[i]) + return false; + } + return true; + } } } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeGIContributor.cs b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeGIContributor.cs index 54b46791..83e44b93 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeGIContributor.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeGIContributor.cs @@ -390,10 +390,14 @@ namespace UnityEngine.Rendering var filteredPrototypes = new List(); foreach (var treeProto in terrain.treePrototypes) { - int treeProtoLayerMask = 1 << treeProto.component.gameObject.layer; + // check if the mesh renderer exists + if (treeProto.component != null) + { + int treeProtoLayerMask = 1 << treeProto.component.gameObject.layer; - if ((treeProtoLayerMask & layerMask) != 0) - filteredPrototypes.Add(treeProto); + if ((treeProtoLayerMask & layerMask) != 0) + filteredPrototypes.Add(treeProto); + } } var terrainContrib = new TerrainContributor() diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumePerSceneData.cs b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumePerSceneData.cs index 639f3087..4fc973f5 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumePerSceneData.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumePerSceneData.cs @@ -78,7 +78,7 @@ namespace UnityEngine.Rendering #if UNITY_EDITOR // Check if we are trying to load APV data for a scene which has not enabled APV (or it was removed) - var bakedData = serializedBakingSet.GetSceneBakeData(sceneGUID); + var bakedData = serializedBakingSet.GetSceneBakeData(sceneGUID, addIfMissing: false); if (bakedData != null && bakedData.hasProbeVolume == false) return; #endif @@ -97,9 +97,10 @@ namespace UnityEngine.Rendering { #if UNITY_EDITOR // In the editor, always refresh the GUID as it may become out of date is scene is duplicated or other weird things - // This field is serialized, so it will be available in standalones, where it can't change anymore + // This field is serialized, so it will be available in standalones, where it can't change anymore. + // Only change the GUID if the new one is valid. var newGUID = gameObject.scene.GetGUID(); - if (newGUID != sceneGUID) + if (newGUID != sceneGUID && new GUID(newGUID) != default) { sceneGUID = newGUID; EditorUtility.SetDirty(this); diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeStreamableAsset.cs b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeStreamableAsset.cs index 4f60b151..c21c10b4 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeStreamableAsset.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeStreamableAsset.cs @@ -43,6 +43,9 @@ namespace UnityEngine.Rendering m_StreamableCellDescs = cellDescs; m_ElementSize = elementSize; m_StreamableAssetPath = Path.Combine(Path.Combine(apvStreamingAssetsPath, bakingSetGUID), m_AssetGUID + ".bytes"); +#if UNITY_EDITOR + EnsureAssetLoaded(); +#endif } internal void RefreshAssetPath() @@ -63,9 +66,16 @@ namespace UnityEngine.Rendering return m_FinalAssetPath; } + internal bool HasValidAssetReference() + { + return m_Asset != null && m_Asset.bytes != null; + } + unsafe public bool FileExists() { #if UNITY_EDITOR + if (HasValidAssetReference()) + return true; if (File.Exists(GetAssetPath())) return true; // File may not exist if it was moved, refresh path in this case @@ -89,9 +99,16 @@ namespace UnityEngine.Rendering m_FinalAssetPath = ""; } - public void UpdateAssetReference(bool useStreamingAsset) + // Ensures that the asset is referenced via Unity's serialization layer. + public void EnsureAssetLoaded() + { + m_Asset = AssetDatabase.LoadAssetAtPath(GetAssetPath()); + } + + // Temporarily clear the asset reference. Used to prevent serialization of the asset when we are using the StreamingAssets codepath. + public void ClearAssetReferenceForBuild() { - m_Asset = useStreamingAsset ? null : AssetDatabase.LoadAssetAtPath(GetAssetPath()); + m_Asset = null; } #endif diff --git a/Packages/com.unity.render-pipelines.core/Runtime/PostProcessing/IPostProcessComponent.cs b/Packages/com.unity.render-pipelines.core/Runtime/PostProcessing/IPostProcessComponent.cs index 7dd3f4e5..8c154a31 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/PostProcessing/IPostProcessComponent.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/PostProcessing/IPostProcessComponent.cs @@ -16,7 +16,7 @@ namespace UnityEngine.Rendering /// /// Tells if the post process can run the effect on-tile or if it needs a full pass. /// - /// True if it can run on-tile, otherwise false. + /// true if it can run on-tile, false otherwise. [Obsolete("Unused #from(2023.1)", false)] bool IsTileCompatible() => false; } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/PostProcessing/LensFlareCommonSRP.cs b/Packages/com.unity.render-pipelines.core/Runtime/PostProcessing/LensFlareCommonSRP.cs index 49c57b5e..20ecdb6b 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/PostProcessing/LensFlareCommonSRP.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/PostProcessing/LensFlareCommonSRP.cs @@ -6,8 +6,17 @@ using UnityEngine.Experimental.Rendering; namespace UnityEngine.Rendering { /// - /// Common code for all Data-Driven Lens Flare used + /// Provides methods for implementing lens flares in a render pipeline. /// + /// + /// The High Definition Render Pipeline (HDRP) and Universal Render Pipeline (URP) use this class for their lens flare implementation. The class supports both screen space lens flares and quad-based lens flares. + /// You must call the methods of `LensFlareCommonSRP` at several places inside the Scriptable Render Pipeline (SRP). At minimum, you must call the method. + /// You can use any of these methods in a `Monobehaviour` script. + /// + /// . + /// + /// Note that only one `LensFlareCommonSRP` can be alive at any point. To call members of this class, use the property. + /// public sealed class LensFlareCommonSRP { private static LensFlareCommonSRP m_Instance = null; @@ -38,7 +47,7 @@ namespace UnityEngine.Rendering private static List m_AvailableIndicies = new List(); /// - /// Max lens-flares-with-occlusion supported + /// Defines how many lens flare with occlusion are supported in the view at any time. /// public static int maxLensFlareWithOcclusion = 128; @@ -103,30 +112,47 @@ namespace UnityEngine.Rendering { } - private static readonly bool s_SupportsLensFlare16bitsFormat = SystemInfo.IsFormatSupported(GraphicsFormat.R16_SFloat, GraphicsFormatUsage.Render); - private static readonly bool s_SupportsLensFlare32bitsFormat = SystemInfo.IsFormatSupported(GraphicsFormat.R32_SFloat, GraphicsFormatUsage.Render); + static readonly bool s_SupportsLensFlare16bitsFormat = SystemInfo.IsFormatSupported(GraphicsFormat.R16_SFloat, GraphicsFormatUsage.Render); + static readonly bool s_SupportsLensFlare32bitsFormat = SystemInfo.IsFormatSupported(GraphicsFormat.R32_SFloat, GraphicsFormatUsage.Render); + static readonly bool s_SupportsLensFlare16bitsFormatWithLoadStore = SystemInfo.IsFormatSupported(GraphicsFormat.R16_SFloat, GraphicsFormatUsage.LoadStore); + static readonly bool s_SupportsLensFlare32bitsFormatWithLoadStore = SystemInfo.IsFormatSupported(GraphicsFormat.R32_SFloat, GraphicsFormatUsage.LoadStore); - /// - /// Check if we can use an OcclusionRT - /// - /// return true if we can have the OcclusionRT - static public bool IsOcclusionRTCompatible() + // UUM-91313: Some Android Vulkan devices (Adreno 540) don't support R16_SFloat with GraphicsFormatUsage.LoadStore, + // which is required when creating a render texture with enableRandomWrite flag. Random writes are only needed by + // the merge step (compute shader using the texture as UAV), so we enable the flag only if merging is enabled. + static bool requireOcclusionRTRandomWrite => mergeNeeded > 0; + + static bool CheckOcclusionBasedOnDeviceType() { #if UNITY_SERVER return false; #else - return SystemInfo.graphicsDeviceType != GraphicsDeviceType.OpenGLES3 && - SystemInfo.graphicsDeviceType != GraphicsDeviceType.OpenGLCore && - SystemInfo.graphicsDeviceType != GraphicsDeviceType.Null && - SystemInfo.graphicsDeviceType != GraphicsDeviceType.WebGPU && - (s_SupportsLensFlare16bitsFormat || s_SupportsLensFlare32bitsFormat); //Caching this, because SupportsRenderTextureFormat allocates memory. Go figure. + return SystemInfo.graphicsDeviceType != GraphicsDeviceType.Null && + SystemInfo.graphicsDeviceType != GraphicsDeviceType.OpenGLES3 && + SystemInfo.graphicsDeviceType != GraphicsDeviceType.OpenGLCore && + SystemInfo.graphicsDeviceType != GraphicsDeviceType.WebGPU; #endif } + /// + /// Check if we can create OcclusionRT texture to be used as render target + /// + /// Returns true if a supported format is found + public static bool IsOcclusionRTCompatible() + { + if (requireOcclusionRTRandomWrite) + { + return CheckOcclusionBasedOnDeviceType() && + (s_SupportsLensFlare16bitsFormatWithLoadStore || s_SupportsLensFlare32bitsFormatWithLoadStore); + } + return CheckOcclusionBasedOnDeviceType() && + (s_SupportsLensFlare16bitsFormat || s_SupportsLensFlare32bitsFormat); + } + static GraphicsFormat GetOcclusionRTFormat() { // SystemInfo.graphicsDeviceType == {GraphicsDeviceType.Direct3D12, GraphicsDeviceType.GameCoreXboxSeries, GraphicsDeviceType.XboxOneD3D12, GraphicsDeviceType.PlayStation5, ...} - if (s_SupportsLensFlare16bitsFormat) + if (requireOcclusionRTRandomWrite ? s_SupportsLensFlare16bitsFormatWithLoadStore : s_SupportsLensFlare16bitsFormat) return GraphicsFormat.R16_SFloat; else // Needed a R32_SFloat for Metal or/and DirectX < 11.3 @@ -134,8 +160,11 @@ namespace UnityEngine.Rendering } /// - /// Initialization function which must be called by the SRP. + /// Initializes the lens flares. You must call this method. /// + /// + /// You usually call `Initialize` in the constructor. + /// static public void Initialize() { frameIdx = 0; @@ -150,16 +179,19 @@ namespace UnityEngine.Rendering width: maxLensFlareWithOcclusion, height: Mathf.Max(mergeNeeded * (maxLensFlareWithOcclusionTemporalSample + 1), 1), format: GetOcclusionRTFormat(), - slices: TextureXR.slices, - enableRandomWrite: true, + slices: TextureXR.slices, + enableRandomWrite: requireOcclusionRTRandomWrite, dimension: TextureDimension.Tex2DArray); } } } /// - /// Disposal function, must be called by the SRP to release all internal textures. + /// Releases all internal textures. /// + /// + /// Usually, `Dispose` is called in the function. + /// static public void Dispose() { if (IsOcclusionRTCompatible()) @@ -173,8 +205,11 @@ namespace UnityEngine.Rendering } /// - /// Current unique instance + /// Current unique instance. /// + /// + /// Use this property to call other members of this class and make sure that only one lens flare system is running at any time. + /// public static LensFlareCommonSRP Instance { get @@ -196,9 +231,18 @@ namespace UnityEngine.Rendering private System.Collections.Generic.List Data { get { return LensFlareCommonSRP.m_Data; } } /// - /// Check if we have at least one Lens Flare added on the pool + /// Checks if at least one lens flare has been added to the pool. /// - /// true if no Lens Flare were added + /// + /// You can use this method to check if there are any lens flares to render before rendering the lens flares. + /// + /// + /// if (!LensFlareCommonSRP.Instance.IsEmpty()) + /// { + /// LensFlareCommonSRP.DoLensFlareDataDrivenCommon(...); + /// } + /// + /// `true` if no lens flare were added public bool IsEmpty() { return Data.Count == 0; @@ -217,8 +261,12 @@ namespace UnityEngine.Rendering } /// - /// Add a new lens flare component on the pool. + /// Adds a new lens flare component for rendering. /// + /// + /// When is used, this method is called automatically when the lens flare is enabled. + /// You don't need to call this function unless you're manually removing lens flare data using . + /// /// The new data added public void AddData(LensFlareComponentSRP newData) { @@ -231,8 +279,11 @@ namespace UnityEngine.Rendering } /// - /// Remove a lens flare data which exist in the pool. + /// Removes a lens flare data from rendering. /// + /// + /// When is used, this method is called automatically when the lens flare is disabled. + /// /// The data which exist in the pool public void RemoveData(LensFlareComponentSRP data) { @@ -251,8 +302,44 @@ namespace UnityEngine.Rendering /// - /// Attenuation by Light Shape for Point Light + /// Obtains the attenuation for a point light. /// + /// + /// This method can be used to help compute the light attenuation to pass to + /// + /// + /// + /// To handle more than one light type, write a dedicated function to compute the attenuation using these helpers + /// + /// + /// static float GetLensFlareLightAttenuation(Light light, Camera cam, Vector3 wo) + /// { + /// switch (light.type) + /// { + /// case LightType.Directional: + /// return LensFlareCommonSRP.ShapeAttenuationDirLight(light.transform.forward, cam.transform.forward); + /// case LightType.Point: + /// // Do nothing point are omnidirectional for the lens flare + /// return LensFlareCommonSRP.ShapeAttenuationPointLight(); + /// case LightType.Spot: + /// float innerSpotPercent01 = 1; + /// return LensFlareCommonSRP.ShapeAttenuationSpotConeLight(light.transform.forward, wo, light.spotAngle, light.innerSpotAngle / 180.0f); + /// case LightType.Pyramid: + /// return LensFlareCommonSRP.ShapeAttenuationSpotPyramidLight(light.transform.forward, wo); + /// case LightType.Box: + /// return LensFlareCommonSRP.ShapeAttenuationSpotBoxLight(light.transform.forward, wo); + /// case LightType.Rectangle: + /// return LensFlareCommonSRP.ShapeAttenuationAreaRectangleLight(light.transform.forward, wo); + /// case LightType.Tube: + /// float shapeWidth = 1; // Get this data from an external source if our render pipeline supports tube lights. + /// return LensFlareCommonSRP.ShapeAttenuationAreaTubeLight(light.transform.position, light.transform.right, shapeWidth, cam); + /// case LightType.Disc: + /// return LensFlareCommonSRP.ShapeAttenuationAreaDiscLight(light.transform.forward, wo); + /// default: throw new Exception($"GetLensFlareLightAttenuation HDLightType Unknown {typeof(LightType)}: {light.type}"); + /// } + /// } + /// + /// /// Attenuation Factor static public float ShapeAttenuationPointLight() { @@ -260,24 +347,96 @@ namespace UnityEngine.Rendering } /// - /// Attenuation by Light Shape for Directional Light + /// Obtains the attenuation for a directional light. /// /// Forward Vector of Directional Light /// Vector pointing to the eye /// Attenuation Factor + /// + /// This method can be used to help compute the light attenuation to pass to + /// + /// + /// + /// To handle more than one light type, write a dedicated function to compute the attenuation using these helpers + /// + /// + /// static float GetLensFlareLightAttenuation(Light light, Camera cam, Vector3 wo) + /// { + /// switch (light.type) + /// { + /// case LightType.Directional: + /// return LensFlareCommonSRP.ShapeAttenuationDirLight(light.transform.forward, cam.transform.forward); + /// case LightType.Point: + /// // Do nothing point are omnidirectional for the lens flare + /// return LensFlareCommonSRP.ShapeAttenuationPointLight(); + /// case LightType.Spot: + /// float innerSpotPercent01 = 1; + /// return LensFlareCommonSRP.ShapeAttenuationSpotConeLight(light.transform.forward, wo, light.spotAngle, light.innerSpotAngle / 180.0f); + /// case LightType.Pyramid: + /// return LensFlareCommonSRP.ShapeAttenuationSpotPyramidLight(light.transform.forward, wo); + /// case LightType.Box: + /// return LensFlareCommonSRP.ShapeAttenuationSpotBoxLight(light.transform.forward, wo); + /// case LightType.Rectangle: + /// return LensFlareCommonSRP.ShapeAttenuationAreaRectangleLight(light.transform.forward, wo); + /// case LightType.Tube: + /// float shapeWidth = 1; // Get this data from an external source if our render pipeline supports tube lights. + /// return LensFlareCommonSRP.ShapeAttenuationAreaTubeLight(light.transform.position, light.transform.right, shapeWidth, cam); + /// case LightType.Disc: + /// return LensFlareCommonSRP.ShapeAttenuationAreaDiscLight(light.transform.forward, wo); + /// default: throw new Exception($"GetLensFlareLightAttenuation HDLightType Unknown {typeof(LightType)}: {light.type}"); + /// } + /// } + /// + /// static public float ShapeAttenuationDirLight(Vector3 forward, Vector3 wo) { return Mathf.Max(Vector3.Dot(-forward, wo), 0.0f); } /// - /// Attenuation by Light Shape for Spot Light with Cone Shape + /// Obtains the attenuation for a cone spot light. /// /// Forward Vector of Directional Light /// Vector pointing to the eye /// The angle of the light's spotlight cone in degrees. /// Get the inner spot radius between 0 and 1. /// Attenuation Factor + /// + /// This method can be used to help compute the light attenuation to pass to + /// + /// + /// + /// To handle more than one light type, write a dedicated function to compute the attenuation using these helpers + /// + /// + /// static float GetLensFlareLightAttenuation(Light light, Camera cam, Vector3 wo) + /// { + /// switch (light.type) + /// { + /// case LightType.Directional: + /// return LensFlareCommonSRP.ShapeAttenuationDirLight(light.transform.forward, cam.transform.forward); + /// case LightType.Point: + /// // Do nothing point are omnidirectional for the lens flare + /// return LensFlareCommonSRP.ShapeAttenuationPointLight(); + /// case LightType.Spot: + /// float innerSpotPercent01 = 1; + /// return LensFlareCommonSRP.ShapeAttenuationSpotConeLight(light.transform.forward, wo, light.spotAngle, light.innerSpotAngle / 180.0f); + /// case LightType.Pyramid: + /// return LensFlareCommonSRP.ShapeAttenuationSpotPyramidLight(light.transform.forward, wo); + /// case LightType.Box: + /// return LensFlareCommonSRP.ShapeAttenuationSpotBoxLight(light.transform.forward, wo); + /// case LightType.Rectangle: + /// return LensFlareCommonSRP.ShapeAttenuationAreaRectangleLight(light.transform.forward, wo); + /// case LightType.Tube: + /// float shapeWidth = 1; // Get this data from an external source if our render pipeline supports tube lights. + /// return LensFlareCommonSRP.ShapeAttenuationAreaTubeLight(light.transform.position, light.transform.right, shapeWidth, cam); + /// case LightType.Disc: + /// return LensFlareCommonSRP.ShapeAttenuationAreaDiscLight(light.transform.forward, wo); + /// default: throw new Exception($"GetLensFlareLightAttenuation HDLightType Unknown {typeof(LightType)}: {light.type}"); + /// } + /// } + /// + /// static public float ShapeAttenuationSpotConeLight(Vector3 forward, Vector3 wo, float spotAngle, float innerSpotPercent01) { float outerDot = Mathf.Max(Mathf.Cos(0.5f * spotAngle * Mathf.Deg2Rad), 0.0f); @@ -287,35 +446,143 @@ namespace UnityEngine.Rendering } /// - /// Attenuation by Light Shape for Spot Light with Box Shape + /// Obtains the attenuation for a box spot light. /// /// Forward Vector of Directional Light /// Vector pointing to the eye /// Attenuation Factor + /// + /// This method can be used to help compute the light attenuation to pass to + /// + /// + /// + /// To handle more than one light type, write a dedicated function to compute the attenuation using these helpers + /// + /// + /// static float GetLensFlareLightAttenuation(Light light, Camera cam, Vector3 wo) + /// { + /// switch (light.type) + /// { + /// case LightType.Directional: + /// return LensFlareCommonSRP.ShapeAttenuationDirLight(light.transform.forward, cam.transform.forward); + /// case LightType.Point: + /// // Do nothing point are omnidirectional for the lens flare + /// return LensFlareCommonSRP.ShapeAttenuationPointLight(); + /// case LightType.Spot: + /// float innerSpotPercent01 = 1; + /// return LensFlareCommonSRP.ShapeAttenuationSpotConeLight(light.transform.forward, wo, light.spotAngle, light.innerSpotAngle / 180.0f); + /// case LightType.Pyramid: + /// return LensFlareCommonSRP.ShapeAttenuationSpotPyramidLight(light.transform.forward, wo); + /// case LightType.Box: + /// return LensFlareCommonSRP.ShapeAttenuationSpotBoxLight(light.transform.forward, wo); + /// case LightType.Rectangle: + /// return LensFlareCommonSRP.ShapeAttenuationAreaRectangleLight(light.transform.forward, wo); + /// case LightType.Tube: + /// float shapeWidth = 1; // Get this data from an external source if our render pipeline supports tube lights. + /// return LensFlareCommonSRP.ShapeAttenuationAreaTubeLight(light.transform.position, light.transform.right, shapeWidth, cam); + /// case LightType.Disc: + /// return LensFlareCommonSRP.ShapeAttenuationAreaDiscLight(light.transform.forward, wo); + /// default: throw new Exception($"GetLensFlareLightAttenuation HDLightType Unknown {typeof(LightType)}: {light.type}"); + /// } + /// } + /// + /// static public float ShapeAttenuationSpotBoxLight(Vector3 forward, Vector3 wo) { return Mathf.Max(Mathf.Sign(Vector3.Dot(forward, wo)), 0.0f); } /// - /// Attenuation by Light Shape for Spot Light with Pyramid Shape + /// Obtains the attenuation for a pyramid spot light. /// /// Forward Vector of Directional Light /// Vector pointing to the eye /// Attenuation Factor + /// + /// This method can be used to help compute the light attenuation to pass to + /// + /// + /// + /// To handle more than one light type, write a dedicated function to compute the attenuation using these helpers + /// + /// + /// static float GetLensFlareLightAttenuation(Light light, Camera cam, Vector3 wo) + /// { + /// switch (light.type) + /// { + /// case LightType.Directional: + /// return LensFlareCommonSRP.ShapeAttenuationDirLight(light.transform.forward, cam.transform.forward); + /// case LightType.Point: + /// // Do nothing point are omnidirectional for the lens flare + /// return LensFlareCommonSRP.ShapeAttenuationPointLight(); + /// case LightType.Spot: + /// float innerSpotPercent01 = 1; + /// return LensFlareCommonSRP.ShapeAttenuationSpotConeLight(light.transform.forward, wo, light.spotAngle, light.innerSpotAngle / 180.0f); + /// case LightType.Pyramid: + /// return LensFlareCommonSRP.ShapeAttenuationSpotPyramidLight(light.transform.forward, wo); + /// case LightType.Box: + /// return LensFlareCommonSRP.ShapeAttenuationSpotBoxLight(light.transform.forward, wo); + /// case LightType.Rectangle: + /// return LensFlareCommonSRP.ShapeAttenuationAreaRectangleLight(light.transform.forward, wo); + /// case LightType.Tube: + /// float shapeWidth = 1; // Get this data from an external source if our render pipeline supports tube lights. + /// return LensFlareCommonSRP.ShapeAttenuationAreaTubeLight(light.transform.position, light.transform.right, shapeWidth, cam); + /// case LightType.Disc: + /// return LensFlareCommonSRP.ShapeAttenuationAreaDiscLight(light.transform.forward, wo); + /// default: throw new Exception($"GetLensFlareLightAttenuation HDLightType Unknown {typeof(LightType)}: {light.type}"); + /// } + /// } + /// + /// static public float ShapeAttenuationSpotPyramidLight(Vector3 forward, Vector3 wo) { return ShapeAttenuationSpotBoxLight(forward, wo); } /// - /// Attenuation by Light Shape for Area Light with Tube Shape + /// Obtains the attenuation for a tube light. /// /// World Space position of the Light /// Vector pointing to the side (right or left) or the light /// Width (half extent) of the tube light /// Camera rendering the Tube Light /// Attenuation Factor + /// + /// This method can be used to help compute the light attenuation to pass to + /// + /// + /// + /// To handle more than one light type, write a dedicated function to compute the attenuation using these helpers + /// + /// + /// static float GetLensFlareLightAttenuation(Light light, Camera cam, Vector3 wo) + /// { + /// switch (light.type) + /// { + /// case LightType.Directional: + /// return LensFlareCommonSRP.ShapeAttenuationDirLight(light.transform.forward, cam.transform.forward); + /// case LightType.Point: + /// // Do nothing point are omnidirectional for the lens flare + /// return LensFlareCommonSRP.ShapeAttenuationPointLight(); + /// case LightType.Spot: + /// float innerSpotPercent01 = 1; + /// return LensFlareCommonSRP.ShapeAttenuationSpotConeLight(light.transform.forward, wo, light.spotAngle, light.innerSpotAngle / 180.0f); + /// case LightType.Pyramid: + /// return LensFlareCommonSRP.ShapeAttenuationSpotPyramidLight(light.transform.forward, wo); + /// case LightType.Box: + /// return LensFlareCommonSRP.ShapeAttenuationSpotBoxLight(light.transform.forward, wo); + /// case LightType.Rectangle: + /// return LensFlareCommonSRP.ShapeAttenuationAreaRectangleLight(light.transform.forward, wo); + /// case LightType.Tube: + /// float shapeWidth = 1; // Get this data from an external source if our render pipeline supports tube lights. + /// return LensFlareCommonSRP.ShapeAttenuationAreaTubeLight(light.transform.position, light.transform.right, shapeWidth, cam); + /// case LightType.Disc: + /// return LensFlareCommonSRP.ShapeAttenuationAreaDiscLight(light.transform.forward, wo); + /// default: throw new Exception($"GetLensFlareLightAttenuation HDLightType Unknown {typeof(LightType)}: {light.type}"); + /// } + /// } + /// + /// static public float ShapeAttenuationAreaTubeLight(Vector3 lightPositionWS, Vector3 lightSide, float lightWidth, Camera cam) { // Ref: https://hal.archives-ouvertes.fr/hal-02155101/document @@ -383,22 +650,94 @@ namespace UnityEngine.Rendering } /// - /// Attenuation by Light Shape for Area Light with Rectangular Shape + /// Obtains the attenuation for a rectangle light. /// /// Forward Vector of Directional Light /// Vector pointing to the eye /// Attenuation Factor + /// + /// This method can be used to help compute the light attenuation to pass to + /// + /// + /// + /// To handle more than one light type, write a dedicated function to compute the attenuation using these helpers + /// + /// + /// static float GetLensFlareLightAttenuation(Light light, Camera cam, Vector3 wo) + /// { + /// switch (light.type) + /// { + /// case LightType.Directional: + /// return LensFlareCommonSRP.ShapeAttenuationDirLight(light.transform.forward, cam.transform.forward); + /// case LightType.Point: + /// // Do nothing point are omnidirectional for the lens flare + /// return LensFlareCommonSRP.ShapeAttenuationPointLight(); + /// case LightType.Spot: + /// float innerSpotPercent01 = 1; + /// return LensFlareCommonSRP.ShapeAttenuationSpotConeLight(light.transform.forward, wo, light.spotAngle, light.innerSpotAngle / 180.0f); + /// case LightType.Pyramid: + /// return LensFlareCommonSRP.ShapeAttenuationSpotPyramidLight(light.transform.forward, wo); + /// case LightType.Box: + /// return LensFlareCommonSRP.ShapeAttenuationSpotBoxLight(light.transform.forward, wo); + /// case LightType.Rectangle: + /// return LensFlareCommonSRP.ShapeAttenuationAreaRectangleLight(light.transform.forward, wo); + /// case LightType.Tube: + /// float shapeWidth = 1; // Get this data from an external source if our render pipeline supports tube lights. + /// return LensFlareCommonSRP.ShapeAttenuationAreaTubeLight(light.transform.position, light.transform.right, shapeWidth, cam); + /// case LightType.Disc: + /// return LensFlareCommonSRP.ShapeAttenuationAreaDiscLight(light.transform.forward, wo); + /// default: throw new Exception($"GetLensFlareLightAttenuation HDLightType Unknown {typeof(LightType)}: {light.type}"); + /// } + /// } + /// + /// static public float ShapeAttenuationAreaRectangleLight(Vector3 forward, Vector3 wo) { return ShapeAttenuateForwardLight(forward, wo); } /// - /// Attenuation by Light Shape for Area Light with Disc Shape + /// Obtains the attenuation for a disc light. /// /// Forward Vector of Directional Light /// Vector pointing to the eye /// Attenuation Factor + /// + /// This method can be used to help compute the light attenuation to pass to + /// + /// + /// + /// To handle more than one light type, write a dedicated function to compute the attenuation using these helpers + /// + /// + /// static float GetLensFlareLightAttenuation(Light light, Camera cam, Vector3 wo) + /// { + /// switch (light.type) + /// { + /// case LightType.Directional: + /// return LensFlareCommonSRP.ShapeAttenuationDirLight(light.transform.forward, cam.transform.forward); + /// case LightType.Point: + /// // Do nothing point are omnidirectional for the lens flare + /// return LensFlareCommonSRP.ShapeAttenuationPointLight(); + /// case LightType.Spot: + /// float innerSpotPercent01 = 1; + /// return LensFlareCommonSRP.ShapeAttenuationSpotConeLight(light.transform.forward, wo, light.spotAngle, light.innerSpotAngle / 180.0f); + /// case LightType.Pyramid: + /// return LensFlareCommonSRP.ShapeAttenuationSpotPyramidLight(light.transform.forward, wo); + /// case LightType.Box: + /// return LensFlareCommonSRP.ShapeAttenuationSpotBoxLight(light.transform.forward, wo); + /// case LightType.Rectangle: + /// return LensFlareCommonSRP.ShapeAttenuationAreaRectangleLight(light.transform.forward, wo); + /// case LightType.Tube: + /// float shapeWidth = 1; // Get this data from an external source if our render pipeline supports tube lights. + /// return LensFlareCommonSRP.ShapeAttenuationAreaTubeLight(light.transform.position, light.transform.right, shapeWidth, cam); + /// case LightType.Disc: + /// return LensFlareCommonSRP.ShapeAttenuationAreaDiscLight(light.transform.forward, wo); + /// default: throw new Exception($"GetLensFlareLightAttenuation HDLightType Unknown {typeof(LightType)}: {light.type}"); + /// } + /// } + /// + /// static public float ShapeAttenuationAreaDiscLight(Vector3 forward, Vector3 wo) { return ShapeAttenuateForwardLight(forward, wo); @@ -420,7 +759,7 @@ namespace UnityEngine.Rendering } /// - /// Compute internal parameters needed to render single flare + /// Computes the internal parameters needed to render a single flare. /// /// The screen position of the flare. /// The scale of translation applied to the flare. @@ -512,8 +851,11 @@ namespace UnityEngine.Rendering } /// - /// Check if at least one LensFlareComponentSRP request occlusion from background clouds + /// Checks if at least one `LensFlareComponentSRP` requests occlusion from environment effects. /// + /// + /// Environment occlusion can be enabled by setting to true. + /// /// Camera /// true if cloud occlusion is requested static public bool IsCloudLayerOpacityNeeded(Camera cam) @@ -594,9 +936,9 @@ namespace UnityEngine.Rendering #endif /// - /// Effective Job of drawing the set of Lens Flare registered + /// Renders the set of lens flare registered. /// - /// Lens Flare material (HDRP or URP shader) + /// lens flare material (HDRP or URP shader) /// Camera /// XR Infos /// Index of the SinglePass XR @@ -646,9 +988,9 @@ namespace UnityEngine.Rendering } /// - /// Effective Job of drawing the set of Lens Flare registered + /// Renders the set of lens flare registered. /// - /// Lens Flare material (HDRP or URP shader) + /// lens flare material (HDRP or URP shader) /// Camera /// XRPass data. /// XR multipass ID. @@ -684,9 +1026,9 @@ namespace UnityEngine.Rendering } /// - /// Effective Job of drawing the set of Lens Flare registered + /// Renders the set of lens flare registered. /// - /// Lens Flare material (HDRP or URP shader) + /// lens flare material (HDRP or URP shader) /// Camera /// XRPass data. /// XR multipass ID. @@ -741,9 +1083,9 @@ namespace UnityEngine.Rendering } /// - /// Effective Job of drawing the set of Lens Flare registered + /// Computes the occlusion of lens flare using the depth buffer and additional occlusion textures if not null. /// - /// Lens Flare material (HDRP or URP shader) + /// Lens flare material (HDRP or URP shader) /// Camera /// XRPass data. /// XR multipass ID. @@ -977,8 +1319,11 @@ namespace UnityEngine.Rendering } /// - /// Function that process a single element of a LensFlareDataSRP, this function is used on scene/game view and on the inspector for the thumbnail. + /// Renders a single element of a LensFlareDataSRP, this function is used on scene/game view and on the inspector for the thumbnail. /// + /// + /// Can be used to draw aa single lens flare for editor or preview purpose. + /// /// Single LensFlare asset we need to process. /// Command Buffer. /// Color Modulation from Component? @@ -987,7 +1332,7 @@ namespace UnityEngine.Rendering /// Scale from component /// Shader used on URP or HDRP. /// Screen Position - /// Allow Lens Flare offscreen + /// Allow lens flare offscreen /// Screen Ratio /// _FlareData1 used internally by the shader. /// true if we are on preview on the inspector @@ -1322,9 +1667,9 @@ namespace UnityEngine.Rendering } /// - /// Effective Job of drawing the set of Lens Flare registered + /// Renders the set of lens flare registered. /// - /// Lens Flare material (HDRP or URP shader) + /// Lens flare material (HDRP or URP shader) /// Camera /// Viewport used for rendering and XR applied. /// XRPass data. @@ -1356,7 +1701,7 @@ namespace UnityEngine.Rendering /// ShaderID for the FlareData2 /// ShaderID for the FlareData3 /// ShaderID for the FlareData4 - /// Debug View which setup black background to see only Lens Flare + /// Debug View which setup black background to see only lens flare [Obsolete("Use DoLensFlareDataDrivenCommon without _FlareOcclusionRemapTex.._FlareData4 parameters.")] static public void DoLensFlareDataDrivenCommon(Material lensFlareShader, Camera cam, Rect viewport, XRPass xr, int xrIndex, float actualWidth, float actualHeight, @@ -1387,9 +1732,12 @@ namespace UnityEngine.Rendering } /// - /// Effective Job of drawing the set of Lens Flare registered + /// Renders all visible lens flares. /// - /// Lens Flare material (HDRP or URP shader) + /// + /// Call this function during the post processing phase of the Render Pipeline. + /// + /// Lens flare material (HDRP or URP shader) /// Camera /// Viewport used for rendering and XR applied. /// XRPass data. @@ -1409,7 +1757,7 @@ namespace UnityEngine.Rendering /// Sun Occlusion Texture from VolumetricCloud on HDRP or null /// Source Render Target which contains the Color Buffer /// Delegate to which return return the Attenuation of the light based on their shape which uses the functions ShapeAttenuation...(...), must reimplemented per SRP - /// Debug View which setup black background to see only Lens Flare + /// Debug View which setup black background to see only lens flare static public void DoLensFlareDataDrivenCommon(Material lensFlareShader, Camera cam, Rect viewport, XRPass xr, int xrIndex, float actualWidth, float actualHeight, bool usePanini, float paniniDistance, float paniniCropToFit, @@ -1436,9 +1784,9 @@ namespace UnityEngine.Rendering } /// - /// Effective Job of drawing the set of Lens Flare registered + /// Renders the set of lens flare registered. /// - /// Lens Flare material (HDRP or URP shader) + /// Lens flare material (HDRP or URP shader) /// Camera /// Viewport used for rendering and XR applied. /// XRPass data. @@ -1470,7 +1818,7 @@ namespace UnityEngine.Rendering /// ShaderID for the FlareData2 /// ShaderID for the FlareData3 /// ShaderID for the FlareData4 - /// Debug View which setup black background to see only Lens Flare + /// Debug View which setup black background to see only lens flare [Obsolete("Use DoLensFlareDataDrivenCommon without _FlareOcclusionRemapTex.._FlareData4 parameters.")] static public void DoLensFlareDataDrivenCommon(Material lensFlareShader, Camera cam, Rect viewport, XRPass xr, int xrIndex, float actualWidth, float actualHeight, @@ -1501,9 +1849,12 @@ namespace UnityEngine.Rendering } /// - /// Effective Job of drawing the set of Lens Flare registered + /// Renders all visible lens flares. /// - /// Lens Flare material (HDRP or URP shader) + /// + /// Call this function during the post processing phase of the Render Pipeline. + /// + /// Lens flare material (HDRP or URP shader) /// Camera /// Viewport used for rendering and XR applied. /// XRPass data. @@ -1523,7 +1874,7 @@ namespace UnityEngine.Rendering /// Sun Occlusion Texture from VolumetricCloud on HDRP or null /// Source Render Target which contains the Color Buffer /// Delegate to which return return the Attenuation of the light based on their shape which uses the functions ShapeAttenuation...(...), must reimplemented per SRP - /// Debug View which setup black background to see only Lens Flare + /// Debug View which setup black background to see only lens flare static public void DoLensFlareDataDrivenCommon(Material lensFlareShader, Camera cam, Rect viewport, XRPass xr, int xrIndex, float actualWidth, float actualHeight, bool usePanini, float paniniDistance, float paniniCropToFit, @@ -1739,9 +2090,12 @@ namespace UnityEngine.Rendering } /// - /// Effective Job of drawing Lens Flare Screen Space. + /// Renders the screen space lens flare effect. /// - /// Lens Flare material (HDRP or URP shader) + /// + /// Call this function during the post processing of the render pipeline after the bloom. + /// + /// Lens flare material (HDRP or URP shader) /// Camera /// Width actually used for rendering after dynamic resolution and XR is applied. /// Height actually used for rendering after dynamic resolution and XR is applied. @@ -1757,7 +2111,7 @@ namespace UnityEngine.Rendering /// streaksIntensity, streaksLength, streaksOrientation, streaksThreshold /// downsampleStreak, warpedFlareScaleX, warpedFlareScaleY, freeSlot /// UnsafeCommandBuffer - /// Result RT for the Lens Flare Screen Space + /// Result RT for the lens flare Screen Space /// Information if we are in debug mode or not static public void DoLensFlareScreenSpaceCommon( Material lensFlareShader, @@ -1801,9 +2155,12 @@ namespace UnityEngine.Rendering } /// - /// Effective Job of drawing Lens Flare Screen Space. + /// Renders the screen space lens flare effect. /// - /// Lens Flare material (HDRP or URP shader) + /// + /// Call this function during the post processing of the render pipeline after the bloom. + /// + /// Lens flare material (HDRP or URP shader) /// Camera /// Width actually used for rendering after dynamic resolution and XR is applied. /// Height actually used for rendering after dynamic resolution and XR is applied. @@ -1819,7 +2176,7 @@ namespace UnityEngine.Rendering /// streaksIntensity, streaksLength, streaksOrientation, streaksThreshold /// downsampleStreak, warpedFlareScaleX, warpedFlareScaleY, freeSlot /// Command Buffer - /// Result RT for the Lens Flare Screen Space + /// Result RT for the lens flare Screen Space /// ShaderID for the original bloom texture /// ShaderID for the LensFlareScreenSpaceResultTexture texture /// ShaderID for the LensFlareScreenSpaceSpectralLut texture @@ -1886,9 +2243,12 @@ namespace UnityEngine.Rendering } /// - /// Effective Job of drawing Lens Flare Screen Space. + /// Renders the screen space lens flare effect. /// - /// Lens Flare material (HDRP or URP shader) + /// + /// Call this function during the post processing of the render pipeline after the bloom. + /// + /// Lens flare material (HDRP or URP shader) /// Camera /// Width actually used for rendering after dynamic resolution and XR is applied. /// Height actually used for rendering after dynamic resolution and XR is applied. @@ -1904,7 +2264,7 @@ namespace UnityEngine.Rendering /// streaksIntensity, streaksLength, streaksOrientation, streaksThreshold /// downsampleStreak, warpedFlareScaleX, warpedFlareScaleY, freeSlot /// Command Buffer - /// Result RT for the Lens Flare Screen Space + /// Result RT for the lens flare Screen Space /// Information if we are in debug mode or not static public void DoLensFlareScreenSpaceCommon( Material lensFlareShader, diff --git a/Packages/com.unity.render-pipelines.core/Runtime/PostProcessing/LensFlareDataSRP.cs b/Packages/com.unity.render-pipelines.core/Runtime/PostProcessing/LensFlareDataSRP.cs index 675b9c52..61945b8f 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/PostProcessing/LensFlareDataSRP.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/PostProcessing/LensFlareDataSRP.cs @@ -467,6 +467,7 @@ namespace UnityEngine.Rendering } /// LensFlareDataSRP defines a Lens Flare with a set of LensFlareDataElementSRP + [CurrentPipelineHelpURL("shared/lens-flare/lens-flare-asset")] [System.Serializable] public sealed class LensFlareDataSRP : ScriptableObject { diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/CompilerContextData.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/CompilerContextData.cs index 324109f6..c1a42b35 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/CompilerContextData.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/CompilerContextData.cs @@ -43,41 +43,59 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler // Datastructure that contains passes and dependencies and allow you to iterate and reason on them more like a graph internal class CompilerContextData : IDisposable, RenderGraph.ICompiledGraph { - public CompilerContextData(int estimatedNumPasses) + public CompilerContextData() { - passData = new NativeList(estimatedNumPasses, AllocatorManager.Persistent); fences = new Dictionary(); - passNames = new DynamicArray(estimatedNumPasses, false); // T in NativeList cannot contain managed types, so the names are stored separately - inputData = new NativeList(estimatedNumPasses * 2, AllocatorManager.Persistent); - outputData = new NativeList(estimatedNumPasses * 2, AllocatorManager.Persistent); - fragmentData = new NativeList(estimatedNumPasses * 4, AllocatorManager.Persistent); - randomAccessResourceData = new NativeList(4, AllocatorManager.Persistent); // We assume not a lot of passes use random write resources = new ResourcesData(); - nativePassData = new NativeList(estimatedNumPasses, AllocatorManager.Persistent);// assume nothing gets merged - nativeSubPassData = new NativeList(estimatedNumPasses, AllocatorManager.Persistent);// there should "never" be more subpasses than graph passes - createData = new NativeList(estimatedNumPasses * 2, AllocatorManager.Persistent); // assume every pass creates two resources - destroyData = new NativeList(estimatedNumPasses * 2, AllocatorManager.Persistent); // assume every pass destroys two resources + passNames = new DynamicArray(0, false); // T in NativeList cannot contain managed types, so the names are stored separately } - public void Initialize(RenderGraphResourceRegistry resourceRegistry) + void AllocateNativeDataStructuresIfNeeded(int estimatedNumPasses) + { + // Only first init or if Dispose() has been called through RenderGraph.Cleanup() + if (!m_AreNativeListsAllocated) + { + // These are risky heuristics that only work because we purposely estimate a very high number of passes + // We need to fix this with a proper size computation + passData = new NativeList(estimatedNumPasses, AllocatorManager.Persistent); + inputData = new NativeList(estimatedNumPasses * 2, AllocatorManager.Persistent); + outputData = new NativeList(estimatedNumPasses * 2, AllocatorManager.Persistent); + fragmentData = new NativeList(estimatedNumPasses * 4, AllocatorManager.Persistent); + randomAccessResourceData = new NativeList(4, AllocatorManager.Persistent); // We assume not a lot of passes use random write + nativePassData = new NativeList(estimatedNumPasses, AllocatorManager.Persistent);// assume nothing gets merged + nativeSubPassData = new NativeList(estimatedNumPasses, AllocatorManager.Persistent);// there should "never" be more subpasses than graph passes + createData = new NativeList(estimatedNumPasses * 2, AllocatorManager.Persistent); // assume every pass creates two resources + destroyData = new NativeList(estimatedNumPasses * 2, AllocatorManager.Persistent); // assume every pass destroys two resources + + m_AreNativeListsAllocated = true; + } + } + + public void Initialize(RenderGraphResourceRegistry resourceRegistry, int estimatedNumPasses) { resources.Initialize(resourceRegistry); + passNames.Reserve(estimatedNumPasses, false); + AllocateNativeDataStructuresIfNeeded(estimatedNumPasses); } public void Clear() { - passData.Clear(); - fences.Clear(); passNames.Clear(); - inputData.Clear(); - outputData.Clear(); - fragmentData.Clear(); - randomAccessResourceData.Clear(); resources.Clear(); - nativePassData.Clear(); - nativeSubPassData.Clear(); - createData.Clear(); - destroyData.Clear(); + + if (m_AreNativeListsAllocated) + { + passData.Clear(); + fences.Clear(); + inputData.Clear(); + outputData.Clear(); + fragmentData.Clear(); + randomAccessResourceData.Clear(); + nativePassData.Clear(); + nativeSubPassData.Clear(); + createData.Clear(); + destroyData.Clear(); + } } public ResourcesData resources; @@ -278,7 +296,7 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler // IDisposable implementation - bool m_Disposed; + bool m_AreNativeListsAllocated = false; ~CompilerContextData() => Cleanup(); @@ -290,10 +308,10 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler void Cleanup() { - if (!m_Disposed) - { - resources.Dispose(); + resources.Dispose(); + if (m_AreNativeListsAllocated) + { passData.Dispose(); inputData.Dispose(); outputData.Dispose(); @@ -303,7 +321,8 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler randomAccessResourceData.Dispose(); nativePassData.Dispose(); nativeSubPassData.Dispose(); - m_Disposed = true; + + m_AreNativeListsAllocated = false; } } } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/NativePassCompiler.Debug.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/NativePassCompiler.Debug.cs index e05b1f41..c3d6ec3d 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/NativePassCompiler.Debug.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/NativePassCompiler.Debug.cs @@ -93,6 +93,12 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler case PassBreakReason.EndOfGraph: message += "The pass is the last pass in the graph."; break; + case PassBreakReason.DifferentShadingRateImages: + message += $"{prevPassName} uses a different shading rate image than {passName}."; + break; + case PassBreakReason.DifferentShadingRateStates: + message += $"{prevPassName} uses different shading rate states than {passName}."; + break; default: throw new ArgumentOutOfRangeException(); } @@ -158,6 +164,22 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler resourceWriteLists[pair].Add(renderGraphPass.index); } } + foreach (var read in renderGraphPass.transientResourceList[type]) + { + if (read.type == (RenderGraphResourceType)type && read.index == resIndex) + { + // Transient resources are assumed to be read and write + + var pair = ((RenderGraphResourceType)type, resIndex); + if (!resourceReadLists.ContainsKey(pair)) + resourceReadLists[pair] = new List(); + resourceReadLists[pair].Add(renderGraphPass.index); + + if (!resourceWriteLists.ContainsKey(pair)) + resourceWriteLists[pair] = new List(); + resourceWriteLists[pair].Add(renderGraphPass.index); + } + } } } } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/NativePassCompiler.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/NativePassCompiler.cs index 86417959..ad71cfde 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/NativePassCompiler.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/NativePassCompiler.cs @@ -14,7 +14,8 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler public RenderGraphResourceRegistry m_ResourcesForDebugOnly; public List m_RenderPasses; public string debugName; - public bool disableCulling; + public bool disablePassCulling; + public bool disablePassMerging; } internal RenderGraphInputInfo graph; @@ -33,15 +34,12 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler public NativePassCompiler(RenderGraphCompilationCache cache) { m_CompilationCache = cache; - defaultContextData = new CompilerContextData(k_EstimatedPassCount); + defaultContextData = new CompilerContextData(); toVisitPassIds = new Stack(k_EstimatedPassCount); - m_BeginRenderPassAttachments = new NativeList(FixedAttachmentArray.MaxAttachments, Allocator.Persistent); } // IDisposable implementation - bool m_Disposed; - ~NativePassCompiler() => Cleanup(); public void Dispose() @@ -50,16 +48,19 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler GC.SuppressFinalize(this); } - void Cleanup() + public void Cleanup() { - if (!m_Disposed) + // If caching enabled, the two can be different + contextData?.Dispose(); + defaultContextData?.Dispose(); + + if (m_BeginRenderPassAttachments.IsCreated) { m_BeginRenderPassAttachments.Dispose(); - m_Disposed = true; } } - public bool Initialize(RenderGraphResourceRegistry resources, List renderPasses, bool disableCulling, string debugName, bool useCompilationCaching, int graphHash, int frameIndex) + public bool Initialize(RenderGraphResourceRegistry resources, List renderPasses, RenderGraphDebugParams debugParams, string debugName, bool useCompilationCaching, int graphHash, int frameIndex) { bool cached = false; if (!useCompilationCaching) @@ -69,7 +70,8 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler graph.m_ResourcesForDebugOnly = resources; graph.m_RenderPasses = renderPasses; - graph.disableCulling = disableCulling; + graph.disablePassCulling = debugParams.disablePassCulling; + graph.disablePassMerging = debugParams.disablePassMerging; graph.debugName = debugName; Clear(clearContextData: !useCompilationCaching); @@ -124,7 +126,7 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler { using (new ProfilingScope(ProfilingSampler.Get(NativeCompilerProfileId.NRPRGComp_SetupContextData))) { - contextData.Initialize(resources); + contextData.Initialize(resources, k_EstimatedPassCount); } } @@ -195,6 +197,14 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler } } + // shading rate + if (inputPass.hasShadingRateImage && + inputPass.shadingRateAccess.textureHandle.handle.IsValid()) + { + ctxPass.shadingRateImageIndex = ctx.fragmentData.Length; + ctx.AddToFragmentList(inputPass.shadingRateAccess, ctxPass.shadingRateImageIndex, 0); + } + // Grab offset in context fragment list to begin building the fragment input list ctxPass.firstFragmentInput = ctx.fragmentData.Length; @@ -290,7 +300,7 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler for (var i = 0; i < resourceTransCount; ++i) { - var resource = resourceTrans[i]; + var resource = resourceTrans[i]; // Mark this pass as reading from this version of the resource ctx.resources[resource].RegisterReadingPass(ctx, resource, passId, ctxPass.numInputs); @@ -328,7 +338,7 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler using (new ProfilingScope(ProfilingSampler.Get(NativeCompilerProfileId.NRPRGComp_CullNodes))) { // No need to go further if we don't enable culling - if (graph.disableCulling) + if (graph.disablePassCulling) return; // Cull all passes first @@ -365,6 +375,19 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler // Remove the connections from the list so they won't be visited again if (pass.culled) { + // If the culled pass was supposed to generate the latest version of a given resource, + // we need to decrement the latestVersionNumber of this resource + // because its last version will never be created due to its producer being culled + foreach (ref readonly var output in pass.Outputs(ctx)) + { + var outputResource = output.resource; + bool isOutputLastVersion = (outputResource.version == ctx.UnversionedResourceData(outputResource).latestVersionNumber); + + if (isOutputLastVersion) + ctx.UnversionedResourceData(outputResource).latestVersionNumber--; + } + + // Notifying the versioned resources that this pass is no longer reading them foreach (ref readonly var input in pass.Inputs(ctx)) { var inputResource = input.resource; @@ -420,7 +443,8 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler // There is an native pass currently open, try to add the current graph pass to it else { - var mergeTestResult = NativePassData.TryMerge(contextData, activeNativePassId, passIdx); + var mergeTestResult = graph.disablePassMerging ? new PassBreakAudit(PassBreakReason.PassMergingDisabled, passIdx) + : NativePassData.TryMerge(contextData, activeNativePassId, passIdx); // Merge failed, close current native render pass and create a new one if (mergeTestResult.reason != PassBreakReason.Merged) @@ -567,10 +591,14 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler if (pass.waitOnGraphicsFencePassId == -1) { ref var pointToVer = ref ctx.VersionedResourceData(inputResource); - ref var wPass = ref ctx.passData.ElementAt(pointToVer.writePassId); - if (wPass.asyncCompute != pass.asyncCompute) + // If no RG pass writes to the resource, no need to wait for anyone + if (pointToVer.written) { - pass.waitOnGraphicsFencePassId = wPass.passId; + ref var wPass = ref ctx.passData.ElementAt(pointToVer.writePassId); + if (wPass.asyncCompute != pass.asyncCompute) + { + pass.waitOnGraphicsFencePassId = wPass.passId; + } } } } @@ -1094,12 +1122,24 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler } [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] - private void ValidateAttachmentRenderTarget(in RenderTargetInfo attRenderTargetInfo, RenderGraphResourceRegistry resources, int nativePassWidth, int nativePassHeight, int nativePassMSAASamples) + private void ValidateAttachment(in RenderTargetInfo attRenderTargetInfo, RenderGraphResourceRegistry resources, int nativePassWidth, int nativePassHeight, int nativePassMSAASamples, bool isVrs) { if(RenderGraph.enableValidityChecks) { - if (attRenderTargetInfo.width != nativePassWidth || attRenderTargetInfo.height != nativePassHeight || attRenderTargetInfo.msaaSamples != nativePassMSAASamples) - throw new Exception("Low level rendergraph error: Attachments in renderpass do not match!"); + if (isVrs) + { + var tileSize = ShadingRateImage.GetAllocTileSize(nativePassWidth, nativePassHeight); + + if (attRenderTargetInfo.width != tileSize.x || attRenderTargetInfo.height != tileSize.y || attRenderTargetInfo.msaaSamples != 1) + { + throw new Exception("Low level rendergraph error: Shading rate image attachment in renderpass does not match!"); + } + } + else + { + if (attRenderTargetInfo.width != nativePassWidth || attRenderTargetInfo.height != nativePassHeight || attRenderTargetInfo.msaaSamples != nativePassMSAASamples) + throw new Exception("Low level rendergraph error: Attachments in renderpass do not match!"); + } } } @@ -1132,14 +1172,26 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler rgContext.cmd.SetFoveatedRenderingMode(FoveatedRenderingMode.Enabled); } + if (nativePass.hasShadingRateStates) + { + rgContext.cmd.SetShadingRateFragmentSize(nativePass.shadingRateFragmentSize); + rgContext.cmd.SetShadingRateCombiner(ShadingRateCombinerStage.Primitive, nativePass.primitiveShadingRateCombiner); + rgContext.cmd.SetShadingRateCombiner(ShadingRateCombinerStage.Fragment, nativePass.fragmentShadingRateCombiner); + } + // Filling the attachments array to be sent to the rendering command buffer + if(!m_BeginRenderPassAttachments.IsCreated) + m_BeginRenderPassAttachments = new NativeList(FixedAttachmentArray.MaxAttachments, Allocator.Persistent); + m_BeginRenderPassAttachments.Resize(attachmentCount, NativeArrayOptions.UninitializedMemory); for (var i = 0; i < attachmentCount; ++i) { ref var currAttachmentHandle = ref attachments[i].handle; resources.GetRenderTargetInfo(currAttachmentHandle, out var renderTargetInfo); - ValidateAttachmentRenderTarget(renderTargetInfo, resources, w, h, s); + + bool isVrs = (i == nativePass.shadingRateImageIndex); + ValidateAttachment(renderTargetInfo, resources, w, h, s, isVrs); ref var currBeginAttachment = ref m_BeginRenderPassAttachments.ElementAt(i); currBeginAttachment = new AttachmentDescriptor(renderTargetInfo.format); @@ -1228,7 +1280,7 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler } #endif - rgContext.cmd.BeginRenderPass(w, h, d, s, attachmentDescArray, depthAttachmentIndex, nativeSubPassArray, graphPassNamesForDebugSpan); + rgContext.cmd.BeginRenderPass(w, h, d, s, attachmentDescArray, depthAttachmentIndex, nativePass.shadingRateImageIndex, nativeSubPassArray, graphPassNamesForDebugSpan); #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle.Release(safetyHandle); @@ -1244,6 +1296,11 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler { using (new ProfilingScope(ProfilingSampler.Get(NativeCompilerProfileId.NRPRGComp_ExecuteDestroyResources))) { + // Unsafe pass might soon use temporary render targets, + // users can also use temporary data in their render graph execute nodes using public RenderGraphObjectPool API + // In both cases, we need to release these resources after the node execution + rgContext.renderGraphPool.ReleaseAllTempAlloc(); + if (pass.type == RenderGraphPassType.Raster && pass.nativePassIndex >= 0) { // For raster passes we need to destroy resources after all the subpasses at the end of the native renderpass @@ -1277,7 +1334,7 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler } } - internal unsafe void SetRandomWriteTarget(in CommandBuffer cmd, RenderGraphResourceRegistry resources, int index, ResourceHandle resource, bool preserveCounterValue = true) + internal unsafe void ExecuteSetRandomWriteTarget(in CommandBuffer cmd, RenderGraphResourceRegistry resources, int index, ResourceHandle resource, bool preserveCounterValue = true) { if (resource.type == RenderGraphResourceType.Texture) { @@ -1384,7 +1441,7 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler } var nrpBegan = false; - if (isRaster == true && pass.mergeState <= PassMergeState.Begin) + if (isRaster && pass.mergeState <= PassMergeState.Begin) { if (pass.nativePassIndex >= 0) { @@ -1414,7 +1471,7 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler { foreach (var randomWriteAttachment in pass.RandomWriteTextures(contextData)) { - SetRandomWriteTarget(rgContext.cmd, resources, randomWriteAttachment.index, randomWriteAttachment.resource); + ExecuteSetRandomWriteTarget(rgContext.cmd, resources, randomWriteAttachment.index, randomWriteAttachment.resource); } } @@ -1463,6 +1520,13 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler rgContext.cmd.EndRenderPass(); CommandBuffer.ThrowOnSetRenderTarget = false; inRenderPass = false; + + // VRS ShadingRate(Image) cannot be set inside a render pass (cmdBuf). + // ShadingRate is set before BeginRenderPass and here we ResetShadingRate after EndRenderPass. + if (nativePass.hasShadingRateStates || nativePass.hasShadingRateImage) + { + rgContext.cmd.ResetShadingRate(); + } } } } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/PassesData.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/PassesData.cs index ba880599..2b303faf 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/PassesData.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/PassesData.cs @@ -4,6 +4,7 @@ using System.Runtime.CompilerServices; using Unity.Collections.LowLevel.Unsafe; using UnityEngine.Rendering; using System.Collections.Generic; +using Unity.Collections; namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler { @@ -86,6 +87,10 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler public bool hasFoveatedRasterization; public int tag; // Arbitrary per node int used by various graph analysis tools + public ShadingRateFragmentSize shadingRateFragmentSize; + public ShadingRateCombiner primitiveShadingRateCombiner; + public ShadingRateCombiner fragmentShadingRateCombiner; + public PassMergeState mergeState; public int nativePassIndex; // Index of the native pass this pass belongs to public int nativeSubPassIndex; // Index of the native subpass this pass belongs to @@ -104,6 +109,7 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler public int numCreated; public int firstDestroy; //base+offset in CompilerContextData.destroyData (use the InputNodes iterator to iterate this more easily) public int numDestroyed; + public int shadingRateImageIndex; //base+offset in CompilerContextData.fragmentData (there is no iterator, there are always 2 if shading rate is used) public int fragmentInfoWidth; public int fragmentInfoHeight; @@ -118,7 +124,9 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler public bool beginNativeSubpass; // If true this is the first graph pass of a merged native subpass public bool fragmentInfoValid; public bool fragmentInfoHasDepth; + public bool fragmentInfoHasShadingRateImage => shadingRateImageIndex > 0; public bool insertGraphicsFence; // Whether this pass should insert a fence into the command buffer + public bool hasShadingRateStates; [MethodImpl(MethodImplOptions.AggressiveInlining)] public Name GetName(CompilerContextData ctx) => ctx.GetFullPassName(passId); @@ -162,6 +170,12 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler insertGraphicsFence = false; waitOnGraphicsFencePassId = -1; + + hasShadingRateStates = pass.hasShadingRateStates; + shadingRateFragmentSize = pass.shadingRateFragmentSize; + primitiveShadingRateCombiner = pass.primitiveShadingRateCombiner; + fragmentShadingRateCombiner = pass.fragmentShadingRateCombiner; + shadingRateImageIndex = -1; } // Helper func to reset and initialize existing PassData struct directly in a data container without costly deep copy (~120bytes) when adding it @@ -205,6 +219,12 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler insertGraphicsFence = false; waitOnGraphicsFencePassId = -1; + + hasShadingRateStates = pass.hasShadingRateStates; + shadingRateFragmentSize = pass.shadingRateFragmentSize; + primitiveShadingRateCombiner = pass.primitiveShadingRateCombiner; + fragmentShadingRateCombiner = pass.fragmentShadingRateCombiner; + shadingRateImageIndex = -1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -219,6 +239,10 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler public readonly ReadOnlySpan Fragments(CompilerContextData ctx) => ctx.fragmentData.MakeReadOnlySpan(firstFragment, numFragments); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public PassFragmentData ShadingRateImage(CompilerContextData ctx) + => ctx.fragmentData[shadingRateImageIndex]; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly ReadOnlySpan FragmentInputs(CompilerContextData ctx) => ctx.fragmentData.MakeReadOnlySpan(firstFragmentInput, numFragmentInputs); @@ -473,6 +497,9 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler SubPassLimitReached, // Addind the next pass would have generated more subpasses than allowed EndOfGraph, // The last pass in the graph was reached FRStateMismatch, // One pass is using foveated rendering and the other not + DifferentShadingRateImages, // The next pass uses a different shading rate image (and we only allow one in a whole NRP) + DifferentShadingRateStates, // The next pass uses different shading rate states (and we only allow one set in a whole NRP) + PassMergingDisabled, // Wasn't merged because pass merging is disabled Merged, // I actually got merged Count @@ -504,7 +531,10 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler $"The limit of {FixedAttachmentArray.MaxAttachments} native pass attachments would be exceeded when merging with the next pass.", $"The limit of {NativePassCompiler.k_MaxSubpass} native subpasses would be exceeded when merging with the next pass.", "This is the last pass in the graph, there are no other passes to merge.", - "The the next pass uses a different foveated rendering state", + "The next pass uses a different foveated rendering state", + "The next pass uses a different shading rate image", + "The next pass uses a different shading rate rendering state", + "Pass merging is disabled so this pass was not merged", "The next pass got merged into this pass.", }; } @@ -530,8 +560,16 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler public int height; public int volumeDepth; public int samples; + public int shadingRateImageIndex; + public bool hasDepth; public bool hasFoveatedRasterization; + public bool hasShadingRateImage => shadingRateImageIndex >= 0; + public bool hasShadingRateStates; + + public ShadingRateFragmentSize shadingRateFragmentSize; + public ShadingRateCombiner primitiveShadingRateCombiner; + public ShadingRateCombiner fragmentShadingRateCombiner; public NativePassData(ref PassData pass, CompilerContextData ctx) { @@ -565,10 +603,51 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler fragments.Add(fragment); } + // Shading rate and foveation are distinct systems and mutually exclusive. + // Foveation always taking precedence over VRS. + if (pass.fragmentInfoHasShadingRateImage && !hasFoveatedRasterization) + { + shadingRateImageIndex = fragments.size; + fragments.Add(pass.ShadingRateImage(ctx)); + } + else + shadingRateImageIndex = -1; + + hasShadingRateStates = pass.hasShadingRateStates && !hasFoveatedRasterization; + shadingRateFragmentSize = pass.shadingRateFragmentSize; + primitiveShadingRateCombiner = pass.primitiveShadingRateCombiner; + fragmentShadingRateCombiner = pass.fragmentShadingRateCombiner; + // Graph pass is added as the first native subpass TryMergeNativeSubPass(ctx, ref this, ref pass); } + // Gets the best SubPassFlag for a pass that originally had no depth attachment, that we want to merge with this pass. + public SubPassFlags GetSubPassFlagForMerging() + { + // We should not be calling this method if native pass doesn't have depth. + if (hasDepth == false) + { + throw new Exception("SubPassFlag for merging can not be determined if native pass doesn't have a depth attachment"); + } + + // Only do this for mobile using Vulkan. +#if (PLATFORM_ANDROID) + if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Vulkan) + { + // Depth attachment is always at index 0. + return (fragments[0].accessFlags.HasFlag(AccessFlags.Write)) ? SubPassFlags.None : SubPassFlags.ReadOnlyDepth; + } + else + { + return SubPassFlags.ReadOnlyDepth; + } +#else + // By default flag this subpass as ReadOnlyDepth. + return SubPassFlags.ReadOnlyDepth; +#endif + } + public void Clear() { firstGraphPass = 0; @@ -594,7 +673,9 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler return ctx.passData.MakeReadOnlySpan(firstGraphPass, numGraphPasses); } - var actualPasses = new PassData[numGraphPasses]; + var actualPasses = + new NativeArray(numGraphPasses, Allocator.Temp, + NativeArrayOptions.UninitializedMemory); for (int i = firstGraphPass, index = 0; i < lastGraphPass + 1; ++i) { @@ -666,6 +747,38 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler { return new PassBreakAudit(PassBreakReason.FRStateMismatch, passIdToMerge); } + + // Different shading rate images; only allow one per NRP + if (nativePass.hasShadingRateImage != passToMerge.fragmentInfoHasShadingRateImage) + { + return new PassBreakAudit(PassBreakReason.DifferentShadingRateImages, passIdToMerge); + } + + if (nativePass.hasShadingRateImage) + { + var passToMergeSRI = passToMerge.ShadingRateImage(contextData); + var nativePassSRI = nativePass.fragments[nativePass.shadingRateImageIndex]; + if (nativePassSRI.resource.index != passToMergeSRI.resource.index) + { + return new PassBreakAudit(PassBreakReason.DifferentShadingRateImages, passIdToMerge); + } + } + + // Different shading rate states; only allow one set per NRP + if (nativePass.hasShadingRateStates != passToMerge.hasShadingRateStates) + { + return new PassBreakAudit(PassBreakReason.DifferentShadingRateStates, passIdToMerge); + } + + if (nativePass.hasShadingRateStates) + { + if (nativePass.shadingRateFragmentSize != passToMerge.shadingRateFragmentSize || + nativePass.primitiveShadingRateCombiner != passToMerge.primitiveShadingRateCombiner || + nativePass.fragmentShadingRateCombiner != passToMerge.fragmentShadingRateCombiner) + { + return new PassBreakAudit(PassBreakReason.DifferentShadingRateStates, passIdToMerge); + } + } } // Check the non-fragment inputs of this pass, if they are generated by the current open native pass we can't merge @@ -786,11 +899,11 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler // nextSubpass is expensive on some platforms (even if its' essentially a no-op as it's using the same attachments). SubPassFlags flags = SubPassFlags.None; - // If depth ends up being bound only because of merging we explicitly say that we will not write to it - // which could have been implied by leaving the flag to None + // If depth ends up being bound only because of merging if (!passToMerge.fragmentInfoHasDepth && nativePass.hasDepth) { - flags = SubPassFlags.ReadOnlyDepth; + // Set SubPassFlags to best match the pass we are trying to merge with + flags = nativePass.GetSubPassFlagForMerging(); } // MRT attachments @@ -902,11 +1015,11 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler return; } - // If depth ends up being bound only because of merging we explicitly say that we will not write to it - // which could have been implied by leaving the flag to None + // If depth ends up being bound only because of merging if (!passToMerge.fragmentInfoHasDepth && nativePass.hasDepth) { - desc.flags = SubPassFlags.ReadOnlyDepth; + // Set SubPassFlags to best match the pass we are trying to merge with + desc.flags = nativePass.GetSubPassFlagForMerging(); } // MRT attachments @@ -974,6 +1087,14 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler } } + // Shading rate images + { + if (passToMerge.fragmentInfoHasShadingRateImage) + { + desc.flags |= SubPassFlags.UseShadingRateImage; + } + } + if (nativePass.numNativeSubPasses == 0 || !NativePassCompiler.IsSameNativeSubPass(ref desc, ref contextData.nativeSubPassData.ElementAt( nativePass.firstNativeSubPass + @@ -1028,11 +1149,11 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler ref var nativeSubPassDescriptor = ref contextData.nativeSubPassData.ElementAt(lastVisitedNativeSubpassIdx); - // If depth ends up being bound only because of merging we explicitly say that we will not write to it - // which could have been implied by leaving the flag to None + // If depth ends up being bound only because of merging if (!currGraphPass.fragmentInfoHasDepth && nativePass.hasDepth) { - nativeSubPassDescriptor.flags = SubPassFlags.ReadOnlyDepth; + // Set SubPassFlags to best match the pass we are trying to merge with + nativeSubPassDescriptor.flags = nativePass.GetSubPassFlagForMerging(); } // MRT attachments @@ -1124,13 +1245,19 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler ref var existingAttach = ref nativePass.fragments[i]; if (PassFragmentData.SameSubResource(existingAttach, newAttach)) { - // Update the attached version access flags and version - existingAttach.accessFlags |= newAttach.accessFlags; + var newAttachAccessFlags = newAttach.accessFlags; + // If the existing attachment accessFlag has Discard flag, remove Read flag from newAttach flags, as the content has not to be Loaded + if (existingAttach.accessFlags.HasFlag(AccessFlags.Discard)) + newAttachAccessFlags = newAttachAccessFlags & ~AccessFlags.Read; + + existingAttach.accessFlags |= newAttachAccessFlags; + #if DEVELOPMENT_BUILD || UNITY_EDITOR if (existingAttach.resource.version > newAttach.resource.version) throw new Exception("Adding an older version while a higher version is already registered with the pass."); #endif - existingAttach.resource.version = newAttach.resource.version; + var prevAttachRes = existingAttach.resource; + existingAttach.resource = new ResourceHandle(prevAttachRes, newAttach.resource.version); alreadyAttached = true; break; } @@ -1151,13 +1278,19 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler ref var existingAttach = ref nativePass.fragments[i]; if (PassFragmentData.SameSubResource(existingAttach, newAttach)) { - // Update the attached version access flags and version - existingAttach.accessFlags |= newAttach.accessFlags; + var newAttachAccessFlags = newAttach.accessFlags; + // If the existing attachment accessFlag has Discard flag, remove Read flag from newAttach flags, as the content has not to be Loaded + if (existingAttach.accessFlags.HasFlag(AccessFlags.Discard)) + newAttachAccessFlags = newAttachAccessFlags & ~AccessFlags.Read; + + existingAttach.accessFlags |= newAttachAccessFlags; + #if DEVELOPMENT_BUILD || UNITY_EDITOR if (existingAttach.resource.version > newAttach.resource.version) throw new Exception("Adding an older version while a higher version is already registered with the pass."); #endif - existingAttach.resource.version = newAttach.resource.version; + var prevAttachRes = existingAttach.resource; + existingAttach.resource = new ResourceHandle(prevAttachRes, newAttach.resource.version); alreadyAttached = true; break; } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/ResourcesData.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/ResourcesData.cs index fba9b1f2..c1330b14 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/ResourcesData.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/ResourcesData.cs @@ -30,7 +30,7 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler public readonly int volumeDepth; public readonly int msaaSamples; - public readonly int latestVersionNumber; + public int latestVersionNumber; // mostly readonly, can be decremented only if all passes using the last version are culled public readonly bool clear; // graph.m_Resources.GetTextureResourceDesc(fragment.resource).clearBuffer; public readonly bool discard; // graph.m_Resources.GetTextureResourceDesc(fragment.resource).discardBuffer; @@ -207,27 +207,38 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler resourceNames = new DynamicArray[(int)RenderGraphResourceType.Count]; for (int t = 0; t < (int)RenderGraphResourceType.Count; t++) - { - // Note: All these lists are allocated with zero capacity, they will be resized in Initialize when - // the amount of resources is known. - versionedData[t] = new NativeList(0, AllocatorManager.Persistent); - unversionedData[t] = new NativeList(0, AllocatorManager.Persistent); - readerData[t] = new NativeList(0, AllocatorManager.Persistent); resourceNames[t] = new DynamicArray(0); // T in NativeList cannot contain managed types, so the names are stored separately - } } public void Clear() { for (int t = 0; t < (int)RenderGraphResourceType.Count; t++) { - unversionedData[t].Clear(); - versionedData[t].Clear(); - readerData[t].Clear(); + if (unversionedData[t].IsCreated) + unversionedData[t].Clear(); + + if (versionedData[t].IsCreated) + versionedData[t].Clear(); + + if (readerData[t].IsCreated) + readerData[t].Clear(); + resourceNames[t].Clear(); } } + void AllocateAndResizeNativeListIfNeeded(ref NativeList nativeList, int size, NativeArrayOptions options) where T : unmanaged + { + // Allocate the first time or if Dispose() has been called through RenderGraph.Cleanup() + // Length remains 0, list is still empty + if (!nativeList.IsCreated) + nativeList = new NativeList(size, AllocatorManager.Persistent); + + // Resize the list (it will allocate if necessary) + // List is not empty anymore + nativeList.Resize(size, options); + } + public void Initialize(RenderGraphResourceRegistry resources) { uint maxReaders = 0; @@ -238,9 +249,9 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler RenderGraphResourceType resourceType = (RenderGraphResourceType) t; var numResources = resources.GetResourceCount(resourceType); - // For each resource type, resize the buffer (only allocate if bigger) - // We don't clear the buffer as we reinitialize it right after - unversionedData[t].Resize(numResources, NativeArrayOptions.UninitializedMemory); + // We don't clear the list as we reinitialize it right after + AllocateAndResizeNativeListIfNeeded(ref unversionedData[t], numResources, NativeArrayOptions.UninitializedMemory); + resourceNames[t].Resize(numResources, true); if (numResources > 0) // Null Resource @@ -301,8 +312,8 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler MaxVersions = (int)maxWriters + 1; // Clear the other caching structures, they will be filled later - versionedData[t].Resize(MaxVersions * numResources, NativeArrayOptions.ClearMemory); - readerData[t].Resize(MaxVersions * MaxReaders * numResources, NativeArrayOptions.ClearMemory); + AllocateAndResizeNativeListIfNeeded(ref versionedData[t], MaxVersions * numResources, NativeArrayOptions.ClearMemory); + AllocateAndResizeNativeListIfNeeded(ref readerData[t], MaxVersions * MaxReaders * numResources, NativeArrayOptions.ClearMemory); } } @@ -340,9 +351,14 @@ namespace UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler { for (int t = 0; t < (int)RenderGraphResourceType.Count; t++) { - versionedData[t].Dispose(); - unversionedData[t].Dispose(); - readerData[t].Dispose(); + if (versionedData[t].IsCreated) + versionedData[t].Dispose(); + + if (unversionedData[t].IsCreated) + unversionedData[t].Dispose(); + + if (readerData[t].IsCreated) + readerData[t].Dispose(); } } } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Debug/RenderGraphDebugParams.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Debug/RenderGraphDebugParams.cs index edc3ccdc..be738e2c 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Debug/RenderGraphDebugParams.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Debug/RenderGraphDebugParams.cs @@ -11,6 +11,7 @@ namespace UnityEngine.Rendering.RenderGraphModule public bool clearRenderTargetsAtCreation; public bool clearRenderTargetsAtRelease; public bool disablePassCulling; + public bool disablePassMerging; public bool immediateMode; public bool enableLogging; public bool logFrameInformation; @@ -21,6 +22,7 @@ namespace UnityEngine.Rendering.RenderGraphModule clearRenderTargetsAtCreation = false; clearRenderTargetsAtRelease = false; disablePassCulling = false; + disablePassMerging = false; immediateMode = false; enableLogging = false; logFrameInformation = false; @@ -32,6 +34,7 @@ namespace UnityEngine.Rendering.RenderGraphModule public static readonly NameAndTooltip ClearRenderTargetsAtCreation = new() { name = "Clear Render Targets At Creation", tooltip = "Enable to clear all render textures before any rendergraph passes to check if some clears are missing." }; public static readonly NameAndTooltip ClearRenderTargetsAtFree = new() { name = "Clear Render Targets When Freed", tooltip = "Enable to clear all render textures when textures are freed by the graph to detect use after free of textures." }; public static readonly NameAndTooltip DisablePassCulling = new() { name = "Disable Pass Culling", tooltip = "Enable to temporarily disable culling to assess if a pass is culled." }; + public static readonly NameAndTooltip DisablePassMerging = new() { name = "Disable Pass Merging", tooltip = "Enable to temporarily disable pass merging to diagnose issues or analyze performance." }; public static readonly NameAndTooltip ImmediateMode = new() { name = "Immediate Mode", tooltip = "Enable to force render graph to execute all passes in the order you registered them." }; public static readonly NameAndTooltip EnableLogging = new() { name = "Enable Logging", tooltip = "Enable to allow HDRP to capture information in the log." }; public static readonly NameAndTooltip LogFrameInformation = new() { name = "Log Frame Information", tooltip = "Enable to log information output from each frame." }; @@ -69,6 +72,12 @@ namespace UnityEngine.Rendering.RenderGraphModule setter = value => disablePassCulling = value }, new DebugUI.BoolField + { + nameAndTooltip = Strings.DisablePassMerging, + getter = () => disablePassMerging, + setter = value => disablePassMerging = value + }, + new DebugUI.BoolField { nameAndTooltip = Strings.ImmediateMode, getter = () => immediateMode, @@ -144,6 +153,7 @@ namespace UnityEngine.Rendering.RenderGraphModule return clearRenderTargetsAtCreation || clearRenderTargetsAtRelease || disablePassCulling || + disablePassMerging || immediateMode || enableLogging; } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/IRenderGraphBuilder.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/IRenderGraphBuilder.cs index 932cfdde..cb9e6d8e 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/IRenderGraphBuilder.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/IRenderGraphBuilder.cs @@ -327,6 +327,25 @@ namespace UnityEngine.Rendering.RenderGraphModule /// The value passed to 'input'. You should not use the returned value it will be removed in the future. BufferHandle UseBufferRandomAccess(BufferHandle tex, int index, bool preserveCounterValue, AccessFlags flags = AccessFlags.Read); + /// + /// Enables Variable Rate Shading (VRS) on the current rasterization pass. Rasterization will use the texture to determine the rate of fragment shader invocation. + /// + /// Shading rate image (SRI) Texture to use during this pass. + void SetShadingRateImageAttachment(in TextureHandle tex); + + /// + /// Set shading rate fragment size. + /// + /// Shading rate fragment size to set. + void SetShadingRateFragmentSize(ShadingRateFragmentSize shadingRateFragmentSize); + + /// + /// Set shading rate combiner. + /// + /// Shading rate combiner stage to apply combiner to. + /// Shading rate combiner to set. + void SetShadingRateCombiner(ShadingRateCombinerStage stage, ShadingRateCombiner combiner); + /// /// Specify the render function to use for this pass. /// A call to this is mandatory for the pass to be valid. diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.Compiler.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.Compiler.cs index 6fac60ec..9a49da16 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.Compiler.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.Compiler.cs @@ -15,7 +15,7 @@ namespace UnityEngine.Rendering.RenderGraphModule if (nativeCompiler == null) nativeCompiler = new NativePassCompiler(m_CompilationCache); - bool compilationIsCached = nativeCompiler.Initialize(m_Resources, m_RenderPasses, m_DebugParameters.disablePassCulling, name, m_EnableCompilationCaching, graphHash, m_ExecutionCount); + bool compilationIsCached = nativeCompiler.Initialize(m_Resources, m_RenderPasses, m_DebugParameters, name, m_EnableCompilationCaching, graphHash, m_ExecutionCount); if (!compilationIsCached) nativeCompiler.Compile(m_Resources); diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.cs index a59c8efb..f28e7357 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.cs @@ -284,6 +284,8 @@ namespace UnityEngine.Rendering.RenderGraphModule public bool culledByRendererList; public bool hasSideEffect; public bool enableFoveatedRasterization; + public bool hasShadingRateImage; + public bool hasShadingRateStates; public void Reset(RenderGraphPass pass, int index) { @@ -293,6 +295,8 @@ namespace UnityEngine.Rendering.RenderGraphModule enableAsyncCompute = pass.enableAsyncCompute; allowPassCulling = pass.allowPassCulling; enableFoveatedRasterization = pass.enableFoveatedRasterization; + hasShadingRateImage = pass.hasShadingRateImage && !pass.enableFoveatedRasterization; + hasShadingRateStates = pass.hasShadingRateStates && !pass.enableFoveatedRasterization; if (resourceCreateList == null) { @@ -511,6 +515,10 @@ namespace UnityEngine.Rendering.RenderGraphModule /// public void Cleanup() { + // Usually done at the end of Execute step + // Also doing it here in case RG stopped before it + ClearCurrentCompiledGraph(); + m_Resources.Cleanup(); m_DefaultResources.Cleanup(); m_RenderGraphPool.Cleanup(); @@ -518,9 +526,11 @@ namespace UnityEngine.Rendering.RenderGraphModule s_RegisteredGraphs.Remove(this); onGraphUnregistered?.Invoke(this); - nativeCompiler?.contextData?.Dispose(); + nativeCompiler?.Cleanup(); m_CompilationCache?.Clear(); + + DelegateHashCodeUtils.ClearCache(); } internal RenderGraphDebugParams debugParams => m_DebugParameters; @@ -601,6 +611,20 @@ namespace UnityEngine.Rendering.RenderGraphModule return m_Resources.ImportTexture(rt); } + /// + /// Import an external Variable Rate Shading (VRS) textures to the RenderGraph. + /// Any pass writing to an imported texture will be considered having side effects and can't be automatically culled. + /// + /// External shading rate image RTHandle that needs to be imported. + /// New TextureHandle that represents the imported shading rate images in the context of this rendergraph. + public TextureHandle ImportShadingRateImageTexture(RTHandle rt) + { + if (ShadingRateInfo.supportsPerImageTile) + return m_Resources.ImportTexture(rt); + + return TextureHandle.nullHandle; + } + /// /// Import an external texture to the Render Graph. /// Any pass writing to an imported texture will be considered having side effects and can't be automatically culled. @@ -1096,7 +1120,7 @@ namespace UnityEngine.Rendering.RenderGraphModule [CallerLineNumber] int line = 0) where PassData : class, new() #endif { - var renderPass = m_RenderGraphPool.Get>(); + var renderPass = m_RenderGraphPool.Get>(); renderPass.Initialize(m_RenderPasses.Count, m_RenderGraphPool.Get(), passName, RenderGraphPassType.Legacy, sampler); renderPass.AllowGlobalState(true);// Old pass types allow global state by default as HDRP relies on it @@ -1335,7 +1359,7 @@ namespace UnityEngine.Rendering.RenderGraphModule internal DynamicArray GetCompiledPassInfos() { return m_CurrentCompiledGraph.compiledPassInfos; } // Internal for testing purpose only - internal void ClearCompiledGraph() + internal void ClearCurrentCompiledGraph() { ClearCompiledGraph(m_CurrentCompiledGraph, false); } @@ -2149,6 +2173,18 @@ namespace UnityEngine.Rendering.RenderGraphModule void PreRenderPassSetRenderTargets(in CompiledPassInfo passInfo, RenderGraphPass pass, InternalRenderGraphContext rgContext) { + if (passInfo.hasShadingRateImage) + { +#if DEVELOPMENT_BUILD || UNITY_EDITOR + if (!pass.shadingRateAccess.textureHandle.IsValid()) + { + throw new InvalidOperationException("MRT setup with invalid variable rate shading images."); + } +#endif + + CoreUtils.SetShadingRateImage(rgContext.cmd, m_Resources.GetTexture(pass.shadingRateAccess.textureHandle)); + } + var depthBufferIsValid = pass.depthAccess.textureHandle.IsValid(); if (depthBufferIsValid || pass.colorBufferMaxIndex != -1) { @@ -2219,6 +2255,13 @@ namespace UnityEngine.Rendering.RenderGraphModule if (passInfo.enableFoveatedRasterization) rgContext.cmd.SetFoveatedRenderingMode(FoveatedRenderingMode.Enabled); + if (passInfo.hasShadingRateStates) + { + rgContext.cmd.SetShadingRateFragmentSize(pass.shadingRateFragmentSize); + rgContext.cmd.SetShadingRateCombiner(ShadingRateCombinerStage.Primitive, pass.primitiveShadingRateCombiner); + rgContext.cmd.SetShadingRateCombiner(ShadingRateCombinerStage.Fragment, pass.fragmentShadingRateCombiner); + } + PreRenderPassSetRenderTargets(passInfo, pass, rgContext); if (passInfo.enableAsyncCompute) @@ -2253,6 +2296,9 @@ namespace UnityEngine.Rendering.RenderGraphModule void PostRenderPassExecute(ref CompiledPassInfo passInfo, RenderGraphPass pass, InternalRenderGraphContext rgContext) { + if (passInfo.hasShadingRateStates || passInfo.hasShadingRateImage) + rgContext.cmd.ResetShadingRate(); + foreach (var tex in pass.setGlobalsList) { rgContext.cmd.SetGlobalTexture(tex.Item2, tex.Item1); @@ -2519,7 +2565,7 @@ namespace UnityEngine.Rendering.RenderGraphModule newPass.syncFromPassIndex = passInfo.syncFromPassIndex; newPass.syncToPassIndex = passInfo.syncToPassIndex; - DebugData.s_PassScriptMetadata.TryGetValue(pass.name, out newPass.scriptInfo); + DebugData.s_PassScriptMetadata.TryGetValue(pass, out newPass.scriptInfo); for (int type = 0; type < (int)RenderGraphResourceType.Count; ++type) { diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphBuilders.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphBuilders.cs index 8d68e74d..c5248f75 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphBuilders.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphBuilders.cs @@ -513,5 +513,26 @@ namespace UnityEngine.Rendering.RenderGraphModule } } } + + public void SetShadingRateImageAttachment(in TextureHandle sriTextureHandle) + { + CheckNotUseFragment(sriTextureHandle); + + // shading rate image access flag is always read, only 1 mip and 1 slice + var newSriTextureHandle = new TextureHandle(); + newSriTextureHandle.handle = UseResource(sriTextureHandle.handle, AccessFlags.Read); + + m_RenderPass.SetShadingRateImage(newSriTextureHandle, AccessFlags.Read, 0, 0); + } + + public void SetShadingRateFragmentSize(ShadingRateFragmentSize shadingRateFragmentSize) + { + m_RenderPass.SetShadingRateFragmentSize(shadingRateFragmentSize); + } + + public void SetShadingRateCombiner(ShadingRateCombinerStage stage, ShadingRateCombiner combiner) + { + m_RenderPass.SetShadingRateCombiner(stage, combiner); + } } } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphCompilationCache.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphCompilationCache.cs index d32a0bae..ea74f3d9 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphCompilationCache.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphCompilationCache.cs @@ -38,7 +38,7 @@ class RenderGraphCompilationCache for (int i = 0; i < k_CachedGraphCount; ++i) { m_CompiledGraphPool.Push(new RenderGraph.CompiledGraph()); - m_NativeCompiledGraphPool.Push(new CompilerContextData(NativePassCompiler.k_EstimatedPassCount)); + m_NativeCompiledGraphPool.Push(new CompilerContextData()); } } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphDefaultResources.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphDefaultResources.cs index fed5297b..9bcb3d02 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphDefaultResources.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphDefaultResources.cs @@ -36,20 +36,37 @@ namespace UnityEngine.Rendering.RenderGraphModule internal RenderGraphDefaultResources() { - m_BlackTexture2D = RTHandles.Alloc(Texture2D.blackTexture); - m_WhiteTexture2D = RTHandles.Alloc(Texture2D.whiteTexture); - m_ShadowTexture2D = RTHandles.Alloc(1, 1, Experimental.Rendering.GraphicsFormat.D32_SFloat, isShadowMap: true, name: "DefaultShadowTexture"); + InitDefaultResourcesIfNeeded(); + } + + private void InitDefaultResourcesIfNeeded() + { + if (m_BlackTexture2D == null) + m_BlackTexture2D = RTHandles.Alloc(Texture2D.blackTexture); + + if (m_WhiteTexture2D == null) + m_WhiteTexture2D = RTHandles.Alloc(Texture2D.whiteTexture); + + if (m_ShadowTexture2D == null) + m_ShadowTexture2D = RTHandles.Alloc(1, 1, CoreUtils.GetDefaultDepthStencilFormat(), isShadowMap: true, name: "DefaultShadowTexture"); } internal void Cleanup() { - m_BlackTexture2D.Release(); - m_WhiteTexture2D.Release(); - m_ShadowTexture2D.Release(); + m_BlackTexture2D?.Release(); + m_BlackTexture2D = null; + + m_WhiteTexture2D?.Release(); + m_WhiteTexture2D = null; + + m_ShadowTexture2D?.Release(); + m_ShadowTexture2D = null; } internal void InitializeForRendering(RenderGraph renderGraph) { + InitDefaultResourcesIfNeeded(); + blackTexture = renderGraph.ImportTexture(m_BlackTexture2D, true); whiteTexture = renderGraph.ImportTexture(m_WhiteTexture2D, true); defaultShadowTexture = renderGraph.ImportTexture(m_ShadowTexture2D, true); diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphGlobalSettings.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphGlobalSettings.cs index 8dbdd727..8e142638 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphGlobalSettings.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphGlobalSettings.cs @@ -3,8 +3,33 @@ using System; namespace UnityEngine.Rendering { /// - /// Render Graph global settings class. + /// A graphics settings container for settings related to the Render Graph for all Scriptable Render Pipelines. /// + /// + /// To change those settings, go to Editor > Project Settings in the Graphics tab. + /// Changing this through the API is only allowed in the Editor. In the Player, this raises an error. + /// + /// + /// + /// This example demonstrates how to determine if your project uses RenderGraph's compilation caching. + /// + /// using UnityEngine.Rendering; + /// + /// public static class RenderGraphHelper + /// { + /// public static bool enableCompilationCaching + /// { + /// get + /// { + /// var gs = GraphicsSettings.GetRenderPipelineSettings<RenderGraphGlobalSettings>(); + /// if (gs == null) //not in SRP + /// return false; + /// return gs.enableCompilationCaching; + /// } + /// } + /// } + /// + /// [Serializable] [SupportedOnRenderPipeline] [Categorization.CategoryInfo(Name = "Render Graph", Order = 50)] diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphObjectPool.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphObjectPool.cs index 2f97dbe7..13146be8 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphObjectPool.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphObjectPool.cs @@ -110,7 +110,12 @@ namespace UnityEngine.Rendering.RenderGraphModule m_AllocatedMaterialPropertyBlocks.Clear(); } - + + internal bool IsEmpty() + { + return m_AllocatedArrays.Count == 0 && m_AllocatedMaterialPropertyBlocks.Count == 0; + } + // Regular pooling API. Only internal use for now internal T Get() where T : class, new() { diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphPass.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphPass.cs index c2d1f933..33736468 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphPass.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphPass.cs @@ -29,6 +29,14 @@ namespace UnityEngine.Rendering.RenderGraphModule public TextureAccess[] colorBufferAccess { get; protected set; } = new TextureAccess[RenderGraph.kMaxMRTCount]; public int colorBufferMaxIndex { get; protected set; } = -1; + public bool hasShadingRateImage { get; protected set; } + public TextureAccess shadingRateAccess { get; protected set; } + + public bool hasShadingRateStates { get; protected set; } + public ShadingRateFragmentSize shadingRateFragmentSize { get; protected set; } + public ShadingRateCombiner primitiveShadingRateCombiner { get; protected set; } + public ShadingRateCombiner fragmentShadingRateCombiner { get; protected set; } + // Used by native pass compiler only public TextureAccess[] fragmentInputAccess { get; protected set; } = new TextureAccess[RenderGraph.kMaxMRTCount]; public int fragmentInputMaxIndex { get; protected set; } = -1; @@ -100,6 +108,12 @@ namespace UnityEngine.Rendering.RenderGraphModule // We do not need to clear colorBufferAccess and fragmentInputAccess as we have the colorBufferMaxIndex and fragmentInputMaxIndex // which are reset above so we only clear depthAccess here. depthAccess = default(TextureAccess); + + hasShadingRateImage = false; + hasShadingRateStates = false; + shadingRateFragmentSize = ShadingRateFragmentSize.FragmentSize1x1; + primitiveShadingRateCombiner = ShadingRateCombiner.Keep; + fragmentShadingRateCombiner = ShadingRateCombiner.Keep; } // Check if the pass has any render targets set-up @@ -113,7 +127,15 @@ namespace UnityEngine.Rendering.RenderGraphModule [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool IsTransient(in ResourceHandle res) { - return transientResourceList[res.iType].Contains(res); + // Versioning doesn't matter much for transient resources as they are only used within a single pass + for (int i = 0; i < transientResourceList[res.iType].Count; i++) + { + if (transientResourceList[res.iType][i].index == res.index) + { + return true; + } + } + return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -328,7 +350,6 @@ namespace UnityEngine.Rendering.RenderGraphModule #endif } - // Here we want to keep computation to a minimum and only hash what will influence NRP compiler: Pass merging, load/store actions etc. [MethodImpl(MethodImplOptions.AggressiveInlining)] void ComputeTextureHash(ref HashFNV1A32 generator, in ResourceHandle handle, RenderGraphResourceRegistry resources) @@ -339,9 +360,12 @@ namespace UnityEngine.Rendering.RenderGraphModule if (resources.IsRenderGraphResourceImported(handle)) { var res = resources.GetTextureResource(handle); - if (res.graphicsResource.externalTexture != null) // External texture + var graphicsResource = res.graphicsResource; + ref var desc = ref res.desc; + + var externalTexture = graphicsResource.externalTexture; + if (externalTexture != null) // External texture { - var externalTexture = res.graphicsResource.externalTexture; generator.Append((int) externalTexture.graphicsFormat); generator.Append((int) externalTexture.dimension); generator.Append(externalTexture.width); @@ -349,27 +373,26 @@ namespace UnityEngine.Rendering.RenderGraphModule if (externalTexture is RenderTexture externalRT) generator.Append(externalRT.antiAliasing); } - else if (res.graphicsResource.rt != null) // Regular RTHandle + else if (graphicsResource.rt != null) // Regular RTHandle { - var rt = res.graphicsResource.rt; + var rt = graphicsResource.rt; generator.Append((int) rt.graphicsFormat); generator.Append((int) rt.dimension); generator.Append(rt.antiAliasing); - if (res.graphicsResource.useScaling) - if (res.graphicsResource.scaleFunc != null) - generator.Append(res.graphicsResource.scaleFunc); + if (graphicsResource.useScaling) + if (graphicsResource.scaleFunc != null) + generator.Append(DelegateHashCodeUtils.GetFuncHashCode(graphicsResource.scaleFunc)); else - generator.Append(res.graphicsResource.scaleFactor); + generator.Append(graphicsResource.scaleFactor); else { generator.Append(rt.width); generator.Append(rt.height); } } - else if (res.graphicsResource.nameID != default) // External RTI + else if (graphicsResource.nameID != default) // External RTI { // The only info we have is from the provided desc upon importing. - ref var desc = ref res.desc; generator.Append((int) desc.format); generator.Append((int) desc.dimension); generator.Append((int) desc.msaaSamples); @@ -378,8 +401,8 @@ namespace UnityEngine.Rendering.RenderGraphModule } // Add the clear/discard buffer flags to the hash (used in all the cases above) - generator.Append(res.desc.clearBuffer); - generator.Append(res.desc.discardBuffer); + generator.Append(desc.clearBuffer); + generator.Append(desc.discardBuffer); } else { @@ -399,11 +422,20 @@ namespace UnityEngine.Rendering.RenderGraphModule generator.Append(desc.scale); break; case TextureSizeMode.Functor: - generator.Append(desc.func); + generator.Append(DelegateHashCodeUtils.GetFuncHashCode(desc.func)); break; } } } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void ComputeHashForTextureAccess(ref HashFNV1A32 generator, in ResourceHandle handle, in TextureAccess textureAccess) + { + generator.Append(handle.index); + generator.Append((int) textureAccess.flags); + generator.Append(textureAccess.mipLevel); + generator.Append(textureAccess.depthSlice); + } // This function is performance sensitive. // Avoid mass function calls to get the hashCode and compute locally instead. @@ -435,6 +467,22 @@ namespace UnityEngine.Rendering.RenderGraphModule generator.Append(colorBufferMaxIndex); + generator.Append(hasShadingRateImage); + if (hasShadingRateImage) + { + var handle = shadingRateAccess.textureHandle.handle; + if (handle.IsValid()) + { + ComputeTextureHash(ref generator, handle, resources); + ComputeHashForTextureAccess(ref generator, handle, shadingRateAccess); + } + } + + generator.Append(hasShadingRateStates); + generator.Append((int)shadingRateFragmentSize); + generator.Append((int)primitiveShadingRateCombiner); + generator.Append((int)fragmentShadingRateCombiner); + for (int i = 0; i < fragmentInputMaxIndex + 1; ++i) { var fragmentInputAccessElement = fragmentInputAccess[i]; @@ -463,22 +511,27 @@ namespace UnityEngine.Rendering.RenderGraphModule for (int resType = 0; resType < (int)RenderGraphResourceType.Count; resType++) { var resourceReads = resourceReadLists[resType]; - for (int i = 0; i < resourceReads.Count; ++i) + var resourceReadsCount = resourceReads.Count; + for (int i = 0; i < resourceReadsCount; ++i) generator.Append(resourceReads[i].index); var resourceWrites = resourceWriteLists[resType]; - for (int i = 0; i < resourceWrites.Count; ++i) + var resourceWritesCount = resourceWrites.Count; + for (int i = 0; i < resourceWritesCount; ++i) generator.Append(resourceWrites[i].index); var resourceTransient = transientResourceList[resType]; - for (int i = 0; i < resourceTransient.Count; ++i) + var resourceTransientCount = resourceTransient.Count; + for (int i = 0; i < resourceTransientCount; ++i) generator.Append(resourceTransient[i].index); } - for (int i = 0; i < usedRendererListList.Count; ++i) + var usedRendererListListCount = usedRendererListList.Count; + for (int i = 0; i < usedRendererListListCount; ++i) generator.Append(usedRendererListList[i].handle); - for (int i = 0; i < setGlobalsList.Count; ++i) + var setGlobalsListCount = setGlobalsList.Count; + for (int i = 0; i < setGlobalsListCount; ++i) { var global = setGlobalsList[i]; generator.Append(global.Item1.handle.index); @@ -486,19 +539,49 @@ namespace UnityEngine.Rendering.RenderGraphModule } generator.Append(useAllGlobalTextures); - for (int i = 0; i < implicitReadsList.Count; ++i) + var implicitReadsListCount = implicitReadsList.Count; + for (int i = 0; i < implicitReadsListCount; ++i) generator.Append(implicitReadsList[i].index); generator.Append(GetRenderFuncHash()); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - static void ComputeHashForTextureAccess(ref HashFNV1A32 generator, in ResourceHandle handle, in TextureAccess textureAccess) + public void SetShadingRateImage(in TextureHandle shadingRateImage, AccessFlags accessFlags, int mipLevel, int depthSlice) { - generator.Append(handle.index); - generator.Append((int) textureAccess.flags); - generator.Append(textureAccess.mipLevel); - generator.Append(textureAccess.depthSlice); + if (ShadingRateInfo.supportsPerImageTile) + { + hasShadingRateImage = true; + shadingRateAccess = new TextureAccess(shadingRateImage, accessFlags, mipLevel, depthSlice); + AddResourceRead(shadingRateAccess.textureHandle.handle); + } + } + + public void SetShadingRateFragmentSize(ShadingRateFragmentSize shadingRateFragmentSize) + { + if (ShadingRateInfo.supportsPerDrawCall) + { + hasShadingRateStates = true; + this.shadingRateFragmentSize = shadingRateFragmentSize; + } + } + + public void SetShadingRateCombiner(ShadingRateCombinerStage stage, ShadingRateCombiner combiner) + { + if (ShadingRateInfo.supportsPerImageTile) + { + switch (stage) + { + case ShadingRateCombinerStage.Primitive: + hasShadingRateStates = true; + primitiveShadingRateCombiner = combiner; + break; + + case ShadingRateCombinerStage.Fragment: + hasShadingRateStates = true; + fragmentShadingRateCombiner = combiner; + break; + } + } } } @@ -540,7 +623,7 @@ namespace UnityEngine.Rendering.RenderGraphModule [MethodImpl(MethodImplOptions.AggressiveInlining)] public override int GetRenderFuncHash() { - return renderFunc != null ? HashFNV1A32.GetFuncHashCode(renderFunc) : 0; + return renderFunc != null ? DelegateHashCodeUtils.GetFuncHashCode(renderFunc) : 0; } } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourcePool.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourcePool.cs index 9e916c8d..bae48e7d 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourcePool.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourcePool.cs @@ -20,7 +20,7 @@ namespace UnityEngine.Rendering.RenderGraphModule protected Dictionary> m_ResourcePool = new Dictionary>(); // This list allows us to determine if all resources were correctly released in the frame when validity checks are enabled. - // This is useful to warn in case of user error or avoid leaks when a render graph execution errors occurs for example. + // This is useful to warn in case of user error or avoid leaks when a render graph execution error occurs for example. List<(int, Type)> m_FrameAllocatedResources = new List<(int, Type)>(); const int kStaleResourceLifetime = 10; diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceRegistry.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceRegistry.cs index b0bc2ef5..d34c6212 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceRegistry.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceRegistry.cs @@ -686,7 +686,7 @@ namespace UnityEngine.Rendering.RenderGraphModule return texHandle; } - static RenderTargetIdentifier emptyId = new RenderTargetIdentifier(); + static RenderTargetIdentifier emptyId = RenderTargetIdentifier.Invalid; static RenderTargetIdentifier builtinCameraRenderTarget = new RenderTargetIdentifier(BuiltinRenderTextureType.CameraTarget); [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceTexture.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceTexture.cs index ce22c2e7..f92ae931 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceTexture.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceTexture.cs @@ -200,6 +200,16 @@ namespace UnityEngine.Rendering.RenderGraphModule public RenderTextureMemoryless memoryless; ///Special treatment of the VR eye texture used in stereoscopic rendering. public VRTextureUsage vrUsage; + + /// + /// Set to true if the texture is to be used as a shading rate image. + /// + /// + /// Width and height are usually in pixels but if enableShadingRate is set to true, width and height are in tiles. + /// See also Variable Rate Shading. + /// + public bool enableShadingRate; + ///Texture name. public string name; #if UNITY_2020_2_OR_NEWER @@ -229,7 +239,7 @@ namespace UnityEngine.Rendering.RenderGraphModule { get { return (DepthBits)GraphicsFormatUtility.GetDepthBits(format); } set - { + { if (value == DepthBits.None) { if( !GraphicsFormatUtility.IsDepthStencilFormat(format) ) @@ -240,7 +250,7 @@ namespace UnityEngine.Rendering.RenderGraphModule else { format = GraphicsFormatUtility.GetDepthStencilFormat((int)value); - } + } } } @@ -372,6 +382,7 @@ namespace UnityEngine.Rendering.RenderGraphModule clearBuffer = true; clearColor = Color.black; discardBuffer = false; + enableShadingRate = input.enableShadingRate; } /// @@ -403,7 +414,7 @@ namespace UnityEngine.Rendering.RenderGraphModule break; case TextureSizeMode.Functor: if (func != null) - hashCode.Append(func); + hashCode.Append(DelegateHashCodeUtils.GetFuncHashCode(func)); break; case TextureSizeMode.Scale: hashCode.Append(scale); @@ -429,6 +440,7 @@ namespace UnityEngine.Rendering.RenderGraphModule #if UNITY_2020_2_OR_NEWER hashCode.Append(fastMemoryDesc.inFastMemory); #endif + hashCode.Append(enableShadingRate); return hashCode.value; } @@ -474,21 +486,42 @@ namespace UnityEngine.Rendering.RenderGraphModule // Textures are going to be reused under different aliases along the frame so we can't provide a specific name upon creation. // The name in the desc is going to be used for debugging purpose and render graph visualization. if (name == "") - name = $"RenderGraphTexture_{m_TextureCreationIndex++}"; + name = $"RenderGraphTexture_{m_TextureCreationIndex++}"; + + RTHandleAllocInfo rtAllocInfo = new RTHandleAllocInfo(name) + { + slices = desc.slices, + format = desc.format, + filterMode = desc.filterMode, + wrapModeU = desc.wrapMode, + wrapModeV = desc.wrapMode, + wrapModeW = desc.wrapMode, + dimension = desc.dimension, + enableRandomWrite = desc.enableRandomWrite, + useMipMap = desc.useMipMap, + autoGenerateMips = desc.autoGenerateMips, + anisoLevel = desc.anisoLevel, + mipMapBias = desc.mipMapBias, + isShadowMap = desc.isShadowMap, + msaaSamples = (MSAASamples)desc.msaaSamples, + bindTextureMS = desc.bindTextureMS, + useDynamicScale = desc.useDynamicScale, + useDynamicScaleExplicit = desc.useDynamicScaleExplicit, + memoryless = desc.memoryless, + vrUsage = desc.vrUsage, + enableShadingRate = desc.enableShadingRate, + }; switch (desc.sizeMode) { case TextureSizeMode.Explicit: - graphicsResource = RTHandles.Alloc(desc.width, desc.height, desc.format, desc.slices, desc.filterMode, desc.wrapMode, desc.dimension, desc.enableRandomWrite, - desc.useMipMap, desc.autoGenerateMips, desc.isShadowMap, desc.anisoLevel, desc.mipMapBias, desc.msaaSamples, desc.bindTextureMS, desc.useDynamicScale, desc.useDynamicScaleExplicit, desc.memoryless, desc.vrUsage, name); + graphicsResource = RTHandles.Alloc(desc.width, desc.height, rtAllocInfo); break; case TextureSizeMode.Scale: - graphicsResource = RTHandles.Alloc(desc.scale, desc.format, desc.slices, desc.filterMode, desc.wrapMode, desc.dimension, desc.enableRandomWrite, - desc.useMipMap, desc.autoGenerateMips, desc.isShadowMap, desc.anisoLevel, desc.mipMapBias, desc.msaaSamples, desc.bindTextureMS, desc.useDynamicScale, desc.useDynamicScaleExplicit, desc.memoryless, desc.vrUsage, name); + graphicsResource = RTHandles.Alloc(desc.scale, rtAllocInfo); break; case TextureSizeMode.Functor: - graphicsResource = RTHandles.Alloc(desc.func, desc.format, desc.slices, desc.filterMode, desc.wrapMode, desc.dimension, desc.enableRandomWrite, - desc.useMipMap, desc.autoGenerateMips, desc.isShadowMap, desc.anisoLevel, desc.mipMapBias, desc.msaaSamples, desc.bindTextureMS, desc.useDynamicScale, desc.useDynamicScaleExplicit, desc.memoryless, desc.vrUsage, name); + graphicsResource = RTHandles.Alloc(desc.func, rtAllocInfo); break; } } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResources.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResources.cs index df4c4ccc..4fa36d7a 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResources.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResources.cs @@ -13,7 +13,9 @@ namespace UnityEngine.Rendering.RenderGraphModule Count } - internal struct ResourceHandle : IEquatable + // For performance reasons, ResourceHandle is readonly. + // To update an existing instance with a new version, recreate it using its copy constructor + internal readonly struct ResourceHandle : IEquatable { // Note on handles validity. // PassData classes used during render graph passes are pooled and because of that, when users don't fill them completely, @@ -24,9 +26,10 @@ namespace UnityEngine.Rendering.RenderGraphModule const uint kValidityMask = 0xFFFF0000; const uint kIndexMask = 0xFFFF; - uint m_Value; - int m_Version; // A freshly created resource always starts at version 0 the first write should bring it to v1 - + private readonly uint m_Value; + private readonly int m_Version; + private readonly RenderGraphResourceType m_Type; + static uint s_CurrentValidBit = 1 << 16; static uint s_SharedResourceValidBit = 0x7FFF << 16; @@ -44,23 +47,25 @@ namespace UnityEngine.Rendering.RenderGraphModule { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return m_Version; } + } + public RenderGraphResourceType type + { [MethodImpl(MethodImplOptions.AggressiveInlining)] - set { m_Version = value; } + get { return m_Type; } } - public RenderGraphResourceType type { get; private set; } internal ResourceHandle(int value, RenderGraphResourceType type, bool shared) { Debug.Assert(value <= 0xFFFF); m_Value = ((uint)value & kIndexMask) | (shared ? s_SharedResourceValidBit : s_CurrentValidBit); - this.type = type; - this.m_Version = -1; + m_Type = type; + m_Version = -1; } internal ResourceHandle(in ResourceHandle h, int version) { this.m_Value = h.m_Value; - this.type = h.type; + this.m_Type = h.type; this.m_Version = version; } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphUtilsBlit.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphUtilsBlit.cs index ebd4505e..a0600bd5 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphUtilsBlit.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphUtilsBlit.cs @@ -23,17 +23,20 @@ namespace UnityEngine.Rendering.RenderGraphModule.Util class CopyPassData { public bool isMSAA; + public bool force2DForXR; } + private const string DisableTexture2DXArray = "DISABLE_TEXTURE2D_X_ARRAY"; + /// /// Adds a pass to copy data from a source texture to a destination texture. The data in the texture is copied pixel by pixel. The copy function can only do 1:1 copies it will not allow scaling the data or - /// doing texture filtering. Furthermore it requires the source and destination surfaces to be the same size in pixels and have the same number of MSAA samples. If the textures are multi sampled - /// individual samples will be copied. + /// doing texture filtering. Furthermore it requires the source and destination surfaces to be the same size in pixels and have the same number of MSAA samples and array slices. + /// If the textures are multi sampled, individual samples will be copied. /// /// Copy is intentionally limited in functionally so it can be implemented using frame buffer fetch for optimal performance on tile based GPUs. If you are looking for a more generic /// function please use the AddBlitPass function. /// - /// For XR textures you will have to copy for each eye seperatly. + /// When XR is active, array textures containing both eyes will be automatically copied. /// /// For MSAA textures please use the CanAddCopyPassMSAA() function first to check if the CopyPass is supported on current platform. /// @@ -41,10 +44,6 @@ namespace UnityEngine.Rendering.RenderGraphModule.Util /// The RenderGraph adding this pass to. /// The texture the data is copied from. /// The texture the data is copied to. This has to be different from souce. - /// The source slice of a Array of 3D texture to use. Must be 0 for regular 2D textures. - /// The destination slice of a Array of 3D texture to use. Must be 0 for regular 2D textures. - /// The first mipmap level to copy from. Must be zero for non-mipmapped textures. Must be a valid index for mipmapped textures. - /// The first mipmap level to copy to. Must be zero for non-mipmapped textures. Must be a valid index for mipmapped textures. /// A name to use for debugging and error logging. This name will be shown in the rendergraph debugger. /// File line of the source file this function is called from. Used for debugging. This parameter is automatically generated by the compiler. Users do not need to pass it. /// File line of the source file this function is called from. Used for debugging. This parameter is automatically generated by the compiler. Users do not need to pass it. @@ -52,10 +51,6 @@ namespace UnityEngine.Rendering.RenderGraphModule.Util this RenderGraph graph, TextureHandle source, TextureHandle destination, - int sourceSlice = 0, - int destinationSlice = 0, - int sourceMip = 0, - int destinationMip = 0, string passName = "Copy Pass Utility" #if !CORE_PACKAGE_DOCTOOLS , [CallerFilePath] string file = "", @@ -64,29 +59,20 @@ namespace UnityEngine.Rendering.RenderGraphModule.Util { if (!graph.nativeRenderPassesEnabled) throw new ArgumentException("CopyPass only supported for native render pass. Please use the blit functions instead for non native render pass platforms."); - + var sourceDesc = graph.GetTextureDesc(source); var destinationDesc = graph.GetTextureDesc(destination); - if (sourceSlice < 0 || sourceSlice >= sourceDesc.slices) - throw new ArgumentException("Invalid sourceSlice."); - - if (destinationSlice < 0 || destinationSlice >= destinationDesc.slices) - throw new ArgumentException("Invalid destinationSlice."); - - int sourceMaxWidth = math.max(math.max(sourceDesc.width, sourceDesc.height), sourceDesc.slices); - int sourceTotalMipChainLevels = (int)math.log2(sourceMaxWidth) + 1; - if (sourceMip < 0 || sourceMip >= sourceMaxWidth) - throw new ArgumentException("Invalid sourceMip."); - - int destinationMaxWidth = math.max(math.max(destinationDesc.width, destinationDesc.height), destinationDesc.slices); - int destinationTotalMipChainLevels = (int)math.log2(destinationMaxWidth) + 1; - if (destinationMip < 0 || destinationMip >= destinationMaxWidth) - throw new ArgumentException("Invalid destinationMip."); - if (sourceDesc.msaaSamples != destinationDesc.msaaSamples) throw new ArgumentException("MSAA samples from source and destination texture doesn't match."); + if (sourceDesc.width != destinationDesc.width || + sourceDesc.height != destinationDesc.height) + throw new ArgumentException("Dimensions for source and destination texture doesn't match."); + + if (sourceDesc.slices != destinationDesc.slices) + throw new ArgumentException("Slice count for source and destination texture doesn't match."); + var isMSAA = (int)sourceDesc.msaaSamples > 1; // Note: Needs shader model ps_4.1 to support SV_SampleIndex which means the copy pass isn't supported for MSAA on some platforms. @@ -100,15 +86,87 @@ namespace UnityEngine.Rendering.RenderGraphModule.Util using (var builder = graph.AddRasterRenderPass(passName, out var passData, file, line)) { passData.isMSAA = isMSAA; - builder.SetInputAttachment(source, 0, AccessFlags.Read, sourceMip, sourceSlice); - builder.SetRenderAttachment(destination, 0, AccessFlags.Write, destinationMip, destinationSlice); + + bool isXRArrayTextureActive = TextureXR.useTexArray; + bool isArrayTexture = sourceDesc.slices > 1; + passData.force2DForXR = isXRArrayTextureActive && (isArrayTexture == false); + builder.SetInputAttachment(source, 0, AccessFlags.Read); + builder.SetRenderAttachment(destination, 0, AccessFlags.Write); builder.SetRenderFunc((CopyPassData data, RasterGraphContext context) => CopyRenderFunc(data, context)); + if (passData.force2DForXR) builder.AllowGlobalStateModification(true);// So we can set the keywords } } + /// + /// Adds a pass to copy data from a source texture to a destination texture. The data in the texture is copied pixel by pixel. The copy function can only do 1:1 copies it will not allow scaling the data or + /// doing texture filtering. Furthermore it requires the source and destination surfaces to be the same size in pixels and have the same number of MSAA samples. If the textures are multi sampled + /// individual samples will be copied. + /// + /// Copy is intentionally limited in functionally so it can be implemented using frame buffer fetch for optimal performance on tile based GPUs. If you are looking for a more generic + /// function please use the AddBlitPass function. Blit will automatically decide (based on the arguments) whether to use normal rendering or to instead call copy internally. + /// + /// The source/destination mip and slice arguments are ignored and were never used by this function therefore it is better to call the AddCopyPass overload without them. This function + /// is here for backwards compatibility with existing code. + /// + /// When XR is active, array textures containing both eyes will be automatically copied. + /// + /// For MSAA textures please use the CanAddCopyPassMSAA() function first to check if the CopyPass is supported on current platform. + /// + /// + /// The RenderGraph adding this pass to. + /// The texture the data is copied from. + /// The texture the data is copied to. This has to be different from souce. + /// This argument was never used. Please use the overload without this argument instead. If you want to work with mips or array slices you can use blit or write your own frame buffer fetch based implementation. + /// This argument was never used. Please use the overload without this argument instead. If you want to work with mips or array slices you can use blit or write your own frame buffer fetch based implementation. + /// This argument was never used. Please use the overload without this argument instead. If you want to work with mips or array slices you can use blit or write your own frame buffer fetch based implementation. + /// This argument was never used. Please use the overload without this argument instead. If you want to work with mips or array slices you can use blit or write your own frame buffer fetch based implementation. + /// A name to use for debugging and error logging. This name will be shown in the rendergraph debugger. + /// File line of the source file this function is called from. Used for debugging. This parameter is automatically generated by the compiler. Users do not need to pass it. + /// File line of the source file this function is called from. Used for debugging. This parameter is automatically generated by the compiler. Users do not need to pass it. + public static void AddCopyPass( + this RenderGraph graph, + TextureHandle source, + TextureHandle destination, + int sourceSlice, + int destinationSlice = 0, + int sourceMip = 0, + int destinationMip = 0, + string passName = "Copy Pass Utility" +#if !CORE_PACKAGE_DOCTOOLS + , [CallerFilePath] string file = "", + [CallerLineNumber] int line = 0) +#endif + { + AddCopyPass(graph, source, destination, passName, file, line); + } + static void CopyRenderFunc(CopyPassData data, RasterGraphContext rgContext) { - Blitter.CopyTexture(rgContext.cmd, data.isMSAA); + Blitter.CopyTexture(rgContext.cmd, data.isMSAA, data.force2DForXR); + } + + /// + /// Try to auto detect XR textures. + /// + /// + /// + /// + /// + /// + /// + internal static bool IsTextureXR(ref TextureDesc destDesc, int sourceSlice, int destinationSlice, int numSlices, int numMips) + { + if (TextureXR.useTexArray && + destDesc.dimension == TextureDimension.Tex2DArray && + destDesc.slices == TextureXR.slices && + sourceSlice == 0 && + destinationSlice == 0 && + numSlices == TextureXR.slices && + numMips == 1) + { + return true; + } + return false; } /// @@ -139,6 +197,7 @@ namespace UnityEngine.Rendering.RenderGraphModule.Util public int destinationMip; public int numMips; public BlitFilterMode filterMode; + public bool isXR; } @@ -222,7 +281,7 @@ namespace UnityEngine.Rendering.RenderGraphModule.Util passData.destinationMip = destinationMip; passData.numMips = numMips; passData.filterMode = filterMode; - + passData.isXR = IsTextureXR(ref destinationDesc, sourceSlice, destinationSlice, numSlices, numMips); builder.UseTexture(source, AccessFlags.Read); builder.UseTexture(destination, AccessFlags.Write); builder.SetRenderFunc((BlitPassData data, UnsafeGraphContext context) => BlitRenderFunc(data, context)); @@ -237,15 +296,24 @@ namespace UnityEngine.Rendering.RenderGraphModule.Util s_BlitScaleBias.w = data.offset.y; CommandBuffer unsafeCmd = CommandBufferHelpers.GetNativeCommandBuffer(context.cmd); - for (int currSlice = 0; currSlice < data.numSlices; currSlice++) + if (data.isXR) + { + // This is the magic that makes XR work for blit. We set the rendertargets passing -1 for the slices. This means it will bind all (both eyes) slices. + // The engine will then also automatically duplicate our draws and the vertex and pixel shader (through macros) will ensure those draws end up in the right eye. + context.cmd.SetRenderTarget(data.destination, 0, CubemapFace.Unknown, -1); + Blitter.BlitTexture(unsafeCmd, data.source, s_BlitScaleBias, data.sourceMip, data.filterMode == BlitFilterMode.ClampBilinear); + } + else { - for (int currMip = 0; currMip < data.numMips; currMip++) + for (int currSlice = 0; currSlice < data.numSlices; currSlice++) { - context.cmd.SetRenderTarget(data.destination, data.destinationMip + currMip, CubemapFace.Unknown, data.destinationSlice + currSlice); - Blitter.BlitTexture(unsafeCmd, data.source, s_BlitScaleBias, data.sourceMip + currMip, data.sourceSlice + currSlice, data.filterMode == BlitFilterMode.ClampBilinear); + for (int currMip = 0; currMip < data.numMips; currMip++) + { + context.cmd.SetRenderTarget(data.destination, data.destinationMip + currMip, CubemapFace.Unknown, data.destinationSlice + currSlice); + Blitter.BlitTexture(unsafeCmd, data.source, s_BlitScaleBias, data.sourceMip + currMip, data.sourceSlice + currSlice, data.filterMode == BlitFilterMode.ClampBilinear); + } } } - } /// @@ -277,7 +345,8 @@ namespace UnityEngine.Rendering.RenderGraphModule.Util /// /// Use one of the constructor overloads for common use cases. /// - /// + /// By default most constructors will copy all array texture slices. This ensures XR textures are handled "automatically" without additional consideration. + /// /// The shader properties defined in the struct or constructors is used for most common usecases but they are not required to be used in the shader. /// By using the MaterialPropertyBlock can you add your shader properties with custom values. /// @@ -289,7 +358,8 @@ namespace UnityEngine.Rendering.RenderGraphModule.Util private static readonly int blitScaleBias = Shader.PropertyToID("_BlitScaleBias"); /// - /// Simple constructor to set a few amount of parameters to blit. + /// Simple constructor that sets only the most common parameters to blit. The other parameters will be set to sensible default values. + /// /// /// The texture the data is copied from. /// The texture the data is copied to. @@ -299,7 +369,7 @@ namespace UnityEngine.Rendering.RenderGraphModule.Util : this(source, destination, Vector2.one, Vector2.zero, material, shaderPass) { } /// - /// Simple constructor to set a few amount of parameters to blit. + /// Simple constructor that sets only the most common parameters to blit. The other parameters will be set to sensible default values. /// /// The texture the data is copied from. /// The texture the data is copied to. @@ -315,7 +385,7 @@ namespace UnityEngine.Rendering.RenderGraphModule.Util this.offset = offset; sourceSlice = -1; destinationSlice = 0; - numSlices = 1; + numSlices = -1; sourceMip = -1; destinationMip = 0; numMips = 1; @@ -360,7 +430,7 @@ namespace UnityEngine.Rendering.RenderGraphModule.Util MaterialPropertyBlock mpb, int destinationSlice, int destinationMip, - int numSlices = 1, + int numSlices = -1, int numMips = 1, int sourceSlice = -1, int sourceMip = -1, @@ -388,7 +458,7 @@ namespace UnityEngine.Rendering.RenderGraphModule.Util /// Material property block to use to render the blit. This property should contain all data the shader needs. /// The first slice to copy to if the texture is an 3D or array texture. Must be zero for regular textures. /// The first mipmap level to copy to. Must be zero for non-mipmapped textures. Must be a valid index for mipmapped textures. - /// The number of slices to copy. -1 to copy all slices until the end of the texture. Arguments that copy invalid slices to be copied will lead to an error. + /// The number of slices to copy. -1 to copy all slices until the end of the texture. Arguments that copy invalid slices to be copied will lead to an error. If you are using an XR-array texture make sure you set this to -1 or the number of slices in the array our your XR texture will not be correctly copied. /// The number of mipmaps to copy. -1 to copy all mipmaps. Arguments that copy invalid mips to be copied will lead to an error. /// The first slice to copy from if the texture is an 3D or array texture. Must be zero for regular textures. Default is set to -1 to ignore source slices and set it to 0 without looping for each destination slice /// The first mipmap level to copy from. Must be zero for non-mipmapped textures. Must be a valid index for mipmapped textures. Defaults to -1 to ignore source mips and set it to 0 without looping for each destination mip. @@ -412,7 +482,7 @@ namespace UnityEngine.Rendering.RenderGraphModule.Util MaterialPropertyBlock mpb, int destinationSlice, int destinationMip, - int numSlices = 1, + int numSlices = -1, int numMips = 1, int sourceSlice = -1, int sourceMip = -1, @@ -542,7 +612,8 @@ namespace UnityEngine.Rendering.RenderGraphModule.Util public Vector2 offset; /// - /// The first slice of the source texture to blit from. -1 to ignore source slices and set it to 0 without looping for each destination slice. + /// The first slice of the source texture to blit from. -1 to ignore source slices. This will not set any values to the sourceSlicePropertyID texture parameters. + /// If not -1, the sourceSlicePropertyID will be set between sourceSlice and sourceSlice+numSlices for each slice that is blit. /// public int sourceSlice; @@ -557,7 +628,8 @@ namespace UnityEngine.Rendering.RenderGraphModule.Util public int numSlices; /// - /// The first source mipmap to blit from. -1 to ignore source mips and set it to 0 without looping for each destination mip. + /// The first source mipmap to blit from. -1 to ignore source mips. This will not set any values to the sourceMipPropertyID texture parameters. + /// If not -1, the sourceMipPropertyID will be set between sourceMip and sourceMip+numMips for each mip that is blit. /// public int sourceMip; @@ -596,12 +668,14 @@ namespace UnityEngine.Rendering.RenderGraphModule.Util /// /// The scalar property to set with the source slice index. If -1 the default "_BlitTexArraySlice" property will be used. Note: Use Shader.PropertyToID to convert a string property name to an ID. /// If more than one slice is rendered using the blit function (numSlices>1) several full screen quads will be rendered for each slice with different sourceSlicePropertyID values set. + /// If sourceSlice is -1, no values will be set on the property. /// public int sourceSlicePropertyID; /// /// The scalar property to set with the source mip index. If -1 the default "_BlitMipLevel" property will be used. Note: Use Shader.PropertyToID to convert a string property name to an ID. - /// If more than one mip is rendered using the blit function (numMips>1) several full screen quads will be rendered for each slice with different sourceMipPropertyID values set./// + /// If more than one mip is rendered using the blit function (numMips>1), several full screen quads will be rendered for each slice with different sourceMipPropertyID values set. + /// If sourceMip is -1, no values will be set on the property. /// public int sourceMipPropertyID; @@ -636,6 +710,7 @@ namespace UnityEngine.Rendering.RenderGraphModule.Util public int sourceSlicePropertyID; public int sourceMipPropertyID; public int scaleBiasPropertyID; + public bool isXR; } /// @@ -680,27 +755,53 @@ namespace UnityEngine.Rendering.RenderGraphModule.Util [CallerLineNumber] int line = 0) #endif { - var sourceDesc = graph.GetTextureDesc(blitParameters.source); - var destinationDesc = graph.GetTextureDesc(blitParameters.destination); + if (!blitParameters.destination.IsValid()) + { + throw new ArgumentException($"BlitPass: {passName} destination needs to be a valid texture handle."); + } - int sourceMaxWidth = math.max(math.max(sourceDesc.width, sourceDesc.height), sourceDesc.slices); - int sourceTotalMipChainLevels = (int)math.log2(sourceMaxWidth) + 1; + var destinationDesc = graph.GetTextureDesc(blitParameters.destination); + // Fill in unspecified parameters automatically based on the texture descriptor int destinationMaxWidth = math.max(math.max(destinationDesc.width, destinationDesc.height), destinationDesc.slices); int destinationTotalMipChainLevels = (int)math.log2(destinationMaxWidth) + 1; + if (blitParameters.numSlices == -1) + { + blitParameters.numSlices = destinationDesc.slices - blitParameters.destinationSlice; + } - if (blitParameters.numSlices == -1) blitParameters.numSlices = destinationDesc.slices - blitParameters.destinationSlice; - if (blitParameters.numSlices > destinationDesc.slices - blitParameters.destinationSlice - || (blitParameters.sourceSlice != -1 && blitParameters.numSlices > sourceDesc.slices - blitParameters.sourceSlice)) + if (blitParameters.numMips == -1) { - throw new ArgumentException($"BlitPass: {passName} attempts to blit too many slices. The pass will be skipped."); + blitParameters.numMips = destinationTotalMipChainLevels - blitParameters.destinationMip; } - if (blitParameters.numMips == -1) blitParameters.numMips = destinationTotalMipChainLevels - blitParameters.destinationMip; - if (blitParameters.numMips > destinationTotalMipChainLevels - blitParameters.destinationMip - || (blitParameters.sourceMip != -1 && blitParameters.numMips > sourceTotalMipChainLevels - blitParameters.sourceMip)) + // Validate against the source if available + if (blitParameters.source.IsValid()) { - throw new ArgumentException($"BlitPass: {passName} attempts to blit too many mips. The pass will be skipped."); + var sourceDesc = graph.GetTextureDesc(blitParameters.source); + int sourceMaxWidth = math.max(math.max(sourceDesc.width, sourceDesc.height), sourceDesc.slices); + int sourceTotalMipChainLevels = (int)math.log2(sourceMaxWidth) + 1; + + if (blitParameters.sourceSlice != -1 && blitParameters.numSlices > sourceDesc.slices - blitParameters.sourceSlice) + { + throw new ArgumentException($"BlitPass: {passName} attempts to blit too many slices. There are not enough slices in the source array. The pass will be skipped."); + } + + if (blitParameters.sourceMip != -1 && blitParameters.numMips > sourceTotalMipChainLevels - blitParameters.sourceMip) + { + throw new ArgumentException($"BlitPass: {passName} attempts to blit too many mips. There are not enough mips in the source texture. The pass will be skipped."); + } + } + + // Validate against destination + if (blitParameters.numSlices > destinationDesc.slices - blitParameters.destinationSlice) + { + throw new ArgumentException($"BlitPass: {passName} attempts to blit too many slices. There are not enough slices in the destination array. The pass will be skipped."); + } + + if (blitParameters.numMips > destinationTotalMipChainLevels - blitParameters.destinationMip) + { + throw new ArgumentException($"BlitPass: {passName} attempts to blit too many mips. There are not enough mips in the destination texture. The pass will be skipped."); } using (var builder = graph.AddUnsafePass(passName, out var passData, file, line)) @@ -723,8 +824,13 @@ namespace UnityEngine.Rendering.RenderGraphModule.Util passData.sourceSlicePropertyID = blitParameters.sourceSlicePropertyID; passData.sourceMipPropertyID = blitParameters.sourceMipPropertyID; passData.scaleBiasPropertyID = blitParameters.scaleBiasPropertyID; + passData.isXR = IsTextureXR(ref destinationDesc, (passData.sourceSlice == -1) ? 0 : passData.sourceSlice, passData.destinationSlice, passData.numSlices, passData.numMips); + + if (blitParameters.source.IsValid()) + { + builder.UseTexture(blitParameters.source); + } - builder.UseTexture(blitParameters.source); builder.UseTexture(blitParameters.destination, AccessFlags.Write); builder.SetRenderFunc((BlitMaterialPassData data, UnsafeGraphContext context) => BlitMaterialRenderFunc(data, context)); } @@ -741,34 +847,61 @@ namespace UnityEngine.Rendering.RenderGraphModule.Util if (data.propertyBlock == null) data.propertyBlock = s_PropertyBlock; - data.propertyBlock.SetTexture(data.sourceTexturePropertyID, data.source); - if (data.sourceSlice == -1) - data.propertyBlock.SetInt(data.sourceSlicePropertyID, 0); - if (data.sourceMip == -1) - data.propertyBlock.SetInt(data.sourceMipPropertyID, 0); + if (data.source.IsValid()) + { + data.propertyBlock.SetTexture(data.sourceTexturePropertyID, data.source); + } + data.propertyBlock.SetVector(data.scaleBiasPropertyID, s_BlitScaleBias); - for (int currSlice = 0; currSlice < data.numSlices; currSlice++) + if (data.isXR) { - for (int currMip = 0; currMip < data.numMips; currMip++) + // This is the magic that makes XR work for blit. We set the rendertargets passing -1 for the slices. This means it will bind all (both eyes) slices. + // The engine will then also automatically duplicate our draws and the vertex and pixel shader (through macros) will ensure those draws end up in the right eye. + + if (data.sourceSlice != -1) + data.propertyBlock.SetInt(data.sourceSlicePropertyID, 0); + if (data.sourceMip != -1) + data.propertyBlock.SetInt(data.sourceMipPropertyID, data.sourceMip); + + context.cmd.SetRenderTarget(data.destination, 0, CubemapFace.Unknown, -1); + switch (data.geometry) { - if (data.sourceSlice != -1) - data.propertyBlock.SetInt(data.sourceSlicePropertyID, data.sourceSlice + currSlice); - if (data.sourceMip != -1) - data.propertyBlock.SetInt(data.sourceMipPropertyID, data.sourceMip + currMip); - - context.cmd.SetRenderTarget(data.destination, data.destinationMip + currMip, CubemapFace.Unknown, data.destinationSlice + currSlice); - switch (data.geometry) + case FullScreenGeometryType.Mesh: + Blitter.DrawQuadMesh(unsafeCmd, data.material, data.shaderPass, data.propertyBlock); + break; + case FullScreenGeometryType.ProceduralQuad: + Blitter.DrawQuad(unsafeCmd, data.material, data.shaderPass, data.propertyBlock); + break; + case FullScreenGeometryType.ProceduralTriangle: + Blitter.DrawTriangle(unsafeCmd, data.material, data.shaderPass, data.propertyBlock); + break; + } + } + else + { + for (int currSlice = 0; currSlice < data.numSlices; currSlice++) + { + for (int currMip = 0; currMip < data.numMips; currMip++) { - case FullScreenGeometryType.Mesh: - Blitter.DrawQuadMesh(unsafeCmd, data.material, data.shaderPass, data.propertyBlock); - break; - case FullScreenGeometryType.ProceduralQuad: - Blitter.DrawQuad(unsafeCmd, data.material, data.shaderPass, data.propertyBlock); - break; - case FullScreenGeometryType.ProceduralTriangle: - Blitter.DrawTriangle(unsafeCmd, data.material, data.shaderPass, data.propertyBlock); - break; + if (data.sourceSlice != -1) + data.propertyBlock.SetInt(data.sourceSlicePropertyID, data.sourceSlice + currSlice); + if (data.sourceMip != -1) + data.propertyBlock.SetInt(data.sourceMipPropertyID, data.sourceMip + currMip); + + context.cmd.SetRenderTarget(data.destination, data.destinationMip + currMip, CubemapFace.Unknown, data.destinationSlice + currSlice); + switch (data.geometry) + { + case FullScreenGeometryType.Mesh: + Blitter.DrawQuadMesh(unsafeCmd, data.material, data.shaderPass, data.propertyBlock); + break; + case FullScreenGeometryType.ProceduralQuad: + Blitter.DrawQuad(unsafeCmd, data.material, data.shaderPass, data.propertyBlock); + break; + case FullScreenGeometryType.ProceduralTriangle: + Blitter.DrawTriangle(unsafeCmd, data.material, data.shaderPass, data.propertyBlock); + break; + } } } } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Settings/IncludeRenderPipelineAsset.cs b/Packages/com.unity.render-pipelines.core/Runtime/Settings/IncludeRenderPipelineAsset.cs index 4474d014..03eb7a2e 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Settings/IncludeRenderPipelineAsset.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Settings/IncludeRenderPipelineAsset.cs @@ -3,9 +3,39 @@ using System; namespace UnityEngine.Rendering { /// - /// Define the RPAsset inclusion at build time, for your pipeline. - /// Default: only RPAsset in QualitySettings are embedded on build + /// A graphics settings container for settings related to additional inclusion at build time. /// + /// + /// These settings are not editable through the editor's UI but can be changed through the API for advanced usage. + /// Changing this through the API is only allowed in the Editor. In the Player, this raises an error. + /// + /// By default, only RPAsset, in Quality Settings, is embedded in the build. This allows you to add assets. + /// Add any render pipeline assets you use in your project either through this or directly in Quality Settings. They contain data listing what resources need to be embedded in the build. + /// It is highly recommended not to change it unless you know what you are doing. Otherwise, this may lead to unexpected changes in your Player. + /// + /// + /// + /// Here is an example of how to determine what label to use to embed additional assets. + /// + /// using UnityEngine.Rendering; + /// + /// public static class RPAssetIncludedHelper + /// { + /// public static string label + /// { + /// get + /// { + /// var gs = GraphicsSettings.GetRenderPipelineSettings<IncludeAdditionalRPAssets>(); + /// if (gs == null) //not in SRP + /// return null; + /// if (!gs.includeAssetsByLabel) + /// return null; + /// return gs.labelToInclude; + /// } + /// } + /// } + /// + /// [Serializable] [SupportedOnRenderPipeline] [Categorization.CategoryInfo(Name = "H: RP Assets Inclusion", Order = 990), HideInInspector] diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Settings/LightmapSamplingSettings.cs b/Packages/com.unity.render-pipelines.core/Runtime/Settings/LightmapSamplingSettings.cs new file mode 100644 index 00000000..d6ff46e1 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Settings/LightmapSamplingSettings.cs @@ -0,0 +1,30 @@ +using System; + +namespace UnityEngine.Rendering +{ + /// + /// Lightmap Sampling global settings class. + /// + [Serializable] + [SupportedOnRenderPipeline()] + [Categorization.CategoryInfo(Name = "Lightmap Sampling Settings", Order = 20)] + public class LightmapSamplingSettings : IRenderPipelineGraphicsSettings + { + [SerializeField, HideInInspector] + int m_Version = 1; + + int IRenderPipelineGraphicsSettings.version { get => m_Version; } + + [SerializeField, Tooltip("Use Bicubic Lightmap Sampling. Enabling this will improve the appearance of lightmaps, but may worsen performance on lower end platforms.")] + bool m_UseBicubicLightmapSampling; + + /// + /// Whether to use bicubic sampling for lightmaps. + /// + public bool useBicubicLightmapSampling + { + get => m_UseBicubicLightmapSampling; + set => this.SetValueAndNotify(ref m_UseBicubicLightmapSampling, value, nameof(m_UseBicubicLightmapSampling)); + } + } +} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Settings/LightmapSamplingSettings.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/Settings/LightmapSamplingSettings.cs.meta new file mode 100644 index 00000000..eb34bfc4 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Settings/LightmapSamplingSettings.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 53de0087ce88a1640b2b6468a44f0043 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Settings/ShaderStrippingSetting.cs b/Packages/com.unity.render-pipelines.core/Runtime/Settings/ShaderStrippingSetting.cs index 8625c4d0..72910851 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Settings/ShaderStrippingSetting.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Settings/ShaderStrippingSetting.cs @@ -21,8 +21,33 @@ namespace UnityEngine.Rendering } /// - /// Class that stores shader stripping settings shared between all pipelines + /// This is a Graphics Settings container for settings related to shader stripping for all scriptable render pipelines. /// + /// + /// To change those settings, go to Editor > Project Settings in the Graphics tab. + /// Changing this through the API is only allowed in the Editor. In the Player, this raises an error. + /// + /// + /// + /// Here is an example of how to check if your project strips variant shaders when building a Player using URP. + /// + /// using UnityEngine.Rendering; + /// + /// public static class ShaderStrippingHelper + /// { + /// public static bool exportLog + /// { + /// get + /// { + /// var gs = GraphicsSettings.GetRenderPipelineSettings<ShaderStrippingSetting>(); + /// if (gs == null) //not in any SRP + /// return false; + /// return gs.exportShaderVariants; + /// } + /// } + /// } + /// + /// [Serializable] [SupportedOnRenderPipeline] [Categorization.CategoryInfo(Name = "Additional Shader Stripping Settings", Order = 40)] @@ -38,7 +63,7 @@ namespace UnityEngine.Rendering [SerializeField] [HideInInspector] private Version m_Version = Version.Initial; - /// Current version. + /// Current version of the settings container. Used only for project upgrades. public int version => (int)m_Version; #endregion diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Textures/BufferedRTHandleSystem.cs b/Packages/com.unity.render-pipelines.core/Runtime/Textures/BufferedRTHandleSystem.cs index 0a8ae2c0..96a94855 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Textures/BufferedRTHandleSystem.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Textures/BufferedRTHandleSystem.cs @@ -156,40 +156,17 @@ namespace UnityEngine.Rendering var buffer = new RTHandle[bufferCount]; m_RTHandles.Add(bufferId, buffer); - var format = RTHandles.GetFormat(descriptor.graphicsFormat, descriptor.depthStencilFormat); - - RTHandle Alloc(ref RenderTextureDescriptor d, FilterMode fMode, TextureWrapMode wMode, bool isShadow, int aniso, float mipBias, string n) - { - return m_RTHandleSystem.Alloc( - d.width, - d.height, - format, - d.volumeDepth, - fMode, - wMode, - d.dimension, - d.enableRandomWrite, - d.useMipMap, - d.autoGenerateMips, - isShadow, - aniso, - mipBias, - (MSAASamples)d.msaaSamples, - d.bindMS, - d.useDynamicScale, - d.useDynamicScaleExplicit, - d.memoryless, - d.vrUsage, - n); - } + RTHandleAllocInfo allocInfo = RTHandles.GetRTHandleAllocInfo(descriptor, filterMode, + wrapMode, anisoLevel, mipMapBias, name); + allocInfo.isShadowMap = isShadowMap; // First is autoresized - buffer[0] = Alloc(ref descriptor, filterMode, wrapMode, isShadowMap, anisoLevel, mipMapBias, name); + buffer[0] = m_RTHandleSystem.Alloc(descriptor.width, descriptor.height, allocInfo); // Other are resized on demand for (int i = 1, c = buffer.Length; i < c; ++i) { - buffer[i] = Alloc(ref descriptor, filterMode, wrapMode, isShadowMap, anisoLevel, mipMapBias, name); + buffer[i] = m_RTHandleSystem.Alloc(descriptor.width, descriptor.height, allocInfo); m_RTHandleSystem.SwitchResizeMode(buffer[i], RTHandleSystem.ResizeMode.OnDemand); } } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Textures/RTHandleSystem.cs b/Packages/com.unity.render-pipelines.core/Runtime/Textures/RTHandleSystem.cs index 8f3745d7..cc04a465 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Textures/RTHandleSystem.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Textures/RTHandleSystem.cs @@ -79,6 +79,9 @@ namespace UnityEngine.Rendering /// Set to true to automatically generate mipmaps. public bool autoGenerateMips { get; set; } + /// Set to true if the texture is sampled as a shadow map. + public bool isShadowMap { get; set; } + /// Anisotropic filtering level. public int anisoLevel { get; set; } @@ -94,12 +97,24 @@ namespace UnityEngine.Rendering /// See Dynamic Resolution documentation](https://docs.unity3d.com/Manual/DynamicResolution.html) public bool useDynamicScale { get; set; } + /// See Dynamic Resolution documentation](https://docs.unity3d.com/Manual/DynamicResolution-control-when-occurs.html) + public bool useDynamicScaleExplicit { get; set; } + /// Use this property to set the render texture memoryless modes. public RenderTextureMemoryless memoryless { get; set; } /// Special treatment of the VR eye texture used in stereoscopic rendering. public VRTextureUsage vrUsage { get; set; } + /// + /// Set to true if the texture is to be used as a shading rate image. + /// + /// + /// Width and height are usually in pixels but if enableShadingRate is set to true, width and height are in tiles. + /// See also Variable Rate Shading. + /// + public bool enableShadingRate { get; set; } + /// Name of the RTHandle. public string name { get; set; } @@ -119,13 +134,16 @@ namespace UnityEngine.Rendering this.enableRandomWrite = false; this.useMipMap = false; this.autoGenerateMips = true; + this.isShadowMap = false; this.anisoLevel = 1; this.mipMapBias = 0f; this.msaaSamples = MSAASamples.None; this.bindTextureMS = false; this.useDynamicScale = false; + this.useDynamicScaleExplicit = false; this.memoryless = RenderTextureMemoryless.None; this.vrUsage = VRTextureUsage.None; + this.enableShadingRate = false; this.name = name; } } @@ -519,7 +537,7 @@ namespace UnityEngine.Rendering /// Allocate a new fixed sized RTHandle. /// /// With of the RTHandle. - /// Heigh of the RTHandle. + /// height of the RTHandle. /// Number of slices of the RTHandle. /// Bit depths of a depth buffer. /// GraphicsFormat of a color buffer. @@ -574,7 +592,7 @@ namespace UnityEngine.Rendering /// Allocate a new fixed sized RTHandle. /// /// With of the RTHandle. - /// Heigh of the RTHandle. + /// height of the RTHandle. /// GraphicsFormat of a color or depth stencil buffer. /// Number of slices of the RTHandle. /// Filtering mode of the RTHandle. @@ -598,7 +616,7 @@ namespace UnityEngine.Rendering int width, int height, GraphicsFormat format, - int slices = 1, + int slices = 1, FilterMode filterMode = FilterMode.Point, TextureWrapMode wrapMode = TextureWrapMode.Repeat, TextureDimension dimension = TextureDimension.Tex2D, @@ -625,7 +643,7 @@ namespace UnityEngine.Rendering /// Allocate a new fixed sized RTHandle. /// /// With of the RTHandle. - /// Heigh of the RTHandle. + /// height of the RTHandle. /// U coordinate wrapping mode of the RTHandle. /// V coordinate wrapping mode of the RTHandle. /// W coordinate wrapping mode of the RTHandle. @@ -683,7 +701,7 @@ namespace UnityEngine.Rendering wrapModeU, wrapModeV, wrapModeW, - slices, + slices, filterMode, dimension, enableRandomWrite, @@ -706,7 +724,7 @@ namespace UnityEngine.Rendering /// Allocate a new fixed sized RTHandle. /// /// With of the RTHandle. - /// Heigh of the RTHandle. + /// height of the RTHandle. /// GraphicsFormat of the color or a depth stencil buffer. /// U coordinate wrapping mode of the RTHandle. /// V coordinate wrapping mode of the RTHandle. @@ -735,7 +753,7 @@ namespace UnityEngine.Rendering TextureWrapMode wrapModeU, TextureWrapMode wrapModeV, TextureWrapMode wrapModeW = TextureWrapMode.Repeat, - int slices = 1, + int slices = 1, FilterMode filterMode = FilterMode.Point, TextureDimension dimension = TextureDimension.Tex2D, bool enableRandomWrite = false, @@ -756,7 +774,7 @@ namespace UnityEngine.Rendering var rt = CreateRenderTexture( width, height, format, slices, filterMode, wrapModeU, wrapModeV, wrapModeW, dimension, enableRandomWrite, useMipMap , autoGenerateMips, isShadowMap, anisoLevel, mipMapBias, msaaSamples, bindTextureMS - , useDynamicScale, useDynamicScaleExplicit, memoryless, vrUsage, name); + , useDynamicScale, useDynamicScaleExplicit, memoryless, vrUsage, false, name); var newRT = new RTHandle(this); newRT.SetRenderTexture(rt); @@ -793,6 +811,7 @@ namespace UnityEngine.Rendering bool useDynamicScaleExplicit, RenderTextureMemoryless memoryless, VRTextureUsage vrUsage, + bool enableShadingRate, string name) { bool enableMSAA = msaaSamples != MSAASamples.None; @@ -811,6 +830,13 @@ namespace UnityEngine.Rendering } bool isDepthStencilFormat = GraphicsFormatUtility.IsDepthStencilFormat(format); + + if (enableShadingRate && (isShadowMap || isDepthStencilFormat)) + { + Debug.LogWarning("RTHandle allocated with incompatible enableShadingRate, forcing enableShadingRate to false."); + enableShadingRate = false; + } + string fullName; GraphicsFormat colorFormat, depthStencilFormat, stencilFormat; ShadowSamplingMode shadowSamplingMode = ShadowSamplingMode.None; @@ -822,7 +848,7 @@ namespace UnityEngine.Rendering int depthBits = GraphicsFormatUtility.GetDepthBits(format); if (depthBits < 16) depthBits = 16; - depthStencilFormat = GraphicsFormatUtility.GetDepthStencilFormat(depthBits, 0); + depthStencilFormat = GraphicsFormatUtility.GetDepthStencilFormat(depthBits, 0); colorFormat = GraphicsFormat.None; stencilFormat = GraphicsFormat.None; shadowSamplingMode = ShadowSamplingMode.CompareDepths; @@ -859,10 +885,11 @@ namespace UnityEngine.Rendering memoryless = memoryless, useMipMap = useMipMap, autoGenerateMips = autoGenerateMips, - enableRandomWrite = enableRandomWrite, + enableRandomWrite = enableRandomWrite, bindMS = bindTextureMS, useDynamicScale = m_HardwareDynamicResRequested && useDynamicScale, - useDynamicScaleExplicit = m_HardwareDynamicResRequested && useDynamicScaleExplicit + useDynamicScaleExplicit = m_HardwareDynamicResRequested && useDynamicScaleExplicit, + enableShadingRate = enableShadingRate, }; var rt = new RenderTexture(desc); @@ -876,7 +903,7 @@ namespace UnityEngine.Rendering rt.wrapModeU = wrapModeU; rt.wrapModeV = wrapModeV; - rt.wrapModeW = wrapModeW; + rt.wrapModeW = wrapModeW; rt.Create(); return rt; @@ -889,15 +916,16 @@ namespace UnityEngine.Rendering /// Height of the RTHandle. /// Struct containing details of allocation /// A new RTHandle. + /// + /// Width and height are usually in pixels but if enableShadingRate is set to true, width and height are in tiles. + /// See also Variable Rate Shading. + /// public RTHandle Alloc(int width, int height, RTHandleAllocInfo info) { - bool isShadowMap = false; - bool useDynamicScaleExplicit = false; - var rt = CreateRenderTexture( width, height, info.format, info.slices, info.filterMode, info.wrapModeU, info.wrapModeV, info.wrapModeW, info.dimension, info.enableRandomWrite, info.useMipMap - , info.autoGenerateMips, isShadowMap, info.anisoLevel, info.mipMapBias, info.msaaSamples, info.bindTextureMS - , info.useDynamicScale, useDynamicScaleExplicit, info.memoryless, info.vrUsage, info.name); + , info.autoGenerateMips, info.isShadowMap, info.anisoLevel, info.mipMapBias, info.msaaSamples, info.bindTextureMS + , info.useDynamicScale, info.useDynamicScaleExplicit, info.memoryless, info.vrUsage, info.enableShadingRate, info.name); var newRT = new RTHandle(this); newRT.SetRenderTexture(rt); @@ -909,6 +937,14 @@ namespace UnityEngine.Rendering newRT.referenceSize = new Vector2Int(width, height); + if (info.enableShadingRate) + { + // even though allocation ask for an explicit size, it's possible the + // resize mode is changed afterward hence assigning the scaling function + // because shading rate image resolution is in tiles + newRT.scaleFunc = (refSize) => ShadingRateImage.GetAllocTileSize(refSize); + } + return newRT; } @@ -923,10 +959,15 @@ namespace UnityEngine.Rendering /// The scale factor to use when calculating the dimensions. The base unscaled size used, is the sizes passed to the last ResetReferenceSize call. /// The calculated dimensions. public Vector2Int CalculateDimensions(Vector2 scaleFactor) + { + return CalculateDimensions(scaleFactor, new Vector2Int(GetMaxWidth(), GetMaxHeight())); + } + + static Vector2Int CalculateDimensions(Vector2 scaleFactor, Vector2Int size) { return new Vector2Int( - Mathf.Max(Mathf.RoundToInt(scaleFactor.x * GetMaxWidth()), 1), - Mathf.Max(Mathf.RoundToInt(scaleFactor.y * GetMaxHeight()), 1) + Mathf.Max(Mathf.RoundToInt(scaleFactor.x * size.x), 1), + Mathf.Max(Mathf.RoundToInt(scaleFactor.y * size.y), 1) ); } @@ -956,7 +997,7 @@ namespace UnityEngine.Rendering public RTHandle Alloc( Vector2 scaleFactor, GraphicsFormat format, - int slices = 1, + int slices = 1, FilterMode filterMode = FilterMode.Point, TextureWrapMode wrapMode = TextureWrapMode.Repeat, TextureDimension dimension = TextureDimension.Tex2D, @@ -977,6 +1018,7 @@ namespace UnityEngine.Rendering { var actualDimensions = CalculateDimensions(scaleFactor); + bool enableShadingRate = false; // Not supported, use RTHandleAllocInfo API instead. var rth = AllocAutoSizedRenderTexture(actualDimensions.x, actualDimensions.y, slices, @@ -996,12 +1038,13 @@ namespace UnityEngine.Rendering useDynamicScaleExplicit, memoryless, vrUsage, + enableShadingRate, name ); rth.referenceSize = actualDimensions; - rth.scaleFactor = scaleFactor; + return rth; } @@ -1082,6 +1125,11 @@ namespace UnityEngine.Rendering /// Constant scale for the RTHandle size computation. /// Struct containing details of allocation /// A new RTHandle. + /// + /// scaleFactor is expected to be based on the reference size in pixels. If enableShadingRate is set to true, + /// conversion in tiles is implicitly done prior to allocation. + /// See also Variable Rate Shading. + /// public RTHandle Alloc(Vector2 scaleFactor, RTHandleAllocInfo info) { int width = Mathf.Max(Mathf.RoundToInt(scaleFactor.x * GetMaxWidth()), 1); @@ -1089,7 +1137,18 @@ namespace UnityEngine.Rendering var rth = AllocAutoSizedRenderTexture(width, height, info); rth.referenceSize = new Vector2Int(width, height); - rth.scaleFactor = scaleFactor; + + if (info.enableShadingRate) + { + // shading rate image resolution is in tiles; adjust refSize + rth.scaleFunc = (refSize) => + { + var dimensions = CalculateDimensions(scaleFactor, refSize); + return ShadingRateImage.GetAllocTileSize(dimensions); + }; + } + else + rth.scaleFactor = scaleFactor; return rth; } @@ -1195,7 +1254,7 @@ namespace UnityEngine.Rendering /// /// Function used for the RTHandle size computation. /// GraphicsFormat of a color or depth stencil buffer. - /// Number of slices of the RTHandle. + /// Number of slices of the RTHandle. /// Filtering mode of the RTHandle. /// Addressing mode of the RTHandle. /// Texture dimension of the RTHandle. @@ -1216,7 +1275,7 @@ namespace UnityEngine.Rendering public RTHandle Alloc( ScaleFunc scaleFunc, GraphicsFormat format, - int slices = 1, + int slices = 1, FilterMode filterMode = FilterMode.Point, TextureWrapMode wrapMode = TextureWrapMode.Repeat, TextureDimension dimension = TextureDimension.Tex2D, @@ -1237,9 +1296,10 @@ namespace UnityEngine.Rendering { var actualDimensions = CalculateDimensions(scaleFunc); + bool enableShadingRate = false; // Not supported, use RTHandleAllocInfo API instead. var rth = AllocAutoSizedRenderTexture(actualDimensions.x, actualDimensions.y, - slices, + slices, format, filterMode, wrapMode, @@ -1256,12 +1316,13 @@ namespace UnityEngine.Rendering useDynamicScaleExplicit, memoryless, vrUsage, + enableShadingRate, name ); rth.referenceSize = actualDimensions; - rth.scaleFunc = scaleFunc; + return rth; } @@ -1271,6 +1332,11 @@ namespace UnityEngine.Rendering /// Function used for the RTHandle size computation. /// Struct containing details of allocation /// A new RTHandle. + /// + /// scaleFunc is expected to receive pixel values. If enableShadingRate is set to true, + /// conversion in tiles is done prior to allocation so that scaleFunc does not have to handle it. + /// See also Variable Rate Shading. + /// public RTHandle Alloc(ScaleFunc scaleFunc, RTHandleAllocInfo info) { var scaleFactor = scaleFunc(new Vector2Int(GetMaxWidth(), GetMaxHeight())); @@ -1279,16 +1345,29 @@ namespace UnityEngine.Rendering var rth = AllocAutoSizedRenderTexture(width, height, info); rth.referenceSize = new Vector2Int(width, height); - rth.scaleFunc = scaleFunc; + + if (info.enableShadingRate) + { + rth.scaleFunc = (refSize) => + { + var dimensions = scaleFunc(refSize); + + // shading rate image resolution is in tiles and current values are in pixels. + // Alloc() with a scaling function is based on refSize which is in pixels. + // adjust dimensions + return ShadingRateImage.GetAllocTileSize(dimensions); + }; + } + else + rth.scaleFunc = scaleFunc; return rth; } - // Internal function - RTHandle AllocAutoSizedRenderTexture( + internal RTHandle AllocAutoSizedRenderTexture( int width, int height, - int slices, + int slices, GraphicsFormat format, FilterMode filterMode, TextureWrapMode wrapMode, @@ -1305,13 +1384,24 @@ namespace UnityEngine.Rendering bool useDynamicScaleExplicit, RenderTextureMemoryless memoryless, VRTextureUsage vrUsage, + bool enableShadingRate, string name ) { + if (enableShadingRate) + { + // this function is called when auto scaling is needed and always expect size in pixels. + // shading rate image resolution is in tiles and current values are in pixels. + // then must adjust width and height + var actualDimensions = ShadingRateImage.GetAllocTileSize(width, height); + width = actualDimensions.x; + height = actualDimensions.y; + } + var rt = CreateRenderTexture( width, height, format, slices, filterMode, wrapMode, wrapMode, wrapMode, dimension, enableRandomWrite, useMipMap , autoGenerateMips, isShadowMap, anisoLevel, mipMapBias, msaaSamples, bindTextureMS - , useDynamicScale, useDynamicScaleExplicit, memoryless, vrUsage, name); + , useDynamicScale, useDynamicScaleExplicit, memoryless, vrUsage, enableShadingRate, name); var rth = new RTHandle(this); rth.SetRenderTexture(rt); @@ -1324,15 +1414,22 @@ namespace UnityEngine.Rendering return rth; } - RTHandle AllocAutoSizedRenderTexture(int width, int height, RTHandleAllocInfo info) + internal RTHandle AllocAutoSizedRenderTexture(int width, int height, RTHandleAllocInfo info) { - bool isShadowMap = false; - bool useDynamicScaleExplicit = false; + if (info.enableShadingRate) + { + // this function is called when auto scaling is needed and always expect size in pixels. + // shading rate image resolution is in tiles and current values are in pixels. + // then must adjust width and height + var actualDimensions = ShadingRateImage.GetAllocTileSize(width, height); + width = actualDimensions.x; + height = actualDimensions.y; + } var rt = CreateRenderTexture( width, height, info.format, info.slices, info.filterMode, info.wrapModeU, info.wrapModeV, info.wrapModeW, info.dimension, info.enableRandomWrite, info.useMipMap - , info.autoGenerateMips, isShadowMap, info.anisoLevel, info.mipMapBias, info.msaaSamples, info.bindTextureMS - , info.useDynamicScale, useDynamicScaleExplicit, info.memoryless, info.vrUsage, info.name); + , info.autoGenerateMips, info.isShadowMap, info.anisoLevel, info.mipMapBias, info.msaaSamples, info.bindTextureMS + , info.useDynamicScale, info.useDynamicScaleExplicit, info.memoryless, info.vrUsage, info.enableShadingRate, info.name); var rth = new RTHandle(this); rth.SetRenderTexture(rt); diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Textures/RTHandles.cs b/Packages/com.unity.render-pipelines.core/Runtime/Textures/RTHandles.cs index 35698efb..1cd7b308 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Textures/RTHandles.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Textures/RTHandles.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.CompilerServices; using UnityEngine.Assertions; using UnityEngine.Experimental.Rendering; @@ -48,7 +49,7 @@ namespace UnityEngine.Rendering /// Allocate a new fixed sized RTHandle with the default RTHandle System. /// /// With of the RTHandle. - /// Heigh of the RTHandle. + /// height of the RTHandle. /// Number of slices of the RTHandle. /// Bit depths of a depth buffer. /// GraphicsFormat of a color buffer. @@ -122,9 +123,9 @@ namespace UnityEngine.Rendering /// Allocate a new fixed sized RTHandle with the default RTHandle System. /// /// With of the RTHandle. - /// Heigh of the RTHandle. + /// height of the RTHandle. /// GraphicsFormat of a color or depth stencil buffer. - /// Number of slices of the RTHandle. + /// Number of slices of the RTHandle. /// Filtering mode of the RTHandle. /// Addressing mode of the RTHandle. /// Texture dimension of the RTHandle. @@ -146,7 +147,7 @@ namespace UnityEngine.Rendering int width, int height, GraphicsFormat format, - int slices = 1, + int slices = 1, FilterMode filterMode = FilterMode.Point, TextureWrapMode wrapMode = TextureWrapMode.Repeat, TextureDimension dimension = TextureDimension.Tex2D, @@ -169,7 +170,7 @@ namespace UnityEngine.Rendering width, height, format, - slices, + slices, filterMode, wrapMode, dimension, @@ -193,7 +194,7 @@ namespace UnityEngine.Rendering /// Allocate a new fixed sized RTHandle with the default RTHandle System. /// /// With of the RTHandle. - /// Heigh of the RTHandle. + /// height of the RTHandle. /// U coordinate wrapping mode of the RTHandle. /// V coordinate wrapping mode of the RTHandle. /// W coordinate wrapping mode of the RTHandle. @@ -302,38 +303,49 @@ namespace UnityEngine.Rendering string name = "" ) { - var format = GetFormat(descriptor.graphicsFormat, descriptor.depthStencilFormat); - - var result = s_DefaultInstance.Alloc( - descriptor.width, - descriptor.height, - format, - descriptor.volumeDepth, - filterMode, - wrapMode, - descriptor.dimension, - descriptor.enableRandomWrite, - descriptor.useMipMap, - descriptor.autoGenerateMips, - isShadowMap, - anisoLevel, - mipMapBias, - (MSAASamples)descriptor.msaaSamples, - descriptor.bindMS, - descriptor.useDynamicScale, - descriptor.useDynamicScaleExplicit, - descriptor.memoryless, - descriptor.vrUsage, - name - ); - return result; + return s_DefaultInstance.Alloc(descriptor.width, descriptor.height, + GetRTHandleAllocInfo(descriptor, filterMode, wrapMode, anisoLevel, mipMapBias, name)); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] static internal GraphicsFormat GetFormat(GraphicsFormat colorFormat, GraphicsFormat depthStencilFormat) { return (depthStencilFormat==GraphicsFormat.None) ? colorFormat : depthStencilFormat; } + // Internal RtDesc to RtAllocInfo conversion utility function. + // Keep internal for future changes. + // + // NOTE: It has no default values to avoid param ambiguity of the flat RtHandleAlloc API. + // NOTE: There isn't 100% field to field mapping, so some fields might need manual adjustment afterwards. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static RTHandleAllocInfo GetRTHandleAllocInfo(in RenderTextureDescriptor desc, FilterMode filterMode, TextureWrapMode wrapMode, int anisoLevel, float mipMapBias, string name) + { + return new RTHandleAllocInfo(name) + { + slices = desc.volumeDepth, + format = RTHandles.GetFormat(desc.graphicsFormat, desc.depthStencilFormat), + filterMode = filterMode, + wrapModeU = wrapMode, + wrapModeV = wrapMode, + wrapModeW = wrapMode, + dimension = desc.dimension, + enableRandomWrite = desc.enableRandomWrite, + useMipMap = desc.useMipMap, + autoGenerateMips = desc.autoGenerateMips, + isShadowMap = desc.shadowSamplingMode != ShadowSamplingMode.None, + anisoLevel = anisoLevel, + mipMapBias = mipMapBias, + msaaSamples = (MSAASamples)desc.msaaSamples, + bindTextureMS = desc.bindMS, + useDynamicScale = desc.useDynamicScale, + useDynamicScaleExplicit = desc.useDynamicScaleExplicit, + memoryless = desc.memoryless, + vrUsage = desc.vrUsage, + enableShadingRate = desc.enableShadingRate, + }; + } + /// /// Allocate a new automatically sized RTHandle for the default RTHandle System. /// @@ -431,7 +443,7 @@ namespace UnityEngine.Rendering public static RTHandle Alloc( Vector2 scaleFactor, GraphicsFormat format, - int slices = 1, + int slices = 1, FilterMode filterMode = FilterMode.Point, TextureWrapMode wrapMode = TextureWrapMode.Repeat, TextureDimension dimension = TextureDimension.Tex2D, @@ -496,29 +508,8 @@ namespace UnityEngine.Rendering string name = "" ) { - var format = GetFormat(descriptor.graphicsFormat, descriptor.depthStencilFormat); - - return s_DefaultInstance.Alloc( - scaleFactor, - format, - descriptor.volumeDepth, - filterMode, - wrapMode, - descriptor.dimension, - descriptor.enableRandomWrite, - descriptor.useMipMap, - descriptor.autoGenerateMips, - isShadowMap, - anisoLevel, - mipMapBias, - (MSAASamples)descriptor.msaaSamples, - descriptor.bindMS, - descriptor.useDynamicScale, - descriptor.useDynamicScaleExplicit, - descriptor.memoryless, - descriptor.vrUsage, - name - ); + return s_DefaultInstance.Alloc(scaleFactor, + GetRTHandleAllocInfo(descriptor, filterMode, wrapMode, anisoLevel, mipMapBias, name)); } /// @@ -697,29 +688,8 @@ namespace UnityEngine.Rendering Assert.IsFalse(descriptor.graphicsFormat != GraphicsFormat.None && descriptor.depthStencilFormat != GraphicsFormat.None, "The RenderTextureDescriptor used to create RTHandle " + name + " contains both graphicsFormat and depthStencilFormat which is not allowed."); - var format = GetFormat( descriptor.graphicsFormat, descriptor.depthStencilFormat); - - return s_DefaultInstance.Alloc( - scaleFunc, - format, - descriptor.volumeDepth, - filterMode, - wrapMode, - descriptor.dimension, - descriptor.enableRandomWrite, - descriptor.useMipMap, - descriptor.autoGenerateMips, - isShadowMap, - anisoLevel, - mipMapBias, - (MSAASamples)descriptor.msaaSamples, - descriptor.bindMS, - descriptor.useDynamicScale, - descriptor.useDynamicScaleExplicit, - descriptor.memoryless, - descriptor.vrUsage, - name - ); + return s_DefaultInstance.Alloc(scaleFunc, + GetRTHandleAllocInfo(descriptor, filterMode, wrapMode, anisoLevel, mipMapBias, name)); } /// diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blitter.cs b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blitter.cs index 27d7fa2b..dfd48165 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blitter.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blitter.cs @@ -4,6 +4,7 @@ using UnityEngine.Experimental.Rendering; using UnityEngine.Assertions; using System.Text.RegularExpressions; using UnityEngine.Rendering.RenderGraphModule.Util; +using UnityEngine.Rendering.RenderGraphModule; #if UNITY_EDITOR using UnityEditor; #endif @@ -13,6 +14,19 @@ namespace UnityEngine.Rendering /// /// Various blit (texture copy) utilities for the Scriptable Render Pipelines. /// + /// + /// The Blitter class works on textures and targets identified with , + /// but most importantly with . This enables + /// copying to / from textures managed by the . + /// + /// To use the Blitter functionality in the context of custom Scriptable Render Pipelines, you must first create + /// a blit shader that implements various passes covering the blit variants. To facilitate this, you can create a + /// modified version of the Universal Render Pipeline CoreBlit.shader as displayed in the documentation of the + /// method. + /// + /// Prior to using the Blitter, you must call once. When the render pipeline is to + /// be disposed, you must call the method to dispose of resources created by the Blitter. + /// public static class Blitter { static Material s_Copy; @@ -43,6 +57,7 @@ namespace UnityEngine.Rendering } // This enum needs to be in sync with the shader pass names and indices of the Blit.shader in every pipeline. + // Keep in sync also with the documentation for the Initialize method below. enum BlitShaderPassNames { Nearest = 0, @@ -83,10 +98,51 @@ namespace UnityEngine.Rendering static int[] s_BlitColorAndDepthShaderPassIndicesMap; /// - /// Initialize Blitter resources. Must be called once before any use + /// Initializes the Blitter resources. This must be called once before any use. /// - /// Blit shader - /// Blit shader + /// The shader to use when using the blitting / copying methods which operate only on color. + /// The shader to use when using the BlitColorAndDepth methods which operate on both color and depth. + /// + /// Shaders sent to the blitPS parameter should support multiple passes with the corresponding name: + /// + /// Nearest + /// Bilinear + /// NearestQuad + /// BilinearQuad + /// NearestQuadPadding + /// BilinearQuadPadding + /// NearestQuadPaddingRepeat + /// BilinearQuadPaddingRepeat + /// BilinearQuadPaddingOctahedral + /// NearestQuadPaddingAlphaBlend + /// BilinearQuadPaddingAlphaBlend + /// NearestQuadPaddingAlphaBlendRepeat + /// BilinearQuadPaddingAlphaBlendRepeat + /// BilinearQuadPaddingAlphaBlendOctahedral + /// CubeToOctahedral + /// CubeToOctahedralLuminance + /// CubeToOctahedralAlpha + /// CubeToOctahedralRed + /// BilinearQuadLuminance + /// BilinearQuadAlpha + /// BilinearQuadRed + /// NearestCubeToOctahedralPadding + /// BilinearCubeToOctahedralPadding + /// + /// Basic vertex and fragment shader functions are available in Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl for each of these pass types. + /// Similarly, the shaders for the blitColorAndDepthPS parameter should support two passes with these names: + /// + /// ColorOnly + /// ColorAndDepth + /// + /// + /// + /// Blit color shader for URP which implements all the above passes with a user defined FragmentURPBlit fragment function to support debug passes + /// and color space conversion. + /// + /// Blit color and depth shader for URP. + /// + /// public static void Initialize(Shader blitPS, Shader blitColorAndDepthPS) { if (s_Blit != null) @@ -207,7 +263,7 @@ namespace UnityEngine.Rendering } /// - /// Release Blitter resources. + /// Releases all the internal Blitter resources. Must be called when the Blitter object is to be disposed. /// public static void Cleanup() { @@ -228,11 +284,12 @@ namespace UnityEngine.Rendering } /// - /// Returns the default blit material. + /// Returns the default blit material constructed from the blit shader passed as the first argument of + /// the method. /// /// Dimension of the texture to blit, either 2D or 2D Array. /// Blit only a single slice of the array if applicable. - /// The default blit material for specified arguments. + /// The default blit material for the specified arguments. static public Material GetBlitMaterial(TextureDimension dimension, bool singleSlice = false) { var material = (dimension == TextureDimension.Tex2DArray) @@ -284,23 +341,41 @@ namespace UnityEngine.Rendering internal static bool CanCopyMSAA() { + //Temporary disable most msaa copies as we fix UUM-67324 which is a bit more involved due to the internal work required + GraphicsDeviceType deviceType = SystemInfo.graphicsDeviceType; + if (deviceType != GraphicsDeviceType.Metal || deviceType != GraphicsDeviceType.Vulkan) + { + return false; + } + + // This test works since the second pass has the following pragmas and will not be compiled if they are not supported + // #pragma target 4.5 + // #pragma require msaatex return s_Copy.passCount == 2; } /// - /// Copy a texture to another texture using framebuffer fetch. + /// Copies a texture to another texture using framebuffer fetch. /// /// Command Buffer used for rendering. - internal static void CopyTexture(RasterCommandBuffer cmd, bool isMSAA) + /// Disable the special handling when XR is active where the source and destination are considered array + /// textures with a slice for each eye. Setting this to true will consider source and destination as regular 2D textures. When XR is + /// disabled, textures are always 2D so forcing them to 2D has no impact. + internal static void CopyTexture(RasterCommandBuffer cmd, bool isMSAA, bool force2DForXR = false) { + if (force2DForXR) cmd.EnableShaderKeyword("DISABLE_TEXTURE2D_X_ARRAY"); + DrawTriangle(cmd, s_Copy, isMSAA ? 1 : 0); + + // Set back the XR texture for regular XR calls + if (force2DForXR) cmd.DisableShaderKeyword("DISABLE_TEXTURE2D_X_ARRAY"); } /// - /// Blit a RTHandle texture. + /// Blits a RTHandle texture. /// /// Command Buffer used for rendering. - /// Source RTHandle. + /// RTHandle of the source texture to copy from. /// Scale and bias for sampling the input texture. /// Mip level to blit from source. /// Source texture slice index. @@ -311,10 +386,10 @@ namespace UnityEngine.Rendering } /// - /// Blit a RTHandle texture. + /// Blits a RTHandle texture. /// /// Command Buffer used for rendering. - /// Source RTHandle. + /// RTHandle of the source texture to copy from. /// Scale and bias for sampling the input texture. /// Mip level to blit from source. /// Source texture slice index. @@ -326,26 +401,81 @@ namespace UnityEngine.Rendering } /// - /// Blit a RTHandle texture. + /// Adds in a a command to copy an XR compatible texture identified by its into + /// the currently bound render target's color buffer. /// - /// Command Buffer used for rendering. - /// Source RTHandle. - /// Scale and bias for sampling the input texture. - /// Mip level to blit. - /// Enable bilinear filtering. + /// + /// Copying is performed using the blit shader passed as the first argument of + /// the method. + /// + /// This overload is meant for textures and render targets which depend on XR output modes by proper handling, when + /// necessary, of left / right eye data copying. This generally correspond to textures which represent full screen + /// + /// The scaleBias parameter controls the rectangle of pixels in the source texture to copy by manipulating + /// the source texture coordinates. The X and Y coordinates store the scaling factor to apply to these texture + /// coordinates, while the Z and W coordinates store the texture coordinate offsets. The operation will always + /// write to the full destination render target rectangle. + /// + /// Command Buffer used for recording the action. + /// RTHandle of the source texture to copy from. + /// Scale and bias for sampling the source texture. + /// Mip level of the source texture to copy from. + /// Enable bilinear filtering when copying. + /// + /// + /// public static void BlitTexture(RasterCommandBuffer cmd, RTHandle source, Vector4 scaleBias, float mipLevel, bool bilinear) { BlitTexture(cmd.m_WrappedCommandBuffer, source, scaleBias, mipLevel, bilinear); } /// - /// Blit a RTHandle texture. + /// Adds in a a command to copy an XR compatible texture identified by its into + /// the currently bound render target's color buffer. /// - /// Command Buffer used for rendering. - /// Source RTHandle. - /// Scale and bias for sampling the input texture. - /// Mip level to blit. - /// Enable bilinear filtering. + /// + /// Copying is performed using the blit shader passed as the first argument of + /// the method. + /// + /// This overload is meant for textures and render targets which depend on XR output modes by proper handling, when + /// necessary, of left / right eye data copying. This generally correspond to textures which represent full screen + /// data that may differ between eyes. + /// + /// The scaleBias parameter controls the rectangle of pixels in the source texture to copy by manipulating + /// the source texture coordinates. The X and Y coordinates store the scaling factor to apply to these texture + /// coordinates, while the Z and W coordinates store the texture coordinate offsets. The operation will always + /// write to the full destination render target rectangle. + /// + /// Command Buffer used for recording the action. + /// RTHandle of the source texture to copy from. + /// Scale and bias for sampling the source texture. + /// Mip level of the source texture to copy from. + /// Enable bilinear filtering when copying. + /// + /// + /// public static void BlitTexture(CommandBuffer cmd, RTHandle source, Vector4 scaleBias, float mipLevel, bool bilinear) { s_PropertyBlock.SetFloat(BlitShaderIDs._BlitMipLevel, mipLevel); @@ -353,26 +483,74 @@ namespace UnityEngine.Rendering } /// - /// Blit a RTHandle texture 2D. + /// Adds in a a command to copy a texture identified by its into + /// the currently bound render target's color buffer. /// - /// Command Buffer used for rendering. - /// Source RTHandle. - /// Scale and bias for sampling the input texture. - /// Mip level to blit. - /// Enable bilinear filtering. + /// + /// Copying is performed using the blit shader passed as the first argument of + /// the method. + /// + /// The scaleBias parameter controls the rectangle of pixels in the source texture to copy by manipulating + /// the source texture coordinates. The X and Y coordinates store the scaling factor to apply to these texture + /// coordinates, while the Z and W coordinates store the texture coordinate offsets. The operation will always + /// write to the full destination render target rectangle. + /// + /// Command Buffer used for recording the action. + /// RTHandle of the source texture to copy from. + /// Scale and bias for sampling the source texture. + /// Mip level of the source texture to copy from. + /// Enable bilinear filtering when copying. + /// + /// + /// public static void BlitTexture2D(RasterCommandBuffer cmd, RTHandle source, Vector4 scaleBias, float mipLevel, bool bilinear) { BlitTexture2D(cmd.m_WrappedCommandBuffer, source, scaleBias, mipLevel, bilinear); } /// - /// Blit a RTHandle texture 2D. + /// Adds in a a command to copy a texture identified by its into + /// the currently bound render target's color buffer. /// - /// Command Buffer used for rendering. - /// Source RTHandle. - /// Scale and bias for sampling the input texture. - /// Mip level to blit. - /// Enable bilinear filtering. + /// + /// Copying is performed using the blit shader passed as the first argument of + /// the method. + /// + /// The scaleBias parameter controls the rectangle of pixels in the source texture to copy by manipulating + /// the source texture coordinates. The X and Y coordinates store the scaling factor to apply to these texture + /// coordinates, while the Z and W coordinates store the texture coordinate offsets. The operation will always + /// write to the full destination render target rectangle. + /// + /// Command Buffer used for recording the action. + /// RTHandle of the source texture to copy from. + /// Scale and bias for sampling the source texture. + /// Mip level of the source texture to copy from. + /// Enable bilinear filtering when copying. + /// + /// + /// public static void BlitTexture2D(CommandBuffer cmd, RTHandle source, Vector4 scaleBias, float mipLevel, bool bilinear) { s_PropertyBlock.SetFloat(BlitShaderIDs._BlitMipLevel, mipLevel); @@ -380,28 +558,90 @@ namespace UnityEngine.Rendering } /// - /// Blit a 2D texture and depth buffer. + /// Adds in a a command to copy two XR compatible color and depth textures into + /// the currently bound render target's respective color and depth buffer. /// - /// Command Buffer used for rendering. - /// Source Texture for color. - /// Source RenderTexture for depth. - /// Scale and bias for sampling the input texture. - /// Mip level to blit. - /// Enable depth blit. + /// + /// Although the depth render texture can be passed as a parameter, the copying of the depth information is + /// optional and must be enabled with the blitDepth parameter. + /// The copying is done using the blitColorAndDepth shader passed as the second argument of + /// the method. + /// + /// This overload is meant for textures and render targets which depend on XR output modes by proper handling, when + /// necessary, of left / right eye data copying. This generally corresponds to textures which represent full screen + /// data that may differ between eyes. + /// + /// The scaleBias parameter controls the rectangle of pixels in the source texture to copy by manipulating + /// the source texture coordinates. The X and Y coordinates store the scaling factor to apply to these texture + /// coordinates, while the Z and W coordinates store the texture coordinate offsets. The operation will always + /// write to the full destination render target rectangle. + /// + /// Command Buffer used for recording the action. + /// Source color texture to copy from. + /// Source depth render texture to copy from. + /// Scale and bias for sampling the source texture. + /// Mip level of the source texture to copy from. + /// Enable copying of the source depth texture. + /// + /// + /// public static void BlitColorAndDepth(RasterCommandBuffer cmd, Texture sourceColor, RenderTexture sourceDepth, Vector4 scaleBias, float mipLevel, bool blitDepth) { BlitColorAndDepth(cmd.m_WrappedCommandBuffer, sourceColor, sourceDepth, scaleBias, mipLevel, blitDepth); } /// - /// Blit a 2D texture and depth buffer. + /// Adds in a a command to copy two XR compatible color and depth textures into + /// the currently bound render target's respective color and depth buffer. /// - /// Command Buffer used for rendering. - /// Source Texture for color. - /// Source RenderTexture for depth. - /// Scale and bias for sampling the input texture. - /// Mip level to blit. - /// Enable depth blit. + /// + /// Although the depth render texture can be passed as a parameter, the copying of the depth information is + /// optional and must be enabled with the blitDepth parameter. + /// The copying is done using the blitColorAndDepth shader passed as the second argument of + /// the method. + /// + /// This overload is meant for textures and render targets which depend on XR output modes by proper handling, when + /// necessary, of left / right eye data copying. This generally corresponds to textures which represent full screen + /// data that may differ between eyes. + /// + /// The scaleBias parameter controls the rectangle of pixels in the source texture to copy by manipulating + /// the source texture coordinates. The X and Y coordinates store the scaling factor to apply to these texture + /// coordinates, while the Z and W coordinates store the texture coordinate offsets. The operation will always + /// write to the full destination render target rectangle. + /// + /// Command Buffer used for recording the action. + /// Source color texture to copy from. + /// Source depth render texture to copy from. + /// Scale and bias for sampling the source texture. + /// Mip level of the source texture to copy from. + /// Enable copying of the source depth texture. + /// + /// + /// public static void BlitColorAndDepth(CommandBuffer cmd, Texture sourceColor, RenderTexture sourceDepth, Vector4 scaleBias, float mipLevel, bool blitDepth) { s_PropertyBlock.SetFloat(BlitShaderIDs._BlitMipLevel, mipLevel); @@ -413,26 +653,72 @@ namespace UnityEngine.Rendering } /// - /// Blit a RTHandle texture + /// Adds in a a command to copy a texture identified by its into + /// the currently bound render target's color buffer, using a user material and specific shader pass. /// - /// Command Buffer used for rendering. - /// Source RTHandle. - /// Scale and bias for sampling the input texture. - /// Material to invoke when blitting. - /// Pass idx within the material to invoke. + /// + /// The source texture will be bound to the "_BlitTexture" shader property. + /// The scaleBias parameter controls the rectangle of pixels in the source texture to copy by manipulating + /// the source texture coordinates. The X and Y coordinates store the scaling factor to apply to these texture + /// coordinates, while the Z and W coordinates store the texture coordinate offsets. The operation will always + /// write to the full destination render target rectangle. + /// + /// Command Buffer used for recording the action. + /// RTHandle of the source texture to copy from. + /// Scale and bias for sampling the source texture. + /// The material to use for writing to the destination target. + /// The index of the pass to use in the material's shader. + /// + /// + /// public static void BlitTexture(RasterCommandBuffer cmd, RTHandle source, Vector4 scaleBias, Material material, int pass) { BlitTexture(cmd.m_WrappedCommandBuffer, source, scaleBias, material, pass); } /// - /// Blit a RTHandle texture + /// Adds in a a command to copy a texture identified by its into + /// the currently bound render target's color buffer, using a user material and specific shader pass. /// - /// Command Buffer used for rendering. - /// Source RTHandle. - /// Scale and bias for sampling the input texture. - /// Material to invoke when blitting. - /// Pass idx within the material to invoke. + /// + /// The source texture will be bound to the "_BlitTexture" shader property. + /// The scaleBias parameter controls the rectangle of pixels in the source texture to copy by manipulating + /// the source texture coordinates. The X and Y coordinates store the scaling factor to apply to these texture + /// coordinates, while the Z and W coordinates store the texture coordinate offsets. The operation will always + /// write to the full destination render target rectangle. + /// + /// Command Buffer used for recording the action. + /// RTHandle of the source texture to copy from. + /// Scale and bias for sampling the source texture. + /// The material to use for writing to the destination target. + /// The index of the pass to use in the material's shader. + /// + /// + /// public static void BlitTexture(CommandBuffer cmd, RTHandle source, Vector4 scaleBias, Material material, int pass) { s_PropertyBlock.SetVector(BlitShaderIDs._BlitScaleBias, scaleBias); @@ -441,26 +727,72 @@ namespace UnityEngine.Rendering } /// - /// Blit a RTHandle texture + /// Adds in a a command to copy a texture identified by its RenderTargetIdentifier into + /// the currently bound render target's color buffer, using a user material and specific shader pass. /// - /// Command Buffer used for rendering. - /// Source render target. - /// Scale and bias for sampling the input texture. - /// Material to invoke when blitting. - /// Pass idx within the material to invoke. + /// + /// The source texture will be bound to the "_BlitTexture" shader property. + /// The scaleBias parameter controls the rectangle of pixels in the source texture to copy by manipulating + /// the source texture coordinates. The X and Y coordinates store the scaling factor to apply to these texture + /// coordinates, while the Z and W coordinates store the texture coordinate offsets. The operation will always + /// write to the full destination render target rectangle. + /// + /// Command Buffer used for recording the action. + /// RenderTargetIdentifier of the source texture to copy from. + /// Scale and bias for sampling the source texture. + /// The material to use for writing to the destination target. + /// The index of the pass to use in the material's shader. + /// + /// + /// public static void BlitTexture(RasterCommandBuffer cmd, RenderTargetIdentifier source, Vector4 scaleBias, Material material, int pass) { BlitTexture(cmd.m_WrappedCommandBuffer, source, scaleBias, material, pass); } /// - /// Blit a RTHandle texture + /// Adds in a a command to copy a texture identified by its RenderTargetIdentifier into + /// the currently bound render target's color buffer, using a user material and specific shader pass. /// - /// Command Buffer used for rendering. - /// Source render target. - /// Scale and bias for sampling the input texture. - /// Material to invoke when blitting. - /// Pass idx within the material to invoke. + /// + /// The source texture will be bound to the "_BlitTexture" shader property. + /// The scaleBias parameter controls the rectangle of pixels in the source texture to copy by manipulating + /// the source texture coordinates. The X and Y coordinates store the scaling factor to apply to these texture + /// coordinates, while the Z and W coordinates store the texture coordinate offsets. The operation will always + /// write to the full destination render target rectangle. + /// + /// Command Buffer used for recording the action. + /// RenderTargetIdentifier of the source texture to copy from. + /// Scale and bias for sampling the source texture. + /// The material to use for writing to the destination target. + /// The index of the pass to use in the material's shader. + /// + /// + /// public static void BlitTexture(CommandBuffer cmd, RenderTargetIdentifier source, Vector4 scaleBias, Material material, int pass) { s_PropertyBlock.Clear(); @@ -472,13 +804,28 @@ namespace UnityEngine.Rendering } /// - /// Blit a Texture with a specified material. The reference name "_BlitTexture" will be used to bind the input texture. + /// Adds in a a command to copy a texture identified by its RenderTargetIdentifier into + /// a destination render target, using a user material and specific shader pass. /// - /// Command Buffer used for rendering. - /// Source render target. - /// Destination render target. - /// Material to invoke when blitting. - /// Pass idx within the material to invoke. + /// + /// he source texture will be bound to the "_BlitTexture" shader property. + /// + /// This overload is equivalent + /// to + /// with the loadAction set to and the storeAction set to . + /// + /// Command Buffer used for recording the action. + /// RenderTargetIdentifier of the source texture to copy from. + /// RenderTargetIdentifier of the destination render target to copy to. + /// The material to use for writing to the destination target. + /// The index of the pass to use in the material's shader. + /// + /// + /// public static void BlitTexture(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier destination, Material material, int pass) { s_PropertyBlock.Clear(); @@ -491,15 +838,27 @@ namespace UnityEngine.Rendering } /// - /// Blit a Texture with a specified material. The reference name "_BlitTexture" will be used to bind the input texture. + /// Adds in a a command to copy a texture identified by its RenderTargetIdentifier into + /// a destination render target, using a user material, specific shader pass and specific load / store actions. /// - /// Command Buffer used for rendering. - /// Source render target. - /// Destination render target. - /// Load action. - /// Store action. - /// Material to invoke when blitting. - /// Pass idx within the material to invoke. + /// + /// The source texture will be bound to the "_BlitTexture" shader property. + /// + /// Command Buffer used for recording the action. + /// RenderTargetIdentifier of the source texture to copy from. + /// RenderTargetIdentifier of the destination render target to copy to. + /// Load action to perform on the destination render target prior to the copying. + /// Store action to perform on the destination render target after the copying. + /// The material to use for writing to the destination target. + /// The index of the pass to use in the material's shader. + /// + /// + /// public static void BlitTexture(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier destination, RenderBufferLoadAction loadAction, RenderBufferStoreAction storeAction, Material material, int pass) { s_PropertyBlock.Clear(); @@ -512,25 +871,32 @@ namespace UnityEngine.Rendering } /// - /// Blit a quad with a given Material. Set the destination parameter before using this method. + /// Adds in a a command to draw a full screen quad, using a user material and specific shader pass. /// - /// Command Buffer used for rendering. - /// Scale and bias values for sampling the input texture. - /// Material to invoke when blitting. - /// Pass index within the Material to invoke. + /// + /// This method gives you freedom on how to write your blit shader by just taking a material, assumed to + /// be properly configured with input textures already bound to the material. In this method, the "_BlitScaleBias" shader + /// property will be set on the material to the scaleBias parameter, prior to the draw. + /// + /// The scaleBias parameter controls the rectangle of pixels in the source texture to copy by manipulating + /// the source texture coordinates. The X and Y coordinates store the scaling factor to apply to these texture + /// coordinates, while the Z and W coordinates store the texture coordinate offsets. The operation will always + /// write to the full destination render target rectangle. + /// + /// Command Buffer used for recording the action. + /// Scale and bias for sampling the source texture. + /// The material to use for writing to the destination target. + /// The index of the pass to use in the material's shader. public static void BlitTexture(CommandBuffer cmd, Vector4 scaleBias, Material material, int pass) { s_PropertyBlock.SetVector(BlitShaderIDs._BlitScaleBias, scaleBias); DrawTriangle(cmd, material, pass); } + /// /// - /// Blit a quad with a given Material. Set the destination parameter before using this method. + /// Adds in a a command to draw a full screen quad, using a user material and specific shader pass. /// - /// Command Buffer used for rendering. - /// Scale and bias values for sampling the input texture. - /// Material to invoke when blitting. - /// Pass index within the Material to invoke. public static void BlitTexture(RasterCommandBuffer cmd, Vector4 scaleBias, Material material, int pass) { s_PropertyBlock.SetVector(BlitShaderIDs._BlitScaleBias, scaleBias); @@ -538,14 +904,32 @@ namespace UnityEngine.Rendering } /// - /// Blit a RTHandle to another RTHandle. - /// This will properly account for partial usage (in term of resolution) of the texture for the current viewport. + /// Adds in a a command to copy a camera related XR compatible texture identified by + /// its into a destination render target. /// - /// Command Buffer used for rendering. - /// Source RTHandle. - /// Destination RTHandle. - /// Mip level to blit. - /// Enable bilinear filtering. + /// + /// Camera related textures are created with + /// using or + /// to + /// automatically determine their resolution relative to the camera's render target resolution. Compared to the + /// various and methods, this function automatically handles the + /// scaleBias parameter. The copy operation will always write to the full destination render target rectangle. + /// + /// Command Buffer used for recording the action. + /// RTHandle of the source texture to copy from. + /// RTHandle of the destination render target to copy to. + /// Mip level of the source texture to copy from. + /// Enable bilinear filtering when copying. + /// + /// + /// public static void BlitCameraTexture(CommandBuffer cmd, RTHandle source, RTHandle destination, float mipLevel = 0.0f, bool bilinear = false) { Vector2 viewportScale = source.useScaling ? new Vector2(source.rtHandleProperties.rtHandleScale.x, source.rtHandleProperties.rtHandleScale.y) : Vector2.one; @@ -555,14 +939,32 @@ namespace UnityEngine.Rendering } /// - /// Blit a RThandle Texture2D RTHandle to another RTHandle. - /// This will properly account for partial usage (in term of resolution) of the texture for the current viewport. + /// Adds in a a command to copy a camera related texture identified by + /// its into a destination render target. /// - /// Command Buffer used for rendering. - /// Source RTHandle. - /// Destination RTHandle. - /// Mip level to blit. - /// Enable bilinear filtering. + /// + /// Camera related textures are created with the + /// method using or + /// to + /// automatically determine their resolution relative to the camera's render target resolution. Compared to the + /// various and methods, this function automatically handles the + /// scaleBias parameter. The copy operation will always write to the full destination render target rectangle. + /// + /// Command Buffer used for recording the action. + /// RTHandle of the source texture to copy from. + /// RTHandle of the destination render target to copy to. + /// Mip level of the source texture to copy from. + /// Enable bilinear filtering when copying. + /// + /// + /// public static void BlitCameraTexture2D(CommandBuffer cmd, RTHandle source, RTHandle destination, float mipLevel = 0.0f, bool bilinear = false) { Vector2 viewportScale = source.useScaling ? new Vector2(source.rtHandleProperties.rtHandleScale.x, source.rtHandleProperties.rtHandleScale.y) : Vector2.one; @@ -572,15 +974,40 @@ namespace UnityEngine.Rendering } /// - /// Blit a RTHandle to another RTHandle. - /// This will properly account for partial usage (in term of resolution) of the texture for the current viewport. - /// This overloads allows the user to override the default blit shader + /// Adds in a a command to copy a camera related texture identified by + /// its into a destination render target, using a user material and specific shader pass. /// - /// Command Buffer used for rendering. - /// Source RTHandle. - /// Destination RTHandle. - /// The material to use when blitting - /// pass to use of the provided material + /// + /// Camera related textures are created with the + /// method using or + /// to + /// automatically determine their resolution relative to the camera's render target resolution. Compared to the + /// various and methods, this function automatically handles the + /// scaleBias parameter of these methods. The copy operation will always write to the full destination render target rectangle. + /// + /// The "_BlitTexture" shader property will be set to the source texture and the "_BlitScaleBias" shader + /// property will be set to the appropriate parameter, prior to the draw. + /// + /// This overload is equivalent + /// to + /// with the loadAction set to and the storeAction set + /// to . + /// + /// Command Buffer used for recording the action. + /// RTHandle of the source texture to copy from. + /// RTHandle of the destination render target to copy to. + /// The material to use for writing to the destination target. + /// The index of the pass to use in the material's shader. + /// + /// + /// public static void BlitCameraTexture(CommandBuffer cmd, RTHandle source, RTHandle destination, Material material, int pass) { Vector2 viewportScale = source.useScaling ? new Vector2(source.rtHandleProperties.rtHandleScale.x, source.rtHandleProperties.rtHandleScale.y) : Vector2.one; @@ -590,17 +1017,38 @@ namespace UnityEngine.Rendering } /// - /// Blit a RTHandle to another RTHandle. - /// This will properly account for partial usage (in term of resolution) of the texture for the current viewport. - /// This overloads allows the user to override the default blit shader + /// Adds in a a command to copy a camera related texture identified by + /// its into a destination render target, using a user material, specific shader pass and specific load / store actions. /// - /// Command Buffer used for rendering. - /// Source RTHandle. - /// Destination RTHandle. - /// Load action. - /// Store action. - /// The material to use when blitting - /// pass to use of the provided material + /// + /// Camera related textures are created with the + /// method using or + /// to + /// automatically determine their resolution relative to the camera's render target resolution. Compared to the + /// various and methods, this function automatically handles the + /// scaleBias parameter. The copy operation will always write to the full destination render target rectangle. + /// + /// The "_BlitTexture" shader property will be set to the source texture and the "_BlitScaleBias" shader + /// property will be set to the appropriate value, prior to the draw. + /// + /// Command Buffer used for recording the action. + /// RTHandle of the source texture to copy from. + /// RTHandle of the destination render target to copy to. + /// Load action to perform on the destination render target prior to the copying. + /// Store action to perform on the destination render target after the copying. + /// The material to use for writing to the destination target. + /// The index of the pass to use in the material's shader. + /// + /// + /// public static void BlitCameraTexture(CommandBuffer cmd, RTHandle source, RTHandle destination, RenderBufferLoadAction loadAction, RenderBufferStoreAction storeAction, Material material, int pass) { Vector2 viewportScale = source.useScaling ? new Vector2(source.rtHandleProperties.rtHandleScale.x, source.rtHandleProperties.rtHandleScale.y) : Vector2.one; @@ -610,16 +1058,32 @@ namespace UnityEngine.Rendering } /// - /// Blit a RTHandle to another RTHandle. - /// This will properly account for partial usage (in term of resolution) of the texture for the current viewport. - /// This overload allows user to override the scale and bias used when sampling the input RTHandle. + /// Adds in a a command to copy a camera related XR compatible texture identified by + /// its into a destination render target, using a user defined scale and bias. /// - /// Command Buffer used for rendering. - /// Source RTHandle. - /// Destination RTHandle. - /// Scale and bias used to sample the input RTHandle. - /// Mip level to blit. - /// Enable bilinear filtering. + /// + /// The scaleBias parameter controls the rectangle of pixels in the source texture to copy by manipulating + /// the source texture coordinates. The X and Y coordinates store the scaling factor to apply to these texture + /// coordinates, while the Z and W coordinates store the texture coordinate offsets. The operation will always + /// write to the full destination render target rectangle. + /// + /// Command Buffer used for recording the action. + /// RTHandle of the source texture to copy from. + /// RTHandle of the destination render target to copy to. + /// Scale and bias for sampling the source texture. + /// Mip level of the source texture to copy from. + /// Enable bilinear filtering when copying. + /// + /// + /// public static void BlitCameraTexture(CommandBuffer cmd, RTHandle source, RTHandle destination, Vector4 scaleBias, float mipLevel = 0.0f, bool bilinear = false) { // Will set the correct camera viewport as well. @@ -628,16 +1092,33 @@ namespace UnityEngine.Rendering } /// - /// Blit a RTHandle to another RTHandle. - /// This will properly account for partial usage (in term of resolution) of the texture for the current viewport. - /// This overload allows user to override the viewport of the destination RTHandle. + /// Adds in a a command to copy a camera related XR compatible texture identified by + /// its into a destination render target using a custom destination viewport. /// - /// Command Buffer used for rendering. - /// Source RTHandle. - /// Destination RTHandle. - /// Viewport of the destination RTHandle. - /// Mip level to blit. - /// Enable bilinear filtering. + /// + /// Camera related textures are created with the + /// method using or + /// to + /// automatically determine their resolution relative to the camera's render target resolution. Compared to the + /// various and methods, this function automatically handles the + /// scaleBias parameter. The copy operation will write to the destViewport viewport . + /// + /// Command Buffer used for recording the action. + /// RTHandle of the source texture to copy from. + /// RTHandle of the destination render target to copy to. + /// Rect of the destination viewport to write to. + /// Mip level of the source texture to copy from. + /// Enable bilinear filtering when copying. + /// + /// + /// public static void BlitCameraTexture(CommandBuffer cmd, RTHandle source, RTHandle destination, Rect destViewport, float mipLevel = 0.0f, bool bilinear = false) { Vector2 viewportScale = source.useScaling ? new Vector2(source.rtHandleProperties.rtHandleScale.x, source.rtHandleProperties.rtHandleScale.y) : Vector2.one; @@ -647,14 +1128,32 @@ namespace UnityEngine.Rendering } /// - /// Blit a texture using a quad in the current render target. + /// Adds in a a command to copy an XR compatible texture onto a portion of the current render target. /// - /// Command buffer used for rendering. - /// Source texture. - /// Scale and bias for the input texture. - /// Scale and bias for the output texture. - /// Mip level to blit. + /// + /// The scaleBiasTex parameter controls the rectangle of pixels in the source texture to copy by manipulating + /// the source texture coordinates. The X and Y coordinates store the scaling factor to apply to these texture + /// coordinates, while the Z and W coordinates store the texture coordinate offsets. + /// + /// Similarly, the scaleBiasRT parameter controls the rectangle of pixels in the render target to write to by manipulating + /// the destination quad coordinates. The X and Y coordinates store the scaling factor to apply to texture + /// coordinates, while the Z and W coordinates store the coordinate offsets. + /// + /// Command Buffer used for recording the action. + /// The source texture to copy from. + /// Scale and bias for sampling the source texture. + /// Scale and bias for the destination quad. + /// Mip level of the source texture to sample. /// Enable bilinear filtering. + /// + /// + /// public static void BlitQuad(CommandBuffer cmd, Texture source, Vector4 scaleBiasTex, Vector4 scaleBiasRT, int mipLevelTex, bool bilinear) { s_PropertyBlock.SetTexture(BlitShaderIDs._BlitTexture, source); @@ -666,16 +1165,53 @@ namespace UnityEngine.Rendering } /// - /// Blit a texture using a quad in the current render target. + /// Adds in a a command to copy an XR compatible texture onto a portion of the current render target + /// with support for padding on the destination rect. /// - /// Command buffer used for rendering. - /// Source texture. - /// Source texture size. - /// Scale and bias for sampling the input texture. - /// Scale and bias for the output texture. - /// Mip level to blit. + /// + /// ![Diagram of the padding parameters](../manual/images/Blitter_BlitQuadWithPadding.svg) + ///
Diagram detailing the use of the padding, textureSize, scaleBiasTex and scaleBiasRT. + /// + /// The source rect is copied to the destination rect along with extra padding pixels taken from the source texture + /// using the texture's . Both source rect pixels and padding pixels are copied inside the + /// destination rect. + /// + /// The scaleBiasTex parameter controls the rectangle of pixels in the source texture to copy by manipulating + /// the source texture coordinates. The X and Y coordinates store the scaling factor to apply to these texture + /// coordinates, while the Z and W coordinates store the texture coordinate offsets. + /// + /// Similarly, the scaleBiasRT parameter controls the rectangle of pixels in the render target to write to by manipulating + /// the destination quad coordinates. The X and Y coordinates store the scaling factor to apply to texture + /// coordinates, while the Z and W coordinates store the coordinate offsets. + ///
+ /// Command Buffer used for recording the action. + /// The source texture to copy from. + /// Source texture size in pixels. + /// Scale and bias for sampling the source texture. + /// Scale and bias for the destination quad. + /// Mip level of the source texture to sample. /// Enable bilinear filtering. - /// Padding in pixels. + /// Padding in pixels to add in the destination rect. + /// This is the total padding on an axis so to have N pixels added to the left, and N pixels to the right, paddingInPixels should be set to 2N. + /// + /// + /// public static void BlitQuadWithPadding(CommandBuffer cmd, Texture source, Vector2 textureSize, Vector4 scaleBiasTex, Vector4 scaleBiasRT, int mipLevelTex, bool bilinear, int paddingInPixels) { s_PropertyBlock.SetTexture(BlitShaderIDs._BlitTexture, source); @@ -691,16 +1227,50 @@ namespace UnityEngine.Rendering } /// - /// Blit a texture using a quad in the current render target, by performing an alpha blend with the existing content on the render target. + /// Adds in a a command to blit an XR compatible texture onto a portion of the current render target + /// with a multiply blend and support for padding on the destination rect. /// - /// Command buffer used for rendering. - /// Source texture. - /// Source texture size. - /// Scale and bias for sampling the input texture. - /// Scale and bias for the output texture. - /// Mip level to blit. + /// + /// The source rect is blended to the destination rect with a multiplicative blend, along with extra padding pixels taken from the source texture + /// using the texture's . Both source rect pixels and padding pixels are blitted inside the + /// destination rect. See for a diagram of how padding is applied. + /// + /// The scaleBiasTex parameter controls the rectangle of pixels in the source texture to copy by manipulating + /// the source texture coordinates. The X and Y coordinates store the scaling factor to apply to these texture + /// coordinates, while the Z and W coordinates store the texture coordinate offsets. + /// + /// Similarly, the scaleBiasRT parameter controls the rectangle of pixels in the render target to write to by manipulating + /// the destination quad coordinates. The X and Y coordinates store the scaling factor to apply to texture + /// coordinates, while the Z and W coordinates store the coordinate offsets. + /// + /// Command Buffer used for recording the action. + /// The source texture to copy from. + /// Source texture size in pixels. + /// Scale and bias for sampling the source texture. + /// Scale and bias for the destination quad. + /// Mip level of the source texture to sample. /// Enable bilinear filtering. - /// Padding in pixels. + /// Padding in pixels to add in the destination rect. + /// This is the total padding on an axis so to have N pixels added to the left, and N pixels to the right, paddingInPixels should be set to 2N. + /// + /// + /// public static void BlitQuadWithPaddingMultiply(CommandBuffer cmd, Texture source, Vector2 textureSize, Vector4 scaleBiasTex, Vector4 scaleBiasRT, int mipLevelTex, bool bilinear, int paddingInPixels) { s_PropertyBlock.SetTexture(BlitShaderIDs._BlitTexture, source); @@ -716,16 +1286,53 @@ namespace UnityEngine.Rendering } /// - /// Blit a texture (which is a Octahedral projection) using a quad in the current render target. + /// Adds in a a command to copy an XR compatible octahedral environment texture + /// onto a portion of the current render target with support for padding on the destination rect. /// - /// Command buffer used for rendering. - /// Source texture. - /// Source texture size. - /// Scale and bias for sampling the input texture. - /// Scale and bias for the output texture. - /// Mip level to blit. + /// + /// ![Diagram of the padding parameters](../manual/images/Blitter_BlitOctohedralWithPadding.svg) + ///
Diagram detailing the use of the padding, textureSize, scaleBiasTex and scaleBiasRT. + /// + /// The source rect is copied to the destination rect along with extra padding pixels taken from the source texture + /// but, compared to , using a specific octahedral mirror repeat mode. Both source rect pixels + /// and padding pixels are blitted inside the destination rect. + /// + /// The scaleBiasTex parameter controls the rectangle of pixels in the source texture to copy by manipulating + /// the source texture coordinates. The X and Y coordinates store the scaling factor to apply to these texture + /// coordinates, while the Z and W coordinates store the texture coordinate offsets. + /// + /// Similarly, the scaleBiasRT parameter controls the rectangle of pixels in the render target to write to by manipulating + /// the destination quad coordinates. The X and Y coordinates store the scaling factor to apply to texture + /// coordinates, while the Z and W coordinates store the coordinate offsets. + ///
+ /// Command Buffer used for recording the action. + /// The source texture to copy from. + /// Source texture size in pixels. + /// Scale and bias for sampling the source texture. + /// Scale and bias for the destination quad. + /// Mip level of the source texture to sample. /// Enable bilinear filtering. - /// Padding in pixels. + /// Padding in pixels to add in the destination rect. + /// This is the total padding on an axis so to have N pixels added to the left, and N pixels to the right, paddingInPixels should be set to 2N. + /// + /// + /// public static void BlitOctahedralWithPadding(CommandBuffer cmd, Texture source, Vector2 textureSize, Vector4 scaleBiasTex, Vector4 scaleBiasRT, int mipLevelTex, bool bilinear, int paddingInPixels) { s_PropertyBlock.SetTexture(BlitShaderIDs._BlitTexture, source); @@ -738,16 +1345,50 @@ namespace UnityEngine.Rendering } /// - /// Blit a texture (which is a Octahedral projection) using a quad in the current render target, by performing an alpha blend with the existing content on the render target. + /// Adds in a a command to copy an XR compatible octahedral environment texture + /// onto a portion of the current render target with a multiply blend and support for padding on the destination rect. /// - /// Command buffer used for rendering. - /// Source texture. - /// Source texture size. - /// Scale and bias for sampling the input texture. - /// Scale and bias for the output texture. - /// Mip level to blit. + /// + /// The source rect is blended onto the destination rect with a multiplicative blend, with extra padding pixels taken + /// from the source texture but, compared to , using a specific octahedral mirror + /// repeat mode. Both source rect pixels and padding pixels are blitted inside the destination rect. See + /// for a diagram of how padding is applied to the destination. + /// + /// The scaleBiasTex parameter controls the rectangle of pixels in the source texture to copy by manipulating + /// the source texture coordinates. The X and Y coordinates store the scaling factor to apply to these texture + /// coordinates, while the Z and W coordinates store the texture coordinate offsets. + /// + /// Similarly, the scaleBiasRT parameter controls the rectangle of pixels in the render target to write to by manipulating + /// the destination quad coordinates. The X and Y coordinates store the scaling factor to apply to texture + /// coordinates, while the Z and W coordinates store the coordinate offsets. + /// + /// Command Buffer used for recording the action. + /// The source texture to copy from. + /// Source texture size in pixels. + /// Scale and bias for sampling the source texture. + /// Scale and bias for the destination quad. + /// Mip level of the source texture to sample. /// Enable bilinear filtering. - /// Padding in pixels. + /// Padding in pixels to add in all directions to the source rect. + /// + /// + /// public static void BlitOctahedralWithPaddingMultiply(CommandBuffer cmd, Texture source, Vector2 textureSize, Vector4 scaleBiasTex, Vector4 scaleBiasRT, int mipLevelTex, bool bilinear, int paddingInPixels) { s_PropertyBlock.SetTexture(BlitShaderIDs._BlitTexture, source); @@ -760,12 +1401,33 @@ namespace UnityEngine.Rendering } /// - /// Blit a cube texture into 2d texture as octahedral quad. (projection) + /// Adds in a a command to copy a cube map texture onto a portion of the current render target + /// using octahedral mapping for the destination. /// - /// Command buffer used for rendering. - /// Source cube texture. - /// Mip level to sample. - /// Scale and bias for the output texture. + /// + /// The scaleBiasRT parameter controls the rectangle of pixels in the render target to write to by manipulating + /// the destination quad coordinates. The X and Y coordinates store the scaling factor to apply to texture + /// coordinates, while the Z and W coordinates store the coordinate offsets. + /// + /// Command Buffer used for recording the action. + /// The source cube texture to copy from. + /// Scale and bias for the destination quad. + /// Mip level of the source texture to sample. + /// + /// | | X | | + /// // | | + + - +---+ - + + /// // | | / | | | | + /// // +-------+ + - + - + - + + /// Vector4 center3by3 = new Vector4(1.0f/3.0f, 1.0f/3.0f, 1.0f/3.0f, 1.0f/3.0f); + /// Blitter.BlitCubeToOctahedral2DQuad(cmd, source, center3by3, 2); + /// ]]> + /// public static void BlitCubeToOctahedral2DQuad(CommandBuffer cmd, Texture source, Vector4 scaleBiasRT, int mipLevelTex) { s_PropertyBlock.SetTexture(BlitShaderIDs._BlitCubeTexture, source); @@ -776,16 +1438,49 @@ namespace UnityEngine.Rendering } /// - /// Blit a cube texture into 2d texture as octahedral quad with padding. (projection) + /// Adds in a a command to copy a cube map texture onto a portion of the current render target + /// using octahedral mapping for the destination + /// with extra padding on the destination rect. /// - /// Command buffer used for rendering. - /// Source cube texture. - /// Source texture size. - /// Mip level to sample. - /// Scale and bias for the output texture. + /// + /// The source cube map pixels are copied onto the destination rect with extra padding pixels taken from the source texture + /// but using a specific octahedral mirror repeat mode. Both source rect pixels and padding pixels are blitted inside the destination rect. + /// See for a diagram of how padding is applied to the destination. + /// + /// The scaleBiasRT parameter controls the rectangle of pixels in the render target to write to by manipulating + /// the destination quad coordinates. The X and Y coordinates store the scaling factor to apply to texture + /// coordinates, while the Z and W coordinates store the coordinate offsets. + /// + /// Command Buffer used for recording the action. + /// The source cube texture to copy from. + /// Source texture size in pixels. + /// Scale and bias for the destination quad. + /// Mip level of the source texture to sample. /// Enable bilinear filtering. - /// Padding in pixels. + /// Padding in pixels to add in all directions to the source rect. /// The purpose of this parameter is to blit HDR-encoded values to a non HDR texture. Use values from API that produce HDR-encoded values, for example . If this parameter is null, HDR decoding is disabled. + /// + /// | | X | | + /// // | | + + - +---+ - + + /// // | | / | | | | + /// // +-------+ + - + - + - + + /// // Desired padding on the destination rect + /// int paddingInPixelsOneDirection = 16; + /// // Multiply by two for the total padding along an axis. + /// int paddingInPixels = 2 * paddingInPixelsOneDirection; + /// Vector4 center3by3 = new Vector4(1.0f/3.0f, 1.0f/3.0f, 1.0f/3.0f, 1.0f/3.0f); + /// Vector2 subTextureSize = new Vector2(sourceWidth, sourceHeight); + /// // HDR to non-HDR decoding is not necessary here so drop the + /// // last parameter. + /// Blitter.BlitCubeToOctahedral2DQuadWithPadding(cmd, source, subTextureSize, center3by3, 2, paddingInPixels); + /// ]]> + /// public static void BlitCubeToOctahedral2DQuadWithPadding(CommandBuffer cmd, Texture source, Vector2 textureSize, Vector4 scaleBiasRT, int mipLevelTex, bool bilinear, int paddingInPixels, Vector4? decodeInstructions = null) { var material = GetBlitMaterial(source.dimension); @@ -808,16 +1503,40 @@ namespace UnityEngine.Rendering } /// - /// Blit a cube texture into 2d texture as octahedral quad. (projection) - /// Conversion between single and multi channel formats. - /// RGB(A) to YYYY (luminance). - /// R to RRRR. - /// A to AAAA. + /// Adds in a a command to perform a single channel copy of a cube map texture onto a portion of the current render target + /// using octahedral mapping for the destination. /// - /// Command buffer used for rendering. - /// Source texture. - /// Scale and bias for the output texture. - /// Mip level to blit. + /// + /// The conversion to a single channel output depends on the source texture's format: + /// + /// Texture FormatOutput conversion + /// RGB(A)the RGB luminance is written to the destination in all channels. + /// Redthe red value is written to the destination in all channels. + /// Alphathe alpha value is written to the destination in all channels. + /// + /// The scaleBiasRT parameter controls the rectangle of pixels in the render target to write to by manipulating + /// the destination quad coordinates. The X and Y coordinates store the scaling factor to apply to texture + /// coordinates, while the Z and W coordinates store the coordinate offsets. + /// + /// Command Buffer used for recording the action. + /// The source cube texture to copy from. + /// Scale and bias for the destination quad. + /// Mip level of the source texture to sample. + /// + /// | | X | | + /// // | | + + - +---+ - + + /// // | | / | | | | + /// // +-------+ + - + - + - + + /// Vector4 center3by3 = new Vector4(1.0f/3.0f, 1.0f/3.0f, 1.0f/3.0f, 1.0f/3.0f); + /// Blitter.BlitCubeToOctahedral2DQuadSingleChannel(cmd, source, center3by3, 2); + /// ]]> + /// public static void BlitCubeToOctahedral2DQuadSingleChannel(CommandBuffer cmd, Texture source, Vector4 scaleBiasRT, int mipLevelTex) { int pass = 15; @@ -838,17 +1557,40 @@ namespace UnityEngine.Rendering } /// - /// Bilinear Blit a texture using a quad in the current render target. - /// Conversion between single and multi channel formats. - /// RGB(A) to YYYY (luminance). - /// R to RRRR. - /// A to AAAA. + /// Adds in a a command to perform a single channel copy off an XR compatible texture onto a + /// portion of the current render target. /// - /// Command buffer used for rendering. - /// Source texture. - /// Scale and bias for the input texture. - /// Scale and bias for the output texture. - /// Mip level to blit. + /// + /// The conversion to a single channel output depends on the source texture's format: + /// + /// Texture FormatOutput conversion + /// RGB(A)the RGB luminance is written to the destination in all channels. + /// Redthe red value is written to the destination in all channels. + /// Alphathe alpha value is written to the destination in all channels. + /// + /// + /// The scaleBiasTex parameter controls the rectangle of pixels in the source texture to copy by manipulating + /// the source texture coordinates. The X and Y coordinates store the scaling factor to apply to these texture + /// coordinates, while the Z and W coordinates store the texture coordinate offsets. + /// + /// Similarly, the scaleBiasRT parameter controls the rectangle of pixels in the render target to write to by manipulating + /// the destination quad coordinates. The X and Y coordinates store the scaling factor to apply to texture + /// coordinates, while the Z and W coordinates store the coordinate offsets. + /// + /// Command Buffer used for recording the action. + /// The source texture to copy from. + /// Scale and bias for sampling the source texture. + /// Scale and bias for the destination quad. + /// Mip level of the source texture to sample. + /// + /// + /// public static void BlitQuadSingleChannel(CommandBuffer cmd, Texture source, Vector4 scaleBiasTex, Vector4 scaleBiasRT, int mipLevelTex) { int pass = 18; diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Utilities/CoreUtils.cs b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/CoreUtils.cs index 807a5290..9c82d161 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Utilities/CoreUtils.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/CoreUtils.cs @@ -1,8 +1,10 @@ using System; +using System.Collections; using System.IO; using System.Linq; using System.Collections.Generic; using UnityEngine.Experimental.Rendering; +using System.Runtime.CompilerServices; namespace UnityEngine.Rendering { @@ -13,6 +15,25 @@ namespace UnityEngine.Rendering ///
public static class CoreUtils { +#if UNITY_EDITOR + static CoreUtils() + { + void OnBeforeAssemblyReload() + { + UnityObject.DestroyImmediate(m_BlackCubeTexture); + UnityObject.DestroyImmediate(m_BlackVolumeTexture); + UnityObject.DestroyImmediate(m_WhiteCubeTexture); + UnityObject.DestroyImmediate(m_WhiteVolumeTexture); + UnityObject.DestroyImmediate(m_MagentaCubeTexture); + UnityObject.DestroyImmediate(m_MagentaCubeTextureArray); + UnityObject.DestroyImmediate(m_EmptyUAV); + m_EmptyBuffer?.Release(); + UnityEditor.AssemblyReloadEvents.beforeAssemblyReload -= OnBeforeAssemblyReload; + } + UnityEditor.AssemblyReloadEvents.beforeAssemblyReload += OnBeforeAssemblyReload; + } +#endif + /// /// List of look at matrices for cubemap faces. /// Ref: https://msdn.microsoft.com/en-us/library/windows/desktop/bb204881(v=vs.85).aspx @@ -773,6 +794,37 @@ namespace UnityEngine.Rendering SetViewportAndClear(cmd, colorBuffer, clearFlag, clearColor); } + /// + /// Set the current shading rate fragment size + /// + /// CommandBuffer used for rendering commands. + /// Shading rate fragment size to set + public static void SetShadingRateFragmentSize(CommandBuffer cmd, ShadingRateFragmentSize baseShadingRateFragmentSize) + { + cmd.SetShadingRateFragmentSize(baseShadingRateFragmentSize); + } + + /// + /// Set the current shading rate combiner + /// + /// CommandBuffer used for rendering commands. + /// Combiner stage to set + /// Combiner to set + public static void SetShadingRateCombiner(CommandBuffer cmd, ShadingRateCombinerStage stage, ShadingRateCombiner combiner) + { + cmd.SetShadingRateCombiner(stage, combiner); + } + + /// + /// Set the current shading rate image + /// + /// CommandBuffer used for rendering commands. + /// Shading rate image render target identifier to set + public static void SetShadingRateImage(CommandBuffer cmd, in RenderTargetIdentifier shadingRateImage) + { + cmd.SetShadingRateImage(shadingRateImage); + } + /// /// Set the current multiple render texture. /// @@ -1784,5 +1836,115 @@ namespace UnityEngine.Rendering return outCorners; } + + /// + /// Return the GraphicsFormat of DepthStencil RenderTarget preferred for the current platform. + /// + /// The GraphicsFormat of DepthStencil RenderTarget preferred for the current platform. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphicsFormat GetDefaultDepthStencilFormat() + { +#if UNITY_SWITCH || UNITY_EMBEDDED_LINUX || UNITY_QNX || UNITY_ANDROID + return GraphicsFormat.D24_UNorm_S8_UInt; +#else + return GraphicsFormat.D32_SFloat_S8_UInt; +#endif + } + + /// + /// Return the number of DepthStencil RenderTarget depth bits preferred for the current platform. + /// + /// The number of DepthStencil RenderTarget depth bits preferred for the current platform. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static DepthBits GetDefaultDepthBufferBits() + { +#if UNITY_SWITCH || UNITY_EMBEDDED_LINUX || UNITY_QNX || UNITY_ANDROID + return DepthBits.Depth24; +#else + return DepthBits.Depth32; +#endif + } + +#if UNITY_EDITOR + /// + /// Populates null fields or collection elements in a target object from a source object of the same type. + /// + /// + /// The type of the objects. This must be a reference type (`class`). + /// + /// + /// The source object from which to copy field values or collection elements. This cannot be null. + /// + /// + /// The target object to populate with values from the source object. This cannot be null. + /// + /// + /// This method copies non-null field values or collection elements from the source object to the target object. + /// Both objects must be of the same type, and derived or base types are not allowed. Fields are updated only if they + /// are null in the target. If a field is a collection implementing `IList`, the method attempts to copy elements that + /// are null in the target collection. + /// + /// **Type restrictions**: + /// - `T` must be a reference type. + /// - `source` and `target` must be of the exact same type, not derived or base types. + /// - Collections must implement `IList` and have the same length in both source and target for element-by-element copying. + /// + public static void PopulateNullFieldsFrom(T source, T target) + where T : class + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + + if (target == null) + throw new ArgumentNullException(nameof(target)); + + if (source.GetType() != typeof(T) || target.GetType() != typeof(T)) + { + throw new ArgumentException("Source and target must be of the exact same type. Derived or base types are not allowed."); + } + + var type = typeof(T); + var fields = type.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + foreach (System.Reflection.FieldInfo field in fields) + { + var sourceValue = field.GetValue(source); + var targetValue = field.GetValue(target); + + // Check if the field is a collection (implements ICollection) + if (typeof(IList).IsAssignableFrom(field.FieldType)) + { + // Handle collection population + PopulateIListFields( ref sourceValue, ref targetValue); + field.SetValue(target, targetValue); + } + else + { + // Handle individual field population + if (targetValue == null) + field.SetValue(target, sourceValue); // Copy if target is null + } + } + // Generic method to populate arrays + static void PopulateIListFields(ref object source, ref object target) + { + if (source is not IList sourceCollection) + return; + + if (target is not IList targetCollection) + { + target = sourceCollection; + return; + } + + if (sourceCollection.Count != targetCollection.Count) + return; + + for (int i = 0; i < targetCollection.Count; i++) + { + sourceCollection[i] ??= targetCollection[i]; + } + } + } +#endif } } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Utilities/CullContextData.cs b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/CullContextData.cs new file mode 100644 index 00000000..dd6ce86c --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/CullContextData.cs @@ -0,0 +1,59 @@ +using System; +using Unity.Collections; + +namespace UnityEngine.Rendering.Universal +{ + /// + /// Class that holds data related to culling. + /// + public class CullContextData : ContextItem + { + internal ScriptableRenderContext? m_RenderContext; + + /// + public override void Reset() + { + m_RenderContext = null; + } + + /// + /// Assigns the render context once at initialization time. + /// + /// The render context to assign. + public void SetRenderContext(in ScriptableRenderContext renderContext) + { + m_RenderContext = renderContext; + } + + /// + /// Performs scene culling based on the provided parameters. + /// + /// The parameters used for the culling. + /// The culling results. + public CullingResults Cull(ref ScriptableCullingParameters parameters) + { + if (!m_RenderContext.HasValue) + { + throw new InvalidOperationException("The ScriptableRenderContext member is not set."); + } + + return m_RenderContext.Value.Cull(ref parameters); + } + + /// + /// Performs shadow casters culling based on the provided parameters. + /// + /// The scene culling results. + /// The shadow casters culling informations. + /// The parameters used for the shadow culling. + public void CullShadowCasters(CullingResults cullingResults, ShadowCastersCullingInfos shadowCastersCullingInfos) + { + if (!m_RenderContext.HasValue) + { + throw new InvalidOperationException("The ScriptableRenderContext member is not set."); + } + + m_RenderContext.Value.CullShadowCasters(cullingResults, shadowCastersCullingInfos); + } + } +} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Utilities/CullContextData.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/CullContextData.cs.meta new file mode 100644 index 00000000..98100464 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/CullContextData.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: fba8806c6dc73604d8243aebe488e60d \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Utilities/HashFNV1A32.cs b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/HashFNV1A32.cs index 2ad88bb4..ed76b8f5 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Utilities/HashFNV1A32.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/HashFNV1A32.cs @@ -1,5 +1,7 @@ using System; +using System.Collections.Generic; using System.Runtime.CompilerServices; +using Unity.Collections; namespace UnityEngine.Rendering { @@ -100,26 +102,46 @@ namespace UnityEngine.Rendering } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(Delegate del) + public int value => (int)m_Hash; + + public override int GetHashCode() { - unchecked - { - m_Hash = (m_Hash ^ (uint)GetFuncHashCode(del)) * k_Prime; - } + return value; } + } + + static class DelegateHashCodeUtils + { + //Cache to prevent CompilerGeneratedAttribute extraction for known delegate + static readonly Lazy> s_MethodHashCodeToSkipTargetHashMap = new(() => new Dictionary(64)); [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static int GetFuncHashCode(Delegate del) + public static int GetFuncHashCode(Delegate del) { - return del.Method.GetHashCode() ^ RuntimeHelpers.GetHashCode(del.Target); - } + //Get MethodInfo hash code as the main one to be used + var methodHashCode = RuntimeHelpers.GetHashCode(del.Method); + + //Check if we are dealing with lambda or static delegates and skip target if we are. + //Static methods have a null Target. + //Lambdas have a CompilerGeneratedAttribute as they are generated by a compiler. + //If Lambda have any captured variable Target hashcode will be different each time we re-create lambda. + if (!s_MethodHashCodeToSkipTargetHashMap.Value.TryGetValue(methodHashCode, out var skipTarget)) + { + skipTarget = del.Target == null || ( + del.Method.DeclaringType?.IsNestedPrivate == true && + Attribute.IsDefined(del.Method.DeclaringType, typeof(CompilerGeneratedAttribute), false) + ); - public int value => (int)m_Hash; + s_MethodHashCodeToSkipTargetHashMap.Value[methodHashCode] = skipTarget; + } - public override int GetHashCode() - { - return value; + //Combine method info hashcode and target hashcode if needed + return skipTarget ? methodHashCode : methodHashCode ^ RuntimeHelpers.GetHashCode(del.Target); } + + //used for testing + internal static int GetTotalCacheCount() => s_MethodHashCodeToSkipTargetHashMap.Value.Count; + + internal static void ClearCache() => s_MethodHashCodeToSkipTargetHashMap.Value.Clear(); } -} +} \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Utilities/ResourceReloader.cs b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/ResourceReloader.cs index b9cb29b4..51265864 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Utilities/ResourceReloader.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Utilities/ResourceReloader.cs @@ -15,12 +15,14 @@ namespace UnityEngine.Rendering /// The reload call should only be done in Editor context though but it /// could be called from runtime entities. /// + /// + /// public static class ResourceReloader { /// /// Looks for resources in the given object and reload the ones - /// that are missing or broken. - /// This version will still return null value without throwing error if the issue is due to + /// that are missing or broken, using the to find the paths. + /// This version returns a null value without throwing an error if the issue is /// AssetDatabase being not ready. But in this case the assetDatabaseNotReady result will be true. /// /// The object containing reload-able resources @@ -47,7 +49,8 @@ namespace UnityEngine.Rendering /// /// Looks for resources in the given object and reload the ones - /// that are missing or broken. + /// that are missing or broken, using the to find the paths. + /// See for an example. /// /// The object containing reload-able resources /// The base path for the package diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Volume/IVolume.cs b/Packages/com.unity.render-pipelines.core/Runtime/Volume/IVolume.cs index 1a696cd3..37a9949f 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Volume/IVolume.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Volume/IVolume.cs @@ -3,18 +3,40 @@ using System.Collections.Generic; namespace UnityEngine.Rendering { /// - /// An interface for Volumes + /// Defines the basic structure for a Volume, providing the necessary properties for determining + /// whether the volume should be applied globally to the scene or to specific colliders. /// + /// + /// This interface serves as a contract for systems that implement volume logic, enabling + /// reusable code for volume-based behaviors such as rendering effects, post-processing, or scene-specific logic. + /// The interface is commonly implemented by components that define volumes in a scene, + /// allowing for flexibility in determining how the volume interacts with the scene. A volume can either be global + /// (affecting the entire scene) or local (restricted to specific colliders). + /// This interface is also helpful for drawing gizmos in the scene view, as it allows for visual representation + /// of volumes in the editor based on their settings. + /// public interface IVolume { /// - /// Specifies whether to apply the Volume to the entire Scene or not. + /// Gets or sets a value indicating whether the volume applies to the entire scene. + /// If true, the volume is global and affects all objects within the scene. + /// If false, the volume is local and only affects the objects within the specified colliders. /// + /// + /// When set to true, the volume's effects will be applied universally across the scene, + /// without considering individual colliders. When false, the volume will interact only with + /// the objects inside the colliders defined in . + /// bool isGlobal { get; set; } /// - /// The colliders of the volume if is false + /// A list of colliders that define the area of influence of the volume when is set to false. /// + /// + /// This property holds the colliders that restrict the volume's effects to specific areas of the scene. + /// It is only relevant when is false, and defines the boundaries of where the volume is applied. + /// List colliders { get; } } + } diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeComponent.cs b/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeComponent.cs index a1538fbd..17fb6b19 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeComponent.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeComponent.cs @@ -7,10 +7,19 @@ using System.Reflection; namespace UnityEngine.Rendering { /// - /// This attribute allows you to add commands to the Add Override popup menu - /// on Volumes. - /// To filter VolumeComponentMenu based on current Render Pipeline, add SupportedOnRenderPipeline attribute to the class alongside with this attribute. - /// + /// This attribute is used to set up a path in the Add Override popup menu in Unity's Volume system. + /// It allows you to organize and categorize your Volume components into submenus for easier access and management within the editor. + ///
+ /// Specify the name of the menu entry, and use slashes ("/") to create hierarchical submenus in the popup. This is useful for organizing large or complex sets of Volume components. + /// To further filter the menu entries based on the active Render Pipeline, you can combine this attribute with the attribute. + /// This enables conditional display of Volume components depending on the Render Pipeline being used in the project. + /// + /// + /// + /// [VolumeComponentMenu("MyVolumeCategory/LightingEffects")] + /// public class CustomLightingVolume : VolumeComponent { ... } + /// + /// [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] public class VolumeComponentMenu : Attribute { @@ -33,14 +42,14 @@ namespace UnityEngine.Rendering } /// - /// This attribute allows you to add commands to the Add Override popup menu - /// on Volumes and specify for which render pipelines will be supported + /// This attribute allows you to add commands to the Add Override popup menu on Volumes, + /// while also specifying the render pipeline(s) for which the command will be supported. /// - [Obsolete(@"VolumeComponentMenuForRenderPipelineAttribute is deprecated. Use VolumeComponentMenu with SupportedOnCurrentPipeline instead. #from(2023.1)", false)] + [Obsolete(@"VolumeComponentMenuForRenderPipelineAttribute is deprecated. Use VolumeComponentMenu with SupportedOnRenderPipeline instead. #from(2023.1)", false)] public class VolumeComponentMenuForRenderPipeline : VolumeComponentMenu { /// - /// The list of pipeline types that the target class supports + /// The list of pipeline types that the target class supports. /// public Type[] pipelineTypes { get; } @@ -49,14 +58,15 @@ namespace UnityEngine.Rendering /// /// The name of the entry in the override list. You can use slashes to /// create sub-menus. - /// The list of pipeline types that the target class supports + /// The list of pipeline types that the target class supports. + /// Thrown when the pipelineTypes is null or the types do not inherit from . public VolumeComponentMenuForRenderPipeline(string menu, params Type[] pipelineTypes) : base(menu) { if (pipelineTypes == null) - throw new Exception("Specify a list of supported pipeline"); + throw new Exception("Specify a list of supported pipeline."); - // Make sure that we only allow the class types that inherit from the render pipeline + // Ensure that we only allow class types that inherit from RenderPipeline foreach (var t in pipelineTypes) { if (!typeof(RenderPipeline).IsAssignableFrom(t)) @@ -69,20 +79,40 @@ namespace UnityEngine.Rendering } + /// - /// An attribute to hide the volume component to be added through `Add Override` button on the volume component list + /// This attribute prevents the component from being included in the list of available + /// overrides in the Volume Inspector via the Add Override button. /// [AttributeUsage(AttributeTargets.Class)] - [Obsolete("VolumeComponentDeprecated has been deprecated (UnityUpgradable) -> [UnityEngine] UnityEngine.HideInInspector", false)] + [Obsolete("VolumeComponentDeprecated has been deprecated (UnityUpgradable) -> [UnityEngine] UnityEngine.HideInInspector #from(2023.1)", false)] public sealed class VolumeComponentDeprecated : Attribute { } + /// - /// The base class for all the components that can be part of a . - /// The Volume framework automatically handles and interpolates any members found in this class. + /// The base class for all components that can be part of a . + /// This class serves as the foundation for creating and managing volume components in Unity's + /// volume system, enabling the handling of various types in a unified way. /// + /// The class is automatically integrated into the volume framework, + /// which handles interpolation and blending of members at runtime. + /// It ensures that parameter values can be adjusted and smoothly transitioned based on different factors, + /// such as render pipeline settings, quality settings, or user-defined parameters. + /// + /// Due to the need to store multiple types in a single collection, + /// this base class provides a mechanism to handle them generically. It allows for easy management and + /// manipulation of parameters of varying types, ensuring consistency across different volume components. + /// + /// - Stores and manages a collection of objects.. + /// - Integrates seamlessly into for enhanced control over rendering and post-processing effects. + /// /// + /// + /// You can create a custom volume component by inheriting from this base class and defining your own. + /// fields. The will handle the interpolation and blending for you. + /// /// /// using UnityEngine.Rendering; /// @@ -92,6 +122,12 @@ namespace UnityEngine.Rendering /// public ClampedFloatParameter intensity = new ClampedFloatParameter(0f, 0f, 1f); /// } /// + /// + /// + /// In the example above, the custom component `ExampleComponent` extends `VolumeComponent` and defines a parameter + /// (`intensity`) that can be manipulated within the volume framework. The `ClampedFloatParameter` is a type of + /// that ensures the value remains within a specified range. + /// /// [Serializable] public partial class VolumeComponent : ScriptableObject diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeManager.cs b/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeManager.cs index 0402bb49..421eadd8 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeManager.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeManager.cs @@ -15,9 +15,30 @@ using UnityEditor.Rendering; namespace UnityEngine.Rendering { /// - /// A global manager that tracks all the Volumes in the currently loaded Scenes and does all the - /// interpolation work. + /// The is a global manager responsible for tracking and managing all Volume settings across the currently loaded Scenes. + /// It handles interpolation and blending of Volume settings at runtime, ensuring smooth transitions between different states of the volumes. + /// This includes managing post-processing effects, lighting settings, and other environmental effects based on volume profiles. /// + /// + /// + /// The is initialized with two VolumeProfiles: + /// 1. The default VolumeProfile defined in the Graphics Settings. + /// 2. The default VolumeProfile defined in the Quality Settings. + /// + /// These profiles represent the baseline state of all volume parameters, and the VolumeManager interpolates values between them to create a final blended VolumeStack for each camera. + /// Every frame, the VolumeManager updates the parameters of local and global VolumeComponents attached to game objects and ensures that the correct interpolation is applied across different volumes. + /// The VolumeManager acts as the central "point of truth" for all VolumeComponent parameters in a scene. + /// It provides default states for volume settings and dynamically interpolates between different VolumeProfiles to manage changes during runtime. This system is used to handle dynamic environmental and post-processing effects in Unity, ensuring smooth transitions across scene changes and camera views. + /// + /// The VolumeManager integrates seamlessly with Unity's Scriptable Render Pipelines, applying the appropriate settings for rendering effects such as lighting, bloom, exposure, etc., in real time. + /// + /// + /// + /// + /// + /// + /// + /// public sealed partial class VolumeManager { static readonly ProfilerMarker k_ProfilerMarkerUpdate = new ("VolumeManager.Update"); diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeParameter.cs b/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeParameter.cs index b8fc6b90..723f21e4 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeParameter.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeParameter.cs @@ -8,14 +8,25 @@ using System.Runtime.CompilerServices; namespace UnityEngine.Rendering { - // We need this base class to be able to store a list of VolumeParameter in collections as we - // can't store VolumeParameter with variable T types in the same collection. As a result some - // of the following is a bit hacky... - /// - /// The base class for all parameters types stored in a . + /// The base class for all parameter types stored in a . + /// + /// This class serves as a base for different parameter types that are used within the Volume system, such as those controlling post-processing effects, lighting settings, and other volume-related parameters. + /// + /// The class implements the interface, enabling cloning of the parameter's values for later use or manipulation. /// + /// + /// The class is an abstract base class, and cannot be instantiated directly. + /// Derived classes like represent specific parameter types, such as float, vector, or color values, and can be used to configure individual settings in a Volume component. + /// + /// It is important to note that this class is designed to allow various parameter types to be stored and managed collectively. + /// This mechanism enables developers to create complex and configurable Volume components that can be customized with different parameter types (e.g., sliders for float values, color pickers for color values, etc.). + /// + /// + /// /// + /// + /// public abstract class VolumeParameter : ICloneable { #if UNITY_EDITOR || DEVELOPMENT_BUILD diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeStack.cs b/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeStack.cs index fc9e3dfd..1f5afc23 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeStack.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Volume/VolumeStack.cs @@ -4,11 +4,32 @@ using System.Collections.Generic; namespace UnityEngine.Rendering { /// - /// Holds the state of a Volume blending update. A global stack is - /// available by default in but you can also create your own using - /// if you need to update the manager with specific - /// settings and store the results for later use. + /// Represents the state of a Volume blending update within the Volume system. /// + /// + /// + /// This class is responsible for storing the blending of Volume components across multiple scenes and cameras, + /// By default, a global volume stack is provided by the to handle the blending of Volume data across your project. + /// This global stack simplifies managing and blending volume data at a project-wide level. However, if you require more granular control over + /// the blending process or want to store and manage the blending results separately (e.g., per camera or scene), you can create custom volume + /// stacks using . + /// The blending of volumes is based on a combination of several factors: + /// - **Volume Weight:** Determines how strongly a particular volume influences the final result. + /// - **Volume Parameters:** These can be visual settings such as post-processing effects, lighting adjustments, or other specialized effects defined + /// in the Volume components. + /// - **Camera Volume Stack:** Volume blending can vary per camera, allowing different volumes to be blended for different camera views or scenes. + /// + /// While the default global volume stack works for most use cases, custom stacks provide greater flexibility and control, allowing developers + /// to manage and store volume blending results at a per-scene or per-camera level. This can be particularly useful in complex rendering setups + /// or when you want to apply different volume blends for different gameplay contexts or visual effects. + /// + /// Keep in mind that frequent updates to the volume blending process (e.g., every frame) may have an impact on performance, especially when + /// dealing with large numbers of volumes or complex blending operations. + /// + /// + /// + /// + /// public sealed class VolumeStack : IDisposable { // Holds the state of _all_ component types you can possibly add on volumes diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Vrs.meta b/Packages/com.unity.render-pipelines.core/Runtime/Vrs.meta new file mode 100644 index 00000000..3bef0982 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Vrs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cc1099d95a4ee3849a01da5826056b1f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders.meta b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders.meta new file mode 100644 index 00000000..eca032eb --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 77658d0b0e15bb342a01e17ef1b2172a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsImage.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsImage.hlsl new file mode 100644 index 00000000..e89a0c2e --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsImage.hlsl @@ -0,0 +1,21 @@ +#ifndef VRS_IMAGE_INCLUDED +#define VRS_IMAGE_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" + +RW_TEXTURE2D(uint, _ShadingRateImage); + +uniform float4 _VrsScaleBias; + +void ImageStore(uint shadingRateNativeValue, uint2 gid) +{ +#if !defined(APPLY_Y_FLIP) + // compute shader introduce a natural y-flip + // hence the reverse test + gid.y = _VrsScaleBias.w - 1 - gid.y; +#endif + + _ShadingRateImage[gid] = shadingRateNativeValue; +} + +#endif // VRS_IMAGE_INCLUDED diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsImage.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsImage.hlsl.meta new file mode 100644 index 00000000..e3d8c0e5 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsImage.hlsl.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3cc7957ff84646bbbb849b88919e2109 +timeCreated: 1710958387 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsMainTex.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsMainTex.hlsl new file mode 100644 index 00000000..545ccebb --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsMainTex.hlsl @@ -0,0 +1,23 @@ +#ifndef VRS_MAINTEX_INCLUDED +#define VRS_MAINTEX_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureXR.hlsl" +#include "Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsShadingRates.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/GlobalSamplers.hlsl" + +TEXTURE2D_X(_VrsMainTex); + +StructuredBuffer _VrsMainTexLut; + +float4 LoadVrsMainTex(uint2 tid) +{ + return LOAD_TEXTURE2D_X(_VrsMainTex, tid); +} + +float4 SampleVrsMainTexFromCoords(float2 coords) +{ + return SAMPLE_TEXTURE2D_X_LOD(_VrsMainTex, sampler_PointClamp, coords, 0); +} + +#endif // VRS_MAINTEX_INCLUDED diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsMainTex.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsMainTex.hlsl.meta new file mode 100644 index 00000000..2cda9558 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsMainTex.hlsl.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 08b9525dab8d497cb640174e593275d1 +timeCreated: 1710958899 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsShadingRates.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsShadingRates.hlsl new file mode 100644 index 00000000..a4dade3e --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsShadingRates.hlsl @@ -0,0 +1,45 @@ +#ifndef VRS_SHADING_RATES_INCLUDED +#define VRS_SHADING_RATES_INCLUDED + +// Must be kept in sync with ShadingRateFragmentSize +#define SHADING_RATE_FRAGMENT_SIZE_1X1 0 // native value = 0b0000 -> 0 +#define SHADING_RATE_FRAGMENT_SIZE_1X2 1 // native value = 0b0001 -> 1 +#define SHADING_RATE_FRAGMENT_SIZE_2X1 2 // native value = 0b0100 -> 4 +#define SHADING_RATE_FRAGMENT_SIZE_2X2 3 // native value = 0b0101 -> 5 +#define SHADING_RATE_FRAGMENT_SIZE_1x4 4 // native value = 0b0010 -> 2 +#define SHADING_RATE_FRAGMENT_SIZE_4x1 5 // native value = 0b1000 -> 8 +#define SHADING_RATE_FRAGMENT_SIZE_2x4 6 // native value = 0b0110 -> 6 +#define SHADING_RATE_FRAGMENT_SIZE_4x2 7 // native value = 0b1001 -> 9 +#define SHADING_RATE_FRAGMENT_SIZE_4x4 8 // native value = 0b1010 -> 10 +#define SHADING_RATE_FRAGMENT_SIZE_COUNT 9 + +StructuredBuffer _ShadingRateNativeValues; + +/// +/// Unpack a shading rate native value into its horizontal and vertical components. +/// +/// Shading rate native value to unpack. +/// Unpacked value where x component is the horizontal shading rate and y is the vertical shading rate. +uint2 UnpackShadingRate(uint shadingRateNativeValue) +{ + return uint2((shadingRateNativeValue >> 2) & 0x03, shadingRateNativeValue & 0x03); +} + +/// +/// Pack an unpacked shading rates into its native value. +/// +/// Unpacked shading rate. +/// Shading rate native value. +uint PackShadingRate(uint2 unpackedShadingRate) +{ + // If using 4x4 rate, be careful to check for invalid rates + // if (shadingRate.x == 2 && shadingRate.y == 0) + // shadingRate.y = 1; + // + // if (shadingRate.x == 0 && shadingRate.y == 2) + // shadingRate.x = 1; + + return (unpackedShadingRate.x << 2) | unpackedShadingRate.y; +} + +#endif // VRS_SHADING_RATES_INCLUDED diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsShadingRates.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsShadingRates.hlsl.meta new file mode 100644 index 00000000..303e9a6b --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsShadingRates.hlsl.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: dbb73cb4c1954036a32ce1ade17ac0fd +timeCreated: 1710965275 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsTexture.compute b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsTexture.compute new file mode 100644 index 00000000..94e5f338 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsTexture.compute @@ -0,0 +1,69 @@ +// #pragma enable_d3d11_debug_symbols + +#pragma exclude_renderers glcore gles3 + +#pragma multi_compile VRS_TILE_SIZE_8 VRS_TILE_SIZE_16 VRS_TILE_SIZE_32 +#pragma multi_compile _ DISABLE_TEXTURE2D_X_ARRAY +#pragma multi_compile _ APPLY_Y_FLIP + +#pragma kernel TextureCopy +#pragma kernel TextureReduce + + +#include "Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsTileSize.hlsl" +#include "Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsImage.hlsl" +#include "Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsMainTex.hlsl" +#include "Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsShadingRates.hlsl" + + +uint GetShadingRateNativeValueFromColor(float3 color) +{ + for (uint i = 0; i < SHADING_RATE_FRAGMENT_SIZE_COUNT; ++i) + { + float3 delta = abs(color - _VrsMainTexLut[i].rgb); + if (all(delta < 0.01f)) + return _ShadingRateNativeValues[i]; + } + + return _ShadingRateNativeValues[SHADING_RATE_FRAGMENT_SIZE_1X1]; +} + +[numthreads(1, 1, 1)] +void TextureCopy(uint2 tid : SV_DispatchThreadID) +{ + float3 color = LoadVrsMainTex(tid).rgb; + uint shadingRateNativeValue = GetShadingRateNativeValueFromColor(color); + ImageStore(shadingRateNativeValue, tid); +} + + +groupshared uint2 ldsShadingRate; + +[numthreads(VRS_TILE_SIZE, VRS_TILE_SIZE, 1)] +void TextureReduce(uint2 tid : SV_DispatchThreadID, uint2 gid: SV_GroupID, uint gidx: SV_GroupIndex) +{ + // initialize lds: only 1st thread of group does it + if (gidx == 0) + ldsShadingRate = UnpackShadingRate(_ShadingRateNativeValues[SHADING_RATE_FRAGMENT_SIZE_4x4]); + + // read: 1 thread == 1 pixel in main tex, each thread in group must read + float3 color = SampleVrsMainTexFromCoords(tid * _VrsScaleBias.xy).rgb; + uint shadingRateNativeValue = GetShadingRateNativeValueFromColor(color); + uint2 shadingRate = UnpackShadingRate(shadingRateNativeValue); + + GroupMemoryBarrierWithGroupSync(); + + // parallel reduce: 1 group == 1 pixel in vrs image + // conservative reduce: pick highest rate (hence min) + InterlockedMin(ldsShadingRate.x, shadingRate.x); + InterlockedMin(ldsShadingRate.y, shadingRate.y); + + GroupMemoryBarrierWithGroupSync(); + + // store result: only 1st thread of group does it + if (gidx == 0) + { + shadingRateNativeValue = PackShadingRate(ldsShadingRate); + ImageStore(shadingRateNativeValue, gid); + } +} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsTexture.compute.meta b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsTexture.compute.meta new file mode 100644 index 00000000..5fbb7b28 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsTexture.compute.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: cacb30de6c40c7444bbc78cb0a81fd2a +ComputeShaderImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsTileSize.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsTileSize.hlsl new file mode 100644 index 00000000..2838b032 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsTileSize.hlsl @@ -0,0 +1,14 @@ +#ifndef VRS_TILE_SIZE_INCLUDED +#define VRS_TILE_SIZE_INCLUDED + +#if defined(VRS_TILE_SIZE_8) + #define VRS_TILE_SIZE 8 +#elif defined(VRS_TILE_SIZE_16) + #define VRS_TILE_SIZE 16 +#elif defined(VRS_TILE_SIZE_32) + #define VRS_TILE_SIZE 32 +#else + #error Unsupported tile size +#endif + +#endif // VRS_TILE_SIZE_INCLUDED diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsTileSize.hlsl.meta b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsTileSize.hlsl.meta new file mode 100644 index 00000000..457e40f1 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsTileSize.hlsl.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 234c0613ab6043a7852e6ab1a268352a +timeCreated: 1710957835 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsVisualization.shader b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsVisualization.shader new file mode 100644 index 00000000..a00e2cc6 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsVisualization.shader @@ -0,0 +1,46 @@ +Shader "Hidden/Core/VrsVisualization" +{ + SubShader + { + Pass + { + Name "VrsVisualization" + ZTest Always + ZWrite Off + Cull Off + + HLSLPROGRAM + //#pragma enable_d3d11_debug_symbols + + #pragma exclude_renderers glcore gles3 + + #pragma vertex Vert + #pragma fragment Fragment + + #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureXR.hlsl" + #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" + #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl" + #include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl" + + TYPED_TEXTURE2D(uint, _ShadingRateImage); + StructuredBuffer _VisualizationLut; + + uniform float4 _VisualizationParams; + + #define PixelToTileScale _VisualizationParams.xy + + float4 Fragment(Varyings input) : SV_Target + { + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + uint2 pixel = (uint2)(input.positionCS.xy * PixelToTileScale); + uint shadingRate = LOAD_TEXTURE2D_LOD(_ShadingRateImage, pixel, 0); + + return _VisualizationLut[shadingRate]; + } + ENDHLSL + } + } + + Fallback Off +} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsVisualization.shader.meta b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsVisualization.shader.meta new file mode 100644 index 00000000..0f80dc6f --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Shaders/VrsVisualization.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 620b55b8040a88d468e94abe55bed5ba +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Vrs.cs b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Vrs.cs new file mode 100644 index 00000000..56992b91 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Vrs.cs @@ -0,0 +1,392 @@ +using System; +using UnityEngine.Rendering.RenderGraphModule; + +namespace UnityEngine.Rendering +{ + /// + /// Encapsulates variable shading rate support (VRS) and texture conversion to shading rate image + /// + public static class Vrs + { + class ConversionPassData + { + public TextureHandle sriTextureHandle; + public TextureHandle mainTexHandle; + public TextureDimension mainTexDimension; + public BufferHandle mainTexLutHandle; + public BufferHandle validatedShadingRateFragmentSizeHandle; + public ComputeShader computeShader; + public int kernelIndex; + public Vector4 scaleBias; + public Vector2Int dispatchSize; + public bool yFlip; + } + + class VisualizationPassData + { + public Material material; + public TextureHandle source; + public BufferHandle lut; + public TextureHandle dummy; + public Vector4 visualizationParams; + } + + internal static readonly int shadingRateFragmentSizeCount = Enum.GetNames(typeof(ShadingRateFragmentSize)).Length; + + static VrsResources s_VrsResources; + + /// + /// Check if conversion of color texture to shading rate image is supported. + /// Convenience to abstract all capabilities checks. + /// + /// Returns true if conversion of color texture to shading rate image is supported, false otherwise. + public static bool IsColorMaskTextureConversionSupported() + { + return SystemInfo.supportsComputeShaders && + ShadingRateInfo.supportsPerImageTile && + IsInitialized(); + } + + /// + /// Checks if VRS resources are initialized. + /// Initialization may fail due to platform restrictions. + /// + /// Returns true if the Vrs resources are initialized. + public static bool IsInitialized() + { + return s_VrsResources != null && + s_VrsResources.textureComputeShader != null && + s_VrsResources.textureReduceKernel != -1 && + s_VrsResources.textureCopyKernel != -1; + } + + /// + /// Preprocess resources found in VrsRenderPipelineRuntimeResources for use at runtime. + /// + public static void InitializeResources() + { + // GLES3.0/WebGL2 and older GL platforms do not support compute shaders (for conversion). + // Unity does not implement VRS for OpenGL. + bool isOpenGL = SystemInfo.graphicsDeviceType == GraphicsDeviceType.OpenGLCore || + SystemInfo.graphicsDeviceType == GraphicsDeviceType.OpenGLES3; + + // NOTE: should match "#pragma exclude_renderers" in shaders. + bool isPlatformSupported = !isOpenGL; + + // VRS resources are initialized even on platforms that do not support VRS to allow debugging Color<->VRS conversion. + // For example when you are building on a non-VRS platform to a VRS platform. + // VRS conversion requires compute shader support. + // NOTE: Init might fail. + if (SystemInfo.supportsComputeShaders && + isPlatformSupported) + { + var pipelineRuntimeResources = GraphicsSettings.GetRenderPipelineSettings(); + s_VrsResources = new VrsResources(pipelineRuntimeResources); + } + } + + /// + /// Cleanup resources. + /// + public static void DisposeResources() + { + s_VrsResources?.Dispose(); + s_VrsResources = null; + } + + /// + /// Converts a color mask texture to a shading rate image. + /// + /// Render graph to record conversion commands + /// Shading rate images to convert to. + /// Texture to convert from. + /// True if shading rate image should be generated flipped. + /// Shading rate image texture handle created. + /// + /// sriRtHandle and colorMaskRtHandle are imported with renderGraph before doing the conversion. + /// + public static TextureHandle ColorMaskTextureToShadingRateImage(RenderGraph renderGraph, RTHandle sriRtHandle, RTHandle colorMaskRtHandle, bool yFlip) + { + if (renderGraph == null || sriRtHandle == null || colorMaskRtHandle == null) + { + Debug.LogError($"TextureToShadingRateImage: invalid argument."); + return TextureHandle.nullHandle; + } + + var sriTextureHandle = renderGraph.ImportShadingRateImageTexture(sriRtHandle); + var colorMaskHandle = renderGraph.ImportTexture(colorMaskRtHandle); + + return ColorMaskTextureToShadingRateImage(renderGraph, + sriTextureHandle, + colorMaskHandle, + ((Texture)colorMaskRtHandle).dimension, + yFlip); + } + + /// + /// Converts a color mask texture to a shading rate image. + /// + /// Render graph to record conversion commands + /// Shading rate images to convert to. + /// Texture to convert from. + /// Texture's dimension. + /// True if shading rate image should be generated flipped. + /// Shading rate image texture handle created. + /// + /// sriRtHandle and colorMaskHandle are expected to be imported by renderGraph prior to this call. + /// + public static TextureHandle ColorMaskTextureToShadingRateImage(RenderGraph renderGraph, TextureHandle sriTextureHandle, TextureHandle colorMaskHandle, TextureDimension colorMaskDimension, bool yFlip) + { + if (!IsColorMaskTextureConversionSupported()) + { + Debug.LogError($"ColorMaskTextureToShadingRateImage: conversion not supported."); + return TextureHandle.nullHandle; + } + + var sriDesc = sriTextureHandle.GetDescriptor(renderGraph); + if (sriDesc.dimension != TextureDimension.Tex2D) + { + Debug.LogError($"ColorMaskTextureToShadingRateImage: Vrs image not a texture 2D."); + return TextureHandle.nullHandle; + } + + if (colorMaskDimension != TextureDimension.Tex2D && colorMaskDimension != TextureDimension.Tex2DArray) + { + Debug.LogError($"ColorMaskTextureToShadingRateImage: Input texture dimension not supported."); + return TextureHandle.nullHandle; + } + + using (var builder = renderGraph.AddComputePass("TextureToShadingRateImage", out var outerPassData, s_VrsResources.conversionProfilingSampler)) + { + outerPassData.sriTextureHandle = sriTextureHandle; + outerPassData.mainTexHandle = colorMaskHandle; + outerPassData.mainTexDimension = colorMaskDimension; + outerPassData.mainTexLutHandle = renderGraph.ImportBuffer(s_VrsResources.conversionLutBuffer); + outerPassData.validatedShadingRateFragmentSizeHandle = renderGraph.ImportBuffer(s_VrsResources.validatedShadingRateFragmentSizeBuffer); + + outerPassData.computeShader = s_VrsResources.textureComputeShader; + outerPassData.kernelIndex = s_VrsResources.textureReduceKernel; + outerPassData.scaleBias = new Vector4() + { + x = 1.0f / (sriDesc.width * s_VrsResources.tileSize.x), + y = 1.0f / (sriDesc.height * s_VrsResources.tileSize.y), + z = sriDesc.width, + w = sriDesc.height, + }; + outerPassData.dispatchSize = new Vector2Int(sriDesc.width, sriDesc.height); + outerPassData.yFlip = yFlip; + + builder.UseTexture(outerPassData.sriTextureHandle, AccessFlags.Write); + builder.UseTexture(outerPassData.mainTexHandle); + builder.UseBuffer(outerPassData.mainTexLutHandle); + + builder.AllowGlobalStateModification(true); + + builder.SetRenderFunc((ConversionPassData innerPassData, ComputeGraphContext context) => + { + ConversionDispatch(context.cmd, innerPassData); + }); + + return outerPassData.sriTextureHandle; + } + } + + /// + /// Converts a shading rate image to a color texture for visualization. + /// + /// Render graph to record conversion commands + /// Texture to convert from. + /// Output of conversion. + public static void ShadingRateImageToColorMaskTexture(RenderGraph renderGraph, in TextureHandle sriTextureHandle, in TextureHandle colorMaskHandle) + { + if (s_VrsResources == null) + { + Debug.LogError($"ShadingRateImageToColorMaskTexture: VRS not initialized."); + return; + } + + if (!colorMaskHandle.IsValid()) + { + Debug.LogError($"ShadingRateImageToColorMaskTexture: Output target handle is not valid."); + return; + } + + using (var builder = renderGraph.AddRasterRenderPass("ShadingRateImageToTexture", out var outerPassData, s_VrsResources.visualizationProfilingSampler)) + { + outerPassData.material = s_VrsResources.visualizationMaterial; + + if (sriTextureHandle.IsValid()) + outerPassData.source = sriTextureHandle; + else + outerPassData.source = renderGraph.defaultResources.blackTexture; + + outerPassData.lut = renderGraph.ImportBuffer(s_VrsResources.visualizationLutBuffer); + outerPassData.dummy = renderGraph.defaultResources.blackTexture; + outerPassData.visualizationParams = new Vector4( + 1.0f / s_VrsResources.tileSize.x, + 1.0f / s_VrsResources.tileSize.y, + 0, + 0);; + + builder.UseTexture(outerPassData.source); + builder.UseBuffer(outerPassData.lut); + builder.UseTexture(outerPassData.dummy); + builder.SetRenderAttachment(colorMaskHandle, 0); + + builder.AllowPassCulling(false); + + builder.SetRenderFunc((VisualizationPassData innerPassData, RasterGraphContext context) => + { + // must setup blitter source via the material: it's a typed texture (uint) + innerPassData.material.SetTexture(VrsShaders.s_ShadingRateImage, innerPassData.source); + innerPassData.material.SetBuffer(VrsShaders.s_VisualizationLut, innerPassData.lut); + innerPassData.material.SetVector(VrsShaders.s_VisualizationParams, innerPassData.visualizationParams); + + Blitter.BlitTexture(context.cmd, + innerPassData.dummy, + new Vector4(1, 1, 0, 0), + innerPassData.material, + 0); + }); + } + } + + static void ConversionDispatch(ComputeCommandBuffer cmd, ConversionPassData conversionPassData) + { + var disableTexture2dXArray = new LocalKeyword(conversionPassData.computeShader, VrsShaders.k_DisableTexture2dXArray); + if (conversionPassData.mainTexDimension == TextureDimension.Tex2DArray) + cmd.DisableKeyword(conversionPassData.computeShader, disableTexture2dXArray); + else + cmd.EnableKeyword(conversionPassData.computeShader, disableTexture2dXArray); + + var yFlip = new LocalKeyword(conversionPassData.computeShader, VrsShaders.k_YFlip); + if (conversionPassData.yFlip) + cmd.EnableKeyword(conversionPassData.computeShader, yFlip); + else + cmd.DisableKeyword(conversionPassData.computeShader, yFlip); + + cmd.SetComputeTextureParam(conversionPassData.computeShader, conversionPassData.kernelIndex, VrsShaders.s_MainTex, conversionPassData.mainTexHandle); + cmd.SetComputeBufferParam(conversionPassData.computeShader, conversionPassData.kernelIndex, VrsShaders.s_MainTexLut, conversionPassData.mainTexLutHandle); + cmd.SetComputeBufferParam(conversionPassData.computeShader, conversionPassData.kernelIndex, VrsShaders.s_ShadingRateNativeValues, conversionPassData.validatedShadingRateFragmentSizeHandle); + cmd.SetComputeTextureParam(conversionPassData.computeShader, conversionPassData.kernelIndex, VrsShaders.s_ShadingRateImage, conversionPassData.sriTextureHandle); + cmd.SetComputeVectorParam(conversionPassData.computeShader, VrsShaders.s_ScaleBias, conversionPassData.scaleBias); + + cmd.DispatchCompute(conversionPassData.computeShader, conversionPassData.kernelIndex, conversionPassData.dispatchSize.x, conversionPassData.dispatchSize.y, 1); + } + + /// + /// Converts a color mask texture to a shading rate image. + /// Use this function to perform the conversion without the RenderGraph. + /// + /// CommandBuffer used for the compute dispatch. + /// Shading rate images to convert to. + /// Texture to convert from. + /// True if shading rate image should be generated flipped. + public static void ColorMaskTextureToShadingRateImageDispatch(CommandBuffer cmd, RTHandle sriDestination, Texture colorMaskSource, bool yFlip = true) + { + if (sriDestination == null) + { + Debug.LogError("ColorMaskTextureToShadingRateImageDispatch: VRS destination shading rate texture is null."); + return; + } + + if (colorMaskSource == null) + { + Debug.LogError("ColorMaskTextureToShadingRateImageDispatch: VRS source color texture is null."); + return; + } + + if (!IsInitialized()) + { + Debug.LogError("ColorMaskTextureToShadingRateImageDispatch: VRS is not initialized."); + return; + } + + var computeShader = s_VrsResources.textureComputeShader; + var kernelIndex = s_VrsResources.textureReduceKernel; + var colorLutBuffer = s_VrsResources.conversionLutBuffer; + var validatedShadingRateFragmentSizeBuffer = s_VrsResources.validatedShadingRateFragmentSizeBuffer; + + int sriDestWidth = sriDestination.rt.width; + int sriDestHeight = sriDestination.rt.height; + var scaleBias = new Vector4() + { + x = 1.0f / (sriDestWidth * s_VrsResources.tileSize.x), + y = 1.0f / (sriDestHeight * s_VrsResources.tileSize.y), + z = sriDestWidth, + w = sriDestHeight, + }; + + var dispatchSize = new Vector2Int(sriDestWidth, sriDestHeight); + + var disableTexture2dXArray = new LocalKeyword(computeShader, VrsShaders.k_DisableTexture2dXArray); + if (colorMaskSource?.dimension == TextureDimension.Tex2DArray) + cmd.DisableKeyword(computeShader, disableTexture2dXArray); + else + cmd.EnableKeyword(computeShader, disableTexture2dXArray); + + var yFlipKeyword = new LocalKeyword(computeShader, VrsShaders.k_YFlip); + if (yFlip) + cmd.EnableKeyword(computeShader, yFlipKeyword); + else + cmd.DisableKeyword(computeShader, yFlipKeyword); + + cmd.SetComputeTextureParam(computeShader, kernelIndex, VrsShaders.s_MainTex, colorMaskSource); + cmd.SetComputeBufferParam(computeShader, kernelIndex, VrsShaders.s_MainTexLut, colorLutBuffer); + cmd.SetComputeBufferParam(computeShader, kernelIndex, VrsShaders.s_ShadingRateNativeValues, validatedShadingRateFragmentSizeBuffer); + cmd.SetComputeTextureParam(computeShader, kernelIndex, VrsShaders.s_ShadingRateImage, sriDestination); + cmd.SetComputeVectorParam(computeShader, VrsShaders.s_ScaleBias, scaleBias); + + cmd.DispatchCompute(computeShader, kernelIndex, dispatchSize.x, dispatchSize.y, 1); + } + + /// + /// Converts a shading rate image to a color mask texture. + /// Use this function to perform the conversion without the RenderGraph. + /// + /// CommandBuffer used for the compute dispatch. + /// Shading rate images to convert from. + /// Texture to convert to. + public static void ShadingRateImageToColorMaskTextureBlit(CommandBuffer cmd, RTHandle sriSource, RTHandle colorMaskDestination) + { + if (sriSource == null) + { + Debug.LogError("ShadingRateImageToColorMaskTextureBlit: VRS source shading rate texture is null."); + return; + } + + if (colorMaskDestination == null) + { + Debug.LogError("ShadingRateImageToColorMaskTextureBlit: VRS destination color texture is null."); + return; + } + + if(!IsInitialized()) + { + Debug.LogError("ShadingRateImageToColorMaskTextureBlit: VRS is not initialized."); + return; + } + + RTHandle source = sriSource; + RTHandle destination = colorMaskDestination; + + var material = s_VrsResources.visualizationMaterial; + var lut = s_VrsResources.visualizationLutBuffer; + Vector4 visualizationParams = new Vector4( + 1.0f / s_VrsResources.tileSize.x, + 1.0f / s_VrsResources.tileSize.y, + 0, + 0); + + material.SetTexture(VrsShaders.s_ShadingRateImage, source); + material.SetBuffer(VrsShaders.s_VisualizationLut, lut); + material.SetVector(VrsShaders.s_VisualizationParams, visualizationParams); + + CoreUtils.SetRenderTarget(cmd, destination); + Blitter.BlitTexture(cmd, + new Vector4(1, 1, 0, 0), + material, + 0); + } + } +} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Vrs.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Vrs.cs.meta new file mode 100644 index 00000000..828f6274 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/Vrs.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: a5153735ff79d6149a038ac6417b9301 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsLut.cs b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsLut.cs new file mode 100644 index 00000000..7f53faf6 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsLut.cs @@ -0,0 +1,124 @@ +using System; +using System.Runtime.InteropServices; + +namespace UnityEngine.Rendering +{ + /// + /// Variable rate shading lookup table. Use to convert shading rate fragment size and color back and forth. + /// + [Serializable] + public class VrsLut + { + /// + /// Get a new instance of default VrsLut + /// + /// New instance of default VrsLut + public static VrsLut CreateDefault() + { + return new VrsLut() + { + [ShadingRateFragmentSize.FragmentSize1x1] = Color.red, + [ShadingRateFragmentSize.FragmentSize1x2] = Color.yellow, + [ShadingRateFragmentSize.FragmentSize2x1] = Color.white, + [ShadingRateFragmentSize.FragmentSize2x2] = Color.green, + [ShadingRateFragmentSize.FragmentSize1x4] = new Color(0.75f, 0.75f, 0.00f, 1), + [ShadingRateFragmentSize.FragmentSize4x1] = new Color(0.00f, 0.75f, 0.55f, 1), + [ShadingRateFragmentSize.FragmentSize2x4] = new Color(0.50f, 0.00f, 0.50f, 1), + [ShadingRateFragmentSize.FragmentSize4x2] = Color.grey, + [ShadingRateFragmentSize.FragmentSize4x4] = Color.blue, + }; + } + + [SerializeField] + Color[] m_Data = new Color[Vrs.shadingRateFragmentSizeCount]; + + /// + /// Indexing data with ShadingRateFragmentSize enum. + /// + /// Shading rate fragment size to set/get + public Color this[ShadingRateFragmentSize fragmentSize] + { + get => m_Data[(int)fragmentSize]; + set => m_Data[(int)fragmentSize] = value; + } + + /// + /// Create a compute buffer from the lookup table. + /// + /// If true, the buffer will be created with the visualization shader in mind + /// Graphics buffer representing this lookup table + public GraphicsBuffer CreateBuffer(bool forVisualization = false) + { + GraphicsBuffer buffer; + Color[] bufferData; + + if (forVisualization) + { + // lookup table will be used to map shading rate native values to colors + var fragmentSizes = Enum.GetValues(typeof(ShadingRateFragmentSize)); + // Get the encoded binary value associated of the max shading rate supported by our LUT. + // The encoded value will not be sequential. For example, 4x4 is encoded as 0b1010 = 10. + // We do this manually as ShadingRateInfo.QueryNativeValue will return 0 for rates that are + // not supported, which can lead to overflow on devices that support only up to 2x2. + var maxNativeValue = MapFragmentShadingRateToBinary(ShadingRateFragmentSize.FragmentSize4x4); + + bufferData = new Color[maxNativeValue + 1]; + + for (int i = fragmentSizes.Length - 1; i >= 0; --i) + { + var fragmentSize = (ShadingRateFragmentSize)fragmentSizes.GetValue(i); + var nativeValue = ShadingRateInfo.QueryNativeValue(fragmentSize); + bufferData[nativeValue] = m_Data[(int) fragmentSize].linear; + } + } + else + { + // lookup table will be used to map colors to shading rate index + bufferData = new Color[m_Data.Length]; + for (int i = 0; i < m_Data.Length; ++i) + { + bufferData[i] = m_Data[i].linear; + } + } + + buffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, bufferData.Length, Marshal.SizeOf(typeof(Color))); + buffer.SetData(bufferData); + + return buffer; + } + + private const uint Rate1x = 0; + private const uint Rate2x = 1; + private const uint Rate4x = 2; + private uint MapFragmentShadingRateToBinary(ShadingRateFragmentSize fs) + { + switch (fs) + { + default: + case ShadingRateFragmentSize.FragmentSize1x1: + return EncodeShadingRate(Rate1x, Rate1x); + case ShadingRateFragmentSize.FragmentSize1x2: + return EncodeShadingRate(Rate1x, Rate2x); + case ShadingRateFragmentSize.FragmentSize2x1: + return EncodeShadingRate(Rate2x, Rate1x); + case ShadingRateFragmentSize.FragmentSize2x2: + return EncodeShadingRate(Rate2x, Rate2x); + case ShadingRateFragmentSize.FragmentSize1x4: + return EncodeShadingRate(Rate1x, Rate4x); + case ShadingRateFragmentSize.FragmentSize4x1: + return EncodeShadingRate(Rate4x, Rate1x); + case ShadingRateFragmentSize.FragmentSize2x4: + return EncodeShadingRate(Rate2x, Rate4x); + case ShadingRateFragmentSize.FragmentSize4x2: + return EncodeShadingRate(Rate4x, Rate2x); + case ShadingRateFragmentSize.FragmentSize4x4: + return EncodeShadingRate(Rate4x, Rate4x); + } + } + + private uint EncodeShadingRate(uint x, uint y) + { + return ((x << 2) | (y)); + } + } +} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsLut.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsLut.cs.meta new file mode 100644 index 00000000..0842d30f --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsLut.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 022af1b7cce79be46aec3272d72bf1f8 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsRenderPipelineRuntimeResources.cs b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsRenderPipelineRuntimeResources.cs new file mode 100644 index 00000000..95b724b6 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsRenderPipelineRuntimeResources.cs @@ -0,0 +1,72 @@ +using System; + +namespace UnityEngine.Rendering +{ + /// + /// Class that stores the Variable Rate Shading common global resources + /// + [Serializable] + [SupportedOnRenderPipeline] + [Categorization.CategoryInfo(Name = "R: VRS - Runtime Resources", Order = 1000), HideInInspector] + public sealed class VrsRenderPipelineRuntimeResources : IRenderPipelineResources + { + /// + /// Version of the Vrs Resources + /// + public int version => 0; + + bool IRenderPipelineGraphicsSettings.isAvailableInPlayerBuild => true; + + [SerializeField] + [ResourcePath("Runtime/Vrs/Shaders/VrsTexture.compute")] + ComputeShader m_TextureComputeShader; + + /// + /// General Vrs compute shader. + /// + public ComputeShader textureComputeShader + { + get => m_TextureComputeShader; + set => this.SetValueAndNotify(ref m_TextureComputeShader, value, nameof(m_TextureComputeShader)); + } + + [SerializeField] + [ResourcePath("Runtime/Vrs/Shaders/VrsVisualization.shader")] + Shader m_VisualizationShader; + + /// + /// Show resource shader. + /// + public Shader visualizationShader + { + get => m_VisualizationShader; + set => this.SetValueAndNotify(ref m_VisualizationShader, value, nameof(m_VisualizationShader)); + } + + [SerializeField] + [Tooltip("Colors to visualize the shading rates")] + VrsLut m_VisualizationLookupTable = VrsLut.CreateDefault(); + + /// + /// Shading rate visualization lookup table. + /// + public VrsLut visualizationLookupTable + { + get => m_VisualizationLookupTable; + set => this.SetValueAndNotify(ref m_VisualizationLookupTable, value, nameof(m_VisualizationLookupTable)); + } + + [SerializeField] + [Tooltip("Colors to convert between shading rates and textures")] + VrsLut m_ConversionLookupTable = VrsLut.CreateDefault(); + + /// + /// texture to/from Shading rate conversion lookup table. + /// + public VrsLut conversionLookupTable + { + get => m_ConversionLookupTable; + set => this.SetValueAndNotify(ref m_ConversionLookupTable, value, nameof(m_ConversionLookupTable)); + } + } +} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsRenderPipelineRuntimeResources.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsRenderPipelineRuntimeResources.cs.meta new file mode 100644 index 00000000..8c90930c --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsRenderPipelineRuntimeResources.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: c75bfa9127302bc4cbc67983804a44ac \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsResources.cs b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsResources.cs new file mode 100644 index 00000000..ba7dbb8a --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsResources.cs @@ -0,0 +1,173 @@ +using System; + +namespace UnityEngine.Rendering +{ + class VrsResources : IDisposable + { + internal ProfilingSampler conversionProfilingSampler = new ProfilingSampler("VrsConversion"); + internal ProfilingSampler visualizationProfilingSampler = new ProfilingSampler("VrsVisualization"); + internal GraphicsBuffer conversionLutBuffer; + internal GraphicsBuffer visualizationLutBuffer; + + internal ComputeShader textureComputeShader; + internal int textureReduceKernel = -1; + internal int textureCopyKernel = -1; + + internal Vector2Int tileSize; + + internal GraphicsBuffer validatedShadingRateFragmentSizeBuffer; + + Shader m_VisualizationShader; + Material m_VisualizationMaterial; + internal Material visualizationMaterial + { + get + { + // explicit check here: handle case where m_Material is set to null when editor reloads + if (m_VisualizationMaterial == null) + m_VisualizationMaterial = new Material(m_VisualizationShader); + + return m_VisualizationMaterial; + } + } + + internal VrsResources(VrsRenderPipelineRuntimeResources resources) + { + InitializeResources(resources); + +#if UNITY_EDITOR + GraphicsSettings.Unsubscribe(OnVrsResourcesChanged); + GraphicsSettings.Subscribe(OnVrsResourcesChanged); +#endif + } + +#if UNITY_EDITOR + void OnVrsResourcesChanged(VrsRenderPipelineRuntimeResources resources, string propertyName) + { + DisposeResources(); + InitializeResources(resources); + } +#endif + + ~VrsResources() + { + Dispose(); + GC.SuppressFinalize(this); + } + + public void Dispose() + { +#if UNITY_EDITOR + GraphicsSettings.Unsubscribe(OnVrsResourcesChanged); +#endif + DisposeResources(); + } + + void InitializeResources(VrsRenderPipelineRuntimeResources resources) + { + bool success = InitComputeShader(resources); + if (!success) + { + DisposeResources(); + return; + } + + m_VisualizationShader = resources.visualizationShader; + conversionLutBuffer = resources.conversionLookupTable.CreateBuffer(); + visualizationLutBuffer = resources.visualizationLookupTable.CreateBuffer(true); + AllocFragmentSizeBuffer(); + } + + void DisposeResources() + { + conversionLutBuffer?.Dispose(); + conversionLutBuffer = null; + + visualizationLutBuffer?.Dispose(); + visualizationLutBuffer = null; + + validatedShadingRateFragmentSizeBuffer?.Dispose(); + validatedShadingRateFragmentSizeBuffer = null; + + m_VisualizationShader = null; + m_VisualizationMaterial = null; + } + + void AllocFragmentSizeBuffer() + { + // Get available shading rate fragment sizes; unsupported ones + // will be mapped to the closest supported one. + var fragmentSize = new uint[Vrs.shadingRateFragmentSizeCount]; + + var lastAvailableFragmentSize = ShadingRateFragmentSize.FragmentSize1x1; + uint fragmentSizeNativeValue = ShadingRateInfo.QueryNativeValue(lastAvailableFragmentSize); + + foreach (var availableFragmentSize in ShadingRateInfo.availableFragmentSizes) + { + Array.Fill(fragmentSize, + fragmentSizeNativeValue, + (int)lastAvailableFragmentSize, + availableFragmentSize - lastAvailableFragmentSize + 1); + + lastAvailableFragmentSize = availableFragmentSize; + fragmentSizeNativeValue = ShadingRateInfo.QueryNativeValue(lastAvailableFragmentSize); + } + + Array.Fill(fragmentSize, + fragmentSizeNativeValue, + (int)lastAvailableFragmentSize, + ShadingRateFragmentSize.FragmentSize4x4 - lastAvailableFragmentSize + 1); + + validatedShadingRateFragmentSizeBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, fragmentSize.Length, sizeof(uint)); + validatedShadingRateFragmentSizeBuffer.SetData(fragmentSize); + } + + bool InitComputeShader(VrsRenderPipelineRuntimeResources resources) + { + // This Compute Shader resource is used for converting an RGB texture to an R8 SRI + // Don't initialize it if the device does not support image-based VRS + if (!ShadingRateInfo.supportsPerImageTile) + { + return false; + } + + if (!SystemInfo.supportsComputeShaders) + { + return false; + } + + tileSize = ShadingRateInfo.imageTileSize; + var tileSizeOk = tileSize.x == tileSize.y && (tileSize.x == 8 || tileSize.x == 16 || tileSize.x == 32); + if (!tileSizeOk) + { + Debug.LogError($"VRS unsupported tile size: {tileSize.x}x{tileSize.y}."); + return false; + } + + // We expect keywords, if the shader was excluded/discarded then no keywords. + if (resources.textureComputeShader?.keywordSpace.keywordCount <= 0) + { + // Invalidate kernel indices in case they were set (shader reload) + textureReduceKernel = -1; + textureCopyKernel = -1; + return false; + } + + textureComputeShader = resources.textureComputeShader; + + // this keyword need only be set once + textureComputeShader.EnableKeyword($"{VrsShaders.k_TileSizePrefix}{tileSize.x}"); + + // find kernel might fail + textureReduceKernel = TryFindKernel(textureComputeShader, VrsShaders.k_KernelTextureReduce); + textureCopyKernel = TryFindKernel(textureComputeShader, VrsShaders.k_KernelTextureReduce); + + if (textureReduceKernel == -1 || textureCopyKernel == -1) + return false; + + return true; + } + + static int TryFindKernel(ComputeShader computeShader, string name) => computeShader.HasKernel(name) ? computeShader.FindKernel(name) : -1; + } +} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsResources.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsResources.cs.meta new file mode 100644 index 00000000..86967c09 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsResources.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 785d30f91e90dd2448cb87e5f026e49a \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsShaders.cs b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsShaders.cs new file mode 100644 index 00000000..ae683d60 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsShaders.cs @@ -0,0 +1,24 @@ +namespace UnityEngine.Rendering +{ + static class VrsShaders + { + internal const string k_TileSizePrefix = "VRS_TILE_SIZE_"; + + internal const string k_DisableTexture2dXArray = "DISABLE_TEXTURE2D_X_ARRAY"; + internal const string k_YFlip = "APPLY_Y_FLIP"; + + internal static readonly int s_ScaleBias = Shader.PropertyToID("_VrsScaleBias"); + + internal static readonly int s_MainTex = Shader.PropertyToID("_VrsMainTex"); + internal static readonly int s_MainTexLut = Shader.PropertyToID("_VrsMainTexLut"); + + internal static readonly int s_ShadingRateNativeValues = Shader.PropertyToID("_ShadingRateNativeValues"); + internal static readonly int s_ShadingRateImage = Shader.PropertyToID("_ShadingRateImage"); + + internal const string k_KernelTextureCopy = "TextureCopy"; + internal const string k_KernelTextureReduce = "TextureReduce"; + + internal static readonly int s_VisualizationLut = Shader.PropertyToID("_VisualizationLut"); + internal static readonly int s_VisualizationParams = Shader.PropertyToID("_VisualizationParams"); + } +} diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsShaders.cs.meta b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsShaders.cs.meta new file mode 100644 index 00000000..21b075a5 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Runtime/Vrs/VrsShaders.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 4ba9dce31226373439673a105ffbaef2 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Runtime/XR/XRGraphicsAutomatedTests.cs b/Packages/com.unity.render-pipelines.core/Runtime/XR/XRGraphicsAutomatedTests.cs index 9cbb50ad..b1c64f65 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/XR/XRGraphicsAutomatedTests.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/XR/XRGraphicsAutomatedTests.cs @@ -24,7 +24,7 @@ namespace UnityEngine.Rendering /// /// Used by render pipelines to initialize XR tests. /// - public static bool enabled { get; } = activatedFromCommandLine; + public static bool enabled { get; set; } = activatedFromCommandLine; /// /// Set by automated test framework and read by render pipelines. diff --git a/Packages/com.unity.render-pipelines.core/Runtime/XR/XRPass.cs b/Packages/com.unity.render-pipelines.core/Runtime/XR/XRPass.cs index 7f14300b..65c9de7b 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/XR/XRPass.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/XR/XRPass.cs @@ -17,6 +17,8 @@ namespace UnityEngine.Experimental.Rendering internal ScriptableCullingParameters cullingParameters; internal Material occlusionMeshMaterial; internal float occlusionMeshScale; + internal int renderTargetScaledWidth; + internal int renderTargetScaledHeight; internal IntPtr foveatedRenderingInfo; internal int multipassId; internal int cullingPassId; @@ -126,6 +128,16 @@ namespace UnityEngine.Experimental.Rendering /// public int cullingPassId { get; private set; } + /// + /// Destination render target scaled width if XR dynamic resolution is enabled + /// + public int renderTargetScaledWidth { get; private set; } + + /// + /// Destination render target scaled height if XR dynamic resolution is enabled + /// + public int renderTargetScaledHeight { get; private set; } + /// /// Destination render target. /// @@ -463,6 +475,8 @@ namespace UnityEngine.Experimental.Rendering AssignCullingParams(createInfo.cullingPassId, createInfo.cullingParameters); renderTarget = new RenderTargetIdentifier(createInfo.renderTarget, 0, CubemapFace.Unknown, -1); renderTargetDesc = createInfo.renderTargetDesc; + renderTargetScaledWidth = createInfo.renderTargetScaledWidth; + renderTargetScaledHeight = createInfo.renderTargetScaledHeight; motionVectorRenderTarget = new RenderTargetIdentifier(createInfo.motionVectorRenderTarget, 0, CubemapFace.Unknown, -1); motionVectorRenderTargetDesc = createInfo.motionVectorRenderTargetDesc; hasMotionVectorPass = createInfo.hasMotionVectorPass; diff --git a/Packages/com.unity.render-pipelines.core/Runtime/XR/XRSystem.cs b/Packages/com.unity.render-pipelines.core/Runtime/XR/XRSystem.cs index 6be5c7b8..aa80bd23 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/XR/XRSystem.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/XR/XRSystem.cs @@ -242,6 +242,49 @@ namespace UnityEngine.Experimental.Rendering #endif } + /// + /// Used by the render pipeline to retrieve the DynamicResolutionScale value from the XR display. + /// One use case for retrieving this value is that render pipeline can properly sync some SRP owned textures to scale accordingly + /// + /// Returns current DynamicResolutionScale value from the XRDisplaySubsystem. + public static float GetDynamicResolutionScale() + { +#if ENABLE_VR && ENABLE_XR_MODULE + + return s_Display.globalDynamicScale; +#else + return 1.0f; +#endif + } + + /// + /// Used by the render pipeline to calculate texture scaled width for XR display if it supports dynamic resolution + /// + /// Input texture that supports dynamic resolution + /// Returns current scaled width of the input texture. + public static int ScaleTextureWidthForXR(RenderTexture texture) + { +#if ENABLE_VR && ENABLE_XR_MODULE + return s_Display.ScaledTextureWidth(texture); +#else + return 1; +#endif + } + + /// + /// Used by the render pipeline to calculate texture scaled height for XR display if it supports dynamic resolution + /// + /// Input texture that supports dynamic resolution + /// Returns current scaled width of the input texture. + public static int ScaleTextureHeightForXR(RenderTexture texture) + { +#if ENABLE_VR && ENABLE_XR_MODULE + return s_Display.ScaledTextureHeight(texture); +#else + return 1; +#endif + } + /// /// Used by the render pipeline to initiate a new rendering frame through a XR layout. /// @@ -436,6 +479,9 @@ namespace UnityEngine.Experimental.Rendering if (renderParam0.textureArraySlice != 0 || renderParam1.textureArraySlice != 1) return false; + if (renderParam0.viewport != renderParam1.viewport) + return false; + return true; } @@ -443,10 +489,11 @@ namespace UnityEngine.Experimental.Rendering { // Convert viewport from normalized to screen space Rect viewport = renderParameter.viewport; - viewport.x *= renderPass.renderTargetDesc.width; - viewport.width *= renderPass.renderTargetDesc.width; - viewport.y *= renderPass.renderTargetDesc.height; - viewport.height *= renderPass.renderTargetDesc.height; + + viewport.x *= renderPass.renderTargetScaledWidth; + viewport.width *= renderPass.renderTargetScaledWidth; + viewport.y *= renderPass.renderTargetScaledHeight; + viewport.height *= renderPass.renderTargetScaledHeight; // XRTODO : remove this line and use XRSettings.useOcclusionMesh instead when it's fixed Mesh occlusionMesh = XRGraphicsAutomatedTests.running ? null : renderParameter.occlusionMesh; @@ -460,6 +507,7 @@ namespace UnityEngine.Experimental.Rendering // XRTODO : fix root problem RenderTextureDescriptor rtDesc = new RenderTextureDescriptor(xrDesc.width, xrDesc.height, xrDesc.graphicsFormat, xrDesc.depthStencilFormat, xrDesc.mipCount); rtDesc.dimension = xrDesc.dimension; + rtDesc.msaaSamples = xrDesc.msaaSamples; rtDesc.volumeDepth = xrDesc.volumeDepth; rtDesc.vrUsage = xrDesc.vrUsage; rtDesc.sRGB = xrDesc.sRGB; @@ -473,7 +521,9 @@ namespace UnityEngine.Experimental.Rendering { renderTarget = xrRenderPass.renderTarget, renderTargetDesc = XrRenderTextureDescToUnityRenderTextureDesc(xrRenderPass.renderTargetDesc), - hasMotionVectorPass = xrRenderPass.hasMotionVectorPass, + renderTargetScaledWidth = xrRenderPass.renderTargetScaledWidth, + renderTargetScaledHeight = xrRenderPass.renderTargetScaledHeight, + hasMotionVectorPass = xrRenderPass.hasMotionVectorPass, motionVectorRenderTarget = xrRenderPass.motionVectorRenderTarget, motionVectorRenderTargetDesc = XrRenderTextureDescToUnityRenderTextureDesc(xrRenderPass.motionVectorRenderTargetDesc), cullingParameters = cullingParameters, diff --git a/Packages/com.unity.render-pipelines.core/ShaderLibrary/API/GLES3.hlsl b/Packages/com.unity.render-pipelines.core/ShaderLibrary/API/GLES3.hlsl index b5e9d13e..9dacf8d9 100644 --- a/Packages/com.unity.render-pipelines.core/ShaderLibrary/API/GLES3.hlsl +++ b/Packages/com.unity.render-pipelines.core/ShaderLibrary/API/GLES3.hlsl @@ -38,6 +38,15 @@ #define GLES3_1_AEP 0 #endif +// GLES3 causes a performance regression in some devices when using CBUFFER. +// WebGL needs to put LightShadow uniforms into a uniform buffer, +// despite being a GLES3 API. Some mobile devices, such as Adreno GPUs, +// have a small GL_MAX_FRAGMENT_UNIFORM_VECTORS limit, causing Lit shaders +// to fail on those devices. https://jira.unity3d.com/browse/UUM-87232 +#if !defined(UNITY_PLATFORM_WEBGL) +#define LIGHT_SHADOWS_NO_CBUFFER +#endif + // Initialize arbitrary structure with zero values. // Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0 #define ZERO_INITIALIZE(type, name) name = (type)0; diff --git a/Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl b/Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl index 01b3fe6b..1191d588 100644 --- a/Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl +++ b/Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl @@ -8,6 +8,7 @@ #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/SphericalHarmonics.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Filtering.hlsl" #define LIGHTMAP_RGBM_MAX_GAMMA real(5.0) // NB: Must match value in RGBMRanges.h #define LIGHTMAP_RGBM_MAX_LINEAR real(34.493242) // LIGHTMAP_RGBM_MAX_GAMMA ^ 2.2 @@ -208,6 +209,8 @@ real3 DecodeHDREnvironment(real4 encodedIrradiance, real4 decodeInstructions) #define SAMPLE_TEXTURE2D_LIGHTMAP SAMPLE_TEXTURE2D_ARRAY #define LIGHTMAP_EXTRA_ARGS float2 uv, float slice #define LIGHTMAP_EXTRA_ARGS_USE uv, slice +#define LIGHTMAP_SLICE_ARG_USE , slice +#define GET_LIGHTMAP_SIZE(tex, width, height) uint _slices; tex.GetDimensions(width, height, _slices) #else // ^ Lightmaps are not bound as texture arrays, but as individual textures. The // batch is broken every time lightmaps are changed, but this is well-supported @@ -217,6 +220,8 @@ real3 DecodeHDREnvironment(real4 encodedIrradiance, real4 decodeInstructions) #define SAMPLE_TEXTURE2D_LIGHTMAP SAMPLE_TEXTURE2D #define LIGHTMAP_EXTRA_ARGS float2 uv #define LIGHTMAP_EXTRA_ARGS_USE uv +#define LIGHTMAP_SLICE_ARG_USE +#define GET_LIGHTMAP_SIZE(tex, width, height) tex.GetDimensions(width, height) #endif // For the built-in target, lightmaps are defined with half precision. @@ -236,6 +241,27 @@ real3 DecodeHDREnvironment(real4 encodedIrradiance, real4 decodeInstructions) #define SAMPLE_TEXTURE2D_LIGHTMAP SAMPLE_TEXTURE2D #endif +// 4-tap bicubic sampling for lightmaps. Assumes the input texture is bilinearly filtered. +float4 SampleLightmapBicubic(TEXTURE2D_LIGHTMAP_PARAM(tex, smp), LIGHTMAP_EXTRA_ARGS) +{ + float width; + float height; + GET_LIGHTMAP_SIZE(tex, width, height); + float4 texSize = float4(width, height, 1.0/width, 1.0/height); + + float2 xy = uv * texSize.xy + 0.5; + float2 ic = floor(xy); + float2 fc = frac(xy); + + float2 weights[2], offsets[2]; + BicubicFilter(fc, weights, offsets); + + return weights[0].y * (weights[0].x * SAMPLE_TEXTURE2D_LIGHTMAP(tex, smp, (ic + float2(offsets[0].x, offsets[0].y) - 0.5) * texSize.zw LIGHTMAP_SLICE_ARG_USE).rgba + + weights[1].x * SAMPLE_TEXTURE2D_LIGHTMAP(tex, smp, (ic + float2(offsets[1].x, offsets[0].y) - 0.5) * texSize.zw LIGHTMAP_SLICE_ARG_USE).rgba) + + weights[1].y * (weights[0].x * SAMPLE_TEXTURE2D_LIGHTMAP(tex, smp, (ic + float2(offsets[0].x, offsets[1].y) - 0.5) * texSize.zw LIGHTMAP_SLICE_ARG_USE).rgba + + weights[1].x * SAMPLE_TEXTURE2D_LIGHTMAP(tex, smp, (ic + float2(offsets[1].x, offsets[1].y) - 0.5) * texSize.zw LIGHTMAP_SLICE_ARG_USE).rgba); +} + // isStaticLightmap mean it is not an Enlighten map real3 SampleSingleLightmap(TEXTURE2D_LIGHTMAP_PARAM(lightmapTex, lightmapSampler), LIGHTMAP_EXTRA_ARGS, float4 transform, bool isStaticLightmap) { @@ -243,7 +269,11 @@ real3 SampleSingleLightmap(TEXTURE2D_LIGHTMAP_PARAM(lightmapTex, lightmapSampler // transform is scale and bias uv = uv * transform.xy + transform.zw; +#if defined(LIGHTMAP_BICUBIC_SAMPLING) + real4 encodedIlluminance = SampleLightmapBicubic(TEXTURE2D_LIGHTMAP_ARGS(lightmapTex, lightmapSampler), LIGHTMAP_EXTRA_ARGS_USE); +#else real4 encodedIlluminance = SAMPLE_TEXTURE2D_LIGHTMAP(lightmapTex, lightmapSampler, LIGHTMAP_EXTRA_ARGS_USE).rgba; +#endif // Remark: static lightmap is RGBM for now, dynamic lightmap is RGB9E5 real3 illuminance = isStaticLightmap ? DecodeLightmap(encodedIlluminance, decodeInstructions) : encodedIlluminance.rgb; @@ -271,7 +301,11 @@ void SampleDirectionalLightmap(TEXTURE2D_LIGHTMAP_PARAM(lightmapTex, lightmapSam // transform is scale and bias uv = uv * transform.xy + transform.zw; +#if defined(LIGHTMAP_BICUBIC_SAMPLING) + real4 direction = SampleLightmapBicubic(TEXTURE2D_LIGHTMAP_ARGS(lightmapDirTex, lightmapDirSampler), LIGHTMAP_EXTRA_ARGS_USE); +#else real4 direction = SAMPLE_TEXTURE2D_LIGHTMAP(lightmapDirTex, lightmapDirSampler, LIGHTMAP_EXTRA_ARGS_USE); +#endif real halfLambert = dot(normalWS, direction.xyz - 0.5) + 0.5; bakeDiffuseLighting += illuminance * halfLambert / max(1e-4, direction.w); diff --git a/Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl b/Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl index 456d92b1..18150931 100644 --- a/Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl +++ b/Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl @@ -196,7 +196,7 @@ real3 UnpackNormalAG(real4 packedNormal, real scale = 1.0) } // Unpack normal as DXT5nm (1, y, 0, x) or BC5 (x, y, 0, 1) -real3 UnpackNormalmapRGorAG(real4 packedNormal, real scale = 1.0) +real3 UnpackNormalMapRGorAG(real4 packedNormal, real scale = 1.0) { // Convert to (?, y, 0, x) packedNormal.a *= packedNormal.r; @@ -212,7 +212,7 @@ real3 UnpackNormal(real4 packedNormal) return UnpackNormalRGBNoScale(packedNormal); #else // Compiler will optimize the scale away - return UnpackNormalmapRGorAG(packedNormal, 1.0); + return UnpackNormalMapRGorAG(packedNormal, 1.0); #endif } #endif @@ -224,7 +224,7 @@ real3 UnpackNormalScale(real4 packedNormal, real bumpScale) #elif defined(UNITY_NO_DXT5nm) return UnpackNormalRGB(packedNormal, bumpScale); #else - return UnpackNormalmapRGorAG(packedNormal, bumpScale); + return UnpackNormalMapRGorAG(packedNormal, bumpScale); #endif } diff --git a/Packages/com.unity.render-pipelines.core/ShaderLibrary/Sampling/SampleUVMappingInternal.hlsl b/Packages/com.unity.render-pipelines.core/ShaderLibrary/Sampling/SampleUVMappingInternal.hlsl index a9954ca3..b4009dff 100644 --- a/Packages/com.unity.render-pipelines.core/ShaderLibrary/Sampling/SampleUVMappingInternal.hlsl +++ b/Packages/com.unity.render-pipelines.core/ShaderLibrary/Sampling/SampleUVMappingInternal.hlsl @@ -37,7 +37,7 @@ real4 ADD_FUNC_SUFFIX(SampleUVMapping)(TEXTURE2D_PARAM(textureName, samplerName) #define UNPACK_NORMAL_FUNC UnpackNormalRGB #define UNPACK_DERIVATIVE_FUNC UnpackDerivativeNormalRGB #else -#define UNPACK_NORMAL_FUNC UnpackNormalmapRGorAG +#define UNPACK_NORMAL_FUNC UnpackNormalMapRGorAG #define UNPACK_DERIVATIVE_FUNC UnpackDerivativeNormalRGorAG #endif #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Sampling/SampleUVMappingNormalInternal.hlsl" diff --git a/Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl b/Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl index 3dfcbe0e..4f9b5bf0 100644 --- a/Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl +++ b/Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl @@ -73,6 +73,18 @@ UnityTexture2D UnityBuildTexture2DStructInternal(TEXTURE2D_PARAM(tex, samplersta return result; } +#define UnityBuildTexture2DStructNoTexelSize(n) UnityBuildTexture2DStructNoTexelSizeInternal(TEXTURE2D_ARGS(n, sampler##n), n##_ST) +#define UnityBuildTexture2DStructNoScaleNoTexelSize(n) UnityBuildTexture2DStructNoTexelSizeInternal(TEXTURE2D_ARGS(n, sampler##n), float4(1, 1, 0, 0)) +UnityTexture2D UnityBuildTexture2DStructNoTexelSizeInternal(TEXTURE2D_PARAM(tex, samplerstate), float4 scaleTranslate) +{ + UnityTexture2D result; + result.tex = tex; + result.samplerstate = samplerstate; + result.texelSize = float4(1, 1, 1, 1); + result.scaleTranslate = scaleTranslate; + return result; +} + struct UnityTexture2DArray { diff --git a/Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl b/Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl index 5e3b93f9..3acb16aa 100644 --- a/Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl +++ b/Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl @@ -451,7 +451,7 @@ float4 ApplyTextureType(float4 value, int textureType) // NOTE: when textureType is a compile-time constant, the branches compile out if (textureType == TEXTURETYPE_NORMALTANGENTSPACE) { - value.rgb = UnpackNormalmapRGorAG(value); + value.rgb = UnpackNormalMapRGorAG(value); } else if (textureType == TEXTURETYPE_NORMALOBJECTSPACE) { diff --git a/Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureXR.hlsl b/Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureXR.hlsl index 0927aa67..5200189d 100644 --- a/Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureXR.hlsl +++ b/Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureXR.hlsl @@ -107,7 +107,7 @@ #define GATHER_GREEN_TEXTURE2D_X GATHER_GREEN_TEXTURE2D #define GATHER_BLUE_TEXTURE2D_X GATHER_BLUE_TEXTURE2D #define GATHER_ALPHA_TEXTURE2D_X GATHER_ALPHA_TEXTURE2D -#endif +#endif //defined(USE_TEXTURE2D_X_AS_ARRAY) // see Unity\Shaders\Includes\UnityShaderVariables.cginc for impl used by the C++ renderer #if defined(USING_STEREO_MATRICES) && defined(UNITY_STEREO_INSTANCING_ENABLED) @@ -128,4 +128,104 @@ #define UNITY_STEREO_ASSIGN_COMPUTE_EYE_INDEX UNITY_XR_ASSIGN_VIEW_INDEX #endif +#if defined(SHADER_API_METAL) && defined(UNITY_NEEDS_RENDERPASS_FBFETCH_FALLBACK) + // Special metal fallback (allows branching per input to texture load or proper fbf) + +#if defined(USE_TEXTURE2D_X_AS_ARRAY) + +#define RENDERPASS_DECLARE_FALLBACK_X(T, idx) \ + Texture2DArray _UnityFBInput##idx; float4 _UnityFBInput##idx##_TexelSize; \ + inline T ReadFBInput_##idx(bool var, uint2 coord) { \ + [branch]if(var) { return hlslcc_fbinput_##idx; } \ + else { return _UnityFBInput##idx.Load(uint4(coord, SLICE_ARRAY_INDEX, 0)); } \ + } + +#define FRAMEBUFFER_INPUT_X_HALF(idx) cbuffer hlslcc_SubpassInput_f_##idx { half4 hlslcc_fbinput_##idx; bool hlslcc_fbfetch_##idx; }; \ + RENDERPASS_DECLARE_FALLBACK_X(half4, idx) + +#define FRAMEBUFFER_INPUT_X_FLOAT(idx) cbuffer hlslcc_SubpassInput_f_##idx { float4 hlslcc_fbinput_##idx; bool hlslcc_fbfetch_##idx; }; \ + RENDERPASS_DECLARE_FALLBACK_X(float4, idx) + +#define FRAMEBUFFER_INPUT_X_INT(idx) cbuffer hlslcc_SubpassInput_f_##idx { int4 hlslcc_fbinput_##idx; bool hlslcc_fbfetch_##idx; }; \ + RENDERPASS_DECLARE_FALLBACK_X(int4, idx) + +#define FRAMEBUFFER_INPUT_X_UINT(idx) cbuffer hlslcc_SubpassInput_f_##idx { uint4 hlslcc_fbinput_##idx; bool hlslcc_fbfetch_##idx; }; \ + RENDERPASS_DECLARE_FALLBACK_X(uint4, idx) + +#define LOAD_FRAMEBUFFER_INPUT_X(idx, v2fname) ReadFBInput_##idx(hlslcc_fbfetch_##idx, uint2(v2fname.xy)) + + +#define RENDERPASS_DECLARE_FALLBACK_MS_X(T, idx) \ + Texture2DMSArray _UnityFBInput##idx; float4 _UnityFBInput##idx##_TexelSize; \ + inline T ReadFBInput_##idx(bool var, uint2 coord, uint sampleIdx) { \ + [branch]if(var) { return hlslcc_fbinput_##idx[sampleIdx]; } \ + else { return _UnityFBInput##idx.Load(uint3(coord, SLICE_ARRAY_INDEX), sampleIdx); } \ + } + +#define FRAMEBUFFER_INPUT_X_FLOAT_MS(idx) \ + cbuffer hlslcc_SubpassInput_F_##idx { float4 hlslcc_fbinput_##idx[8]; bool hlslcc_fbfetch_##idx; }; \ + RENDERPASS_DECLARE_FALLBACK_MS_X(float4, idx) + +#define FRAMEBUFFER_INPUT_X_HALF_MS(idx) \ + cbuffer hlslcc_SubpassInput_H_##idx { half4 hlslcc_fbinput_##idx[8]; bool hlslcc_fbfetch_##idx; }; \ + RENDERPASS_DECLARE_FALLBACK_MS_X(half4, idx) + +#define FRAMEBUFFER_INPUT_X_INT_MS(idx) \ + cbuffer hlslcc_SubpassInput_I_##idx { int4 hlslcc_fbinput_##idx[8]; bool hlslcc_fbfetch_##idx; }; \ + RENDERPASS_DECLARE_FALLBACK_MS_X(int4, idx) + +#define FRAMEBUFFER_INPUT_X_UINT_MS(idx) \ + cbuffer hlslcc_SubpassInput_U_##idx { uint4 hlslcc_fbinput_##idx[8]; bool hlslcc_fbfetch_##idx; }; \ + UNITY_RENDERPASS_DECLARE_FALLBACK_MS_X(uint4, idx) + +#define LOAD_FRAMEBUFFER_INPUT_X_MS(idx, sampleIdx, v2fname) ReadFBInput_##idx(hlslcc_fbfetch_##idx, uint2(v2fname.xy), sampleIdx) + +#else + // X is just 2D texture so just use the existing macros that have all the metal magic for regular 2D textures + #define FRAMEBUFFER_INPUT_X_HALF(idx) FRAMEBUFFER_INPUT_HALF(idx) + #define FRAMEBUFFER_INPUT_X_FLOAT(idx) FRAMEBUFFER_INPUT_FLOAT(idx) + #define FRAMEBUFFER_INPUT_X_INT(idx) FRAMEBUFFER_INPUT_INT(idx) + #define FRAMEBUFFER_INPUT_X_UINT(idx) FRAMEBUFFER_INPUT_UINT(idx) + #define LOAD_FRAMEBUFFER_INPUT_X(idx, v2fname) LOAD_FRAMEBUFFER_INPUT(idx, v2fname) + + #define FRAMEBUFFER_INPUT_X_HALF_MS(idx) FRAMEBUFFER_INPUT_HALF_MS(idx) + #define FRAMEBUFFER_INPUT_X_FLOAT_MS(idx) FRAMEBUFFER_INPUT_FLOAT_MS(idx) + #define FRAMEBUFFER_INPUT_X_INT_MS(idx) FRAMEBUFFER_INPUT_INT_MS(idx) + #define FRAMEBUFFER_INPUT_X_UINT_MS(idx) FRAMEBUFFER_INPUT_UINT_MS(idx) + #define LOAD_FRAMEBUFFER_INPUT_X_MS(idx, sampleIdx, v2fvertexname) LOAD_FRAMEBUFFER_INPUT_MS(idx, sampleIdx, v2fvertexname) + +#endif //defined(USE_TEXTURE2D_X_AS_ARRAY) + +#elif !defined(PLATFORM_SUPPORTS_NATIVE_RENDERPASS) + + // Use regular texture loads as a fallback these can be either 2d or array depending on the TEXTURE2D_X (USE_TEXTURE2D_X_AS_ARRAY) macros +#define FRAMEBUFFER_INPUT_X_HALF(idx) TEXTURE2D_X_HALF(_UnityFBInput##idx); float4 _UnityFBInput##idx##_TexelSize +#define FRAMEBUFFER_INPUT_X_FLOAT(idx) TEXTURE2D_X_FLOAT(_UnityFBInput##idx); float4 _UnityFBInput##idx##_TexelSize +#define FRAMEBUFFER_INPUT_X_INT(idx) TEXTURE2D_X_INT(_UnityFBInput##idx); float4 _UnityFBInput##idx##_TexelSize +#define FRAMEBUFFER_INPUT_X_UINT(idx) TEXTURE2D_X_UINT(_UnityFBInput##idx); float4 _UnityFBInput##idx##_TexelSize +#define LOAD_FRAMEBUFFER_INPUT_X(idx, v2fvertexname) LOAD_TEXTURE2D_X(_UnityFBInput##idx,v2fvertexname.xy) + +#define FRAMEBUFFER_INPUT_X_FLOAT_MS(idx) TEXTURE2D_X_MSAA(float4, _UnityFBInput##idx); float4 _UnityFBInput##idx##_TexelSize +#define FRAMEBUFFER_INPUT_X_HALF_MS(idx) TEXTURE2D_X_MSAA(float4, _UnityFBInput##idx); float4 _UnityFBInput##idx##_TexelSize +#define FRAMEBUFFER_INPUT_X_INT_MS(idx) TEXTURE2D_X_MSAA(int4, _UnityFBInput##idx); float4 _UnityFBInput##idx##_TexelSize +#define FRAMEBUFFER_INPUT_X_UINT_MS(idx) TEXTURE2D_X_MSAA(uint4, _UnityFBInput##idx); float4 _UnityFBInput##idx##_TexelSize +#define LOAD_FRAMEBUFFER_INPUT_X_MS(idx, sampleIdx, v2fvertexname) LOAD_TEXTURE2D_X_MSAA(_UnityFBInput##idx, v2fvertexname.xy, sampleIdx) + +#else + + // Proper fbf, it will automatically ensure the correct eye is fb-fetched so we do not care if USE_TEXTURE2D_X_AS_ARRAY is enabled or not +#define FRAMEBUFFER_INPUT_X_HALF(idx) FRAMEBUFFER_INPUT_HALF(idx) +#define FRAMEBUFFER_INPUT_X_FLOAT(idx) FRAMEBUFFER_INPUT_FLOAT(idx) +#define FRAMEBUFFER_INPUT_X_INT(idx) FRAMEBUFFER_INPUT_INT(idx) +#define FRAMEBUFFER_INPUT_X_UINT(idx) FRAMEBUFFER_INPUT_UINT(idx) +#define LOAD_FRAMEBUFFER_INPUT_X(idx, v2fname) LOAD_FRAMEBUFFER_INPUT(idx, v2fname) + +#define FRAMEBUFFER_INPUT_X_HALF_MS(idx) FRAMEBUFFER_INPUT_HALF_MS(idx) +#define FRAMEBUFFER_INPUT_X_FLOAT_MS(idx) FRAMEBUFFER_INPUT_FLOAT_MS(idx) +#define FRAMEBUFFER_INPUT_X_INT_MS(idx) FRAMEBUFFER_INPUT_INT_MS(idx) +#define FRAMEBUFFER_INPUT_X_UINT_MS(idx) FRAMEBUFFER_INPUT_UINT_MS(idx) +#define LOAD_FRAMEBUFFER_INPUT_X_MS(idx, sampleIdx, v2fvertexname) LOAD_FRAMEBUFFER_INPUT_MS(idx, sampleIdx, v2fname) + +#endif //!defined(PLATFORM_SUPPORTS_NATIVE_RENDERPASS) + #endif // UNITY_TEXTUREXR_INCLUDED diff --git a/Packages/com.unity.render-pipelines.core/Shaders/CoreCopy.shader b/Packages/com.unity.render-pipelines.core/Shaders/CoreCopy.shader index e799f4ed..dc6870af 100644 --- a/Packages/com.unity.render-pipelines.core/Shaders/CoreCopy.shader +++ b/Packages/com.unity.render-pipelines.core/Shaders/CoreCopy.shader @@ -14,22 +14,45 @@ Shader "Hidden/CoreSRP/CoreCopy" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureXR.hlsl" - #include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl" - + #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/UnityInstancing.hlsl" + + #pragma multi_compile_fragment _ DISABLE_TEXTURE2D_X_ARRAY #pragma vertex Vert #pragma fragment CopyFrag // Declares the framebuffer input as a texture 2d containing half. - FRAMEBUFFER_INPUT_FLOAT(0); + FRAMEBUFFER_INPUT_X_FLOAT(0); + + struct Attributes + { + uint vertexID : SV_VertexID; + UNITY_VERTEX_INPUT_INSTANCE_ID + }; + + struct Varyings + { + float4 positionCS : SV_POSITION; + UNITY_VERTEX_OUTPUT_STEREO + }; + + Varyings Vert(Attributes input) + { + Varyings output; + UNITY_SETUP_INSTANCE_ID(input); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); + + output.positionCS = GetFullScreenTriangleVertexPosition(input.vertexID); + return output; + } // Out frag function takes as input a struct that contains the screen space coordinate we are going to use to sample our texture. It also writes to SV_Target0, this has to match the index set in the UseTextureFragment(sourceTexture, 0, …) we defined in our render pass script. float4 CopyFrag(Varyings input) : SV_Target0 - { - // read the current pixel from the framebuffer - float2 uv = input.texcoord.xy; + { + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + // read previous subpasses directly from the framebuffer. - half4 color = LOAD_FRAMEBUFFER_INPUT(0, input.positionCS.xy); + half4 color = LOAD_FRAMEBUFFER_INPUT_X(0, input.positionCS.xy); // Modify the sampled color return color; @@ -49,23 +72,46 @@ Shader "Hidden/CoreSRP/CoreCopy" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureXR.hlsl" - #include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl" + #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/UnityInstancing.hlsl" + #pragma multi_compile_fragment _ DISABLE_TEXTURE2D_X_ARRAY #pragma vertex Vert #pragma fragment CopyFragMS #pragma target 4.5 #pragma require msaatex // Declares the framebuffer input as a texture 2d containing half. - FRAMEBUFFER_INPUT_FLOAT_MS(0); + FRAMEBUFFER_INPUT_X_FLOAT_MS(0); + + struct Attributes + { + uint vertexID : SV_VertexID; + UNITY_VERTEX_INPUT_INSTANCE_ID + }; + + struct Varyings + { + float4 positionCS : SV_POSITION; + UNITY_VERTEX_OUTPUT_STEREO + }; + + Varyings Vert(Attributes input) + { + Varyings output; + UNITY_SETUP_INSTANCE_ID(input); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); + + output.positionCS = GetFullScreenTriangleVertexPosition(input.vertexID); + return output; + } // Out frag function takes as input a struct that contains the screen space coordinate we are going to use to sample our texture. It also writes to SV_Target0, this has to match the index set in the UseTextureFragment(sourceTexture, 0, …) we defined in our render pass script. float4 CopyFragMS(Varyings input, uint sampleID : SV_SampleIndex) : SV_Target0 { - // read the current pixel from the framebuffer - float2 uv = input.texcoord.xy; + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + // read previous subpasses directly from the framebuffer. - half4 color = LOAD_FRAMEBUFFER_INPUT_MS(0, sampleID, input.positionCS.xy); + half4 color = LOAD_FRAMEBUFFER_INPUT_X_MS(0, sampleID, input.positionCS.xy); // Modify the sampled color return color; diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/AssemblyInfo.cs b/Packages/com.unity.render-pipelines.core/Tests/Editor/AssemblyInfo.cs new file mode 100644 index 00000000..21d14073 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/AssemblyInfo.cs @@ -0,0 +1,3 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("SRPSmoke.Editor.Tests")] diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/AssemblyInfo.cs.meta b/Packages/com.unity.render-pipelines.core/Tests/Editor/AssemblyInfo.cs.meta new file mode 100644 index 00000000..e8c59f80 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/AssemblyInfo.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 79d9da7a81239e744bc809717c68ae47 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/GPUDriven/GPUDrivenRenderingUtils.cs b/Packages/com.unity.render-pipelines.core/Tests/Editor/GPUDriven/GPUDrivenRenderingUtils.cs index cf274f29..c6a6ade5 100644 --- a/Packages/com.unity.render-pipelines.core/Tests/Editor/GPUDriven/GPUDrivenRenderingUtils.cs +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/GPUDriven/GPUDrivenRenderingUtils.cs @@ -1,9 +1,9 @@ using System; using Unity.Collections; +using System.Collections.Generic; using Unity.Collections.LowLevel.Unsafe; using UnityEngine.Assertions; using Unity.Mathematics; -using System.Collections.Generic; namespace UnityEngine.Rendering.Tests { @@ -199,7 +199,7 @@ namespace UnityEngine.Rendering.Tests renderContext.Submit(); } - protected override void Render(ScriptableRenderContext renderContext, Camera[] cameras) + protected override void Render(ScriptableRenderContext renderContext, List cameras) { foreach (var camera in cameras) { diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/NativePassCompilerRenderGraphTests.cs b/Packages/com.unity.render-pipelines.core/Tests/Editor/NativePassCompilerRenderGraphTests.cs index 07eabca3..622b7f25 100644 --- a/Packages/com.unity.render-pipelines.core/Tests/Editor/NativePassCompilerRenderGraphTests.cs +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/NativePassCompilerRenderGraphTests.cs @@ -2,6 +2,7 @@ using NUnit.Framework; using System; using System.Collections.Generic; using UnityEngine.Experimental.Rendering; +using UnityEngine.Profiling; using UnityEngine.Rendering.RenderGraphModule; using UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler; @@ -9,6 +10,8 @@ namespace UnityEngine.Rendering.Tests { class NativePassCompilerRenderGraphTests { + static Recorder gcAllocRecorder = Recorder.Get("GC.Alloc"); + class RenderGraphTestPassData { public TextureHandle[] textures = new TextureHandle[8]; @@ -293,6 +296,183 @@ namespace UnityEngine.Rendering.Tests Assert.AreEqual(Rendering.RenderGraphModule.NativeRenderPassCompiler.PassBreakReason.DifferentDepthTextures, passes[0].breakAudit.reason); } + [Test] + public void MergePassWithWriteAllPass() + { + var g = AllocateRenderGraph(); + + var buffers = ImportAndCreateBuffers(g); + + // Render something to depth + using (var builder = g.AddRasterRenderPass("TestPass0", out var passData)) + { + builder.SetRenderAttachmentDepth(buffers.depthBuffer, AccessFlags.Write); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); + } + // Merge pass, render with WriteAll in extra 0 + using (var builder = g.AddRasterRenderPass("TestPass1", out var passData)) + { + builder.SetRenderAttachment(buffers.extraBuffers[0], 0, AccessFlags.WriteAll); + builder.SetRenderAttachmentDepth(buffers.depthBuffer, AccessFlags.Write); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); + } + + var result = g.CompileNativeRenderGraph(g.ComputeGraphHash()); + var passes = result.contextData.GetNativePasses(); + + Assert.AreEqual(1, passes.Count); + Assert.AreEqual(2, passes[0].numGraphPasses); + + // Validate attachments + Assert.AreEqual(buffers.depthBuffer.handle.index, passes[0].attachments[0].handle.index); + Assert.AreEqual(buffers.extraBuffers[0].handle.index, passes[0].attachments[1].handle.index); + + ref var depthAttachment = ref passes[0].attachments[0]; + Assert.AreEqual(RenderBufferLoadAction.Load, depthAttachment.loadAction); + + ref var extraAttachment = ref passes[0].attachments[1]; + Assert.AreEqual(RenderBufferLoadAction.DontCare, extraAttachment.loadAction); + } + + [Test] + public void MergeWriteAllPassWithReadPass() + { + var g = AllocateRenderGraph(); + + var buffers = ImportAndCreateBuffers(g); + + // Render something to extra 0 + using (var builder = g.AddRasterRenderPass("TestPass0", out var passData)) + { + builder.SetRenderAttachmentDepth(buffers.depthBuffer, AccessFlags.Write); + builder.SetRenderAttachment(buffers.extraBuffers[0], 0, AccessFlags.WriteAll); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); + } + // Read from extra 0 + using (var builder = g.AddRasterRenderPass("TestPass1", out var passData)) + { + builder.SetRenderAttachmentDepth(buffers.depthBuffer, AccessFlags.Write); + builder.SetInputAttachment(buffers.extraBuffers[0], 0, AccessFlags.Read); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); + } + + var result = g.CompileNativeRenderGraph(g.ComputeGraphHash()); + var passes = result.contextData.GetNativePasses(); + + Assert.AreEqual(1, passes.Count); + Assert.AreEqual(2, passes[0].numGraphPasses); + + // Validate attachments + Assert.AreEqual(buffers.depthBuffer.handle.index, passes[0].attachments[0].handle.index); + Assert.AreEqual(buffers.extraBuffers[0].handle.index, passes[0].attachments[1].handle.index); + + ref var depthAttachment = ref passes[0].attachments[0]; + Assert.AreEqual(RenderBufferLoadAction.Load, depthAttachment.loadAction); + + ref var extraAttachment = ref passes[0].attachments[1]; + Assert.AreEqual(RenderBufferLoadAction.DontCare, extraAttachment.loadAction); + } + + [Test] + public void MergeReadPassWithWriteAllPass() + { + var g = AllocateRenderGraph(); + + var buffers = ImportAndCreateBuffers(g); + + // Render something to 0,1 + using (var builder = g.AddRasterRenderPass("TestPass0", out var passData)) + { + builder.SetRenderAttachmentDepth(buffers.depthBuffer, AccessFlags.Write); + builder.SetRenderAttachment(buffers.extraBuffers[0], 0, AccessFlags.Read); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); + } + // Render to final buffer + using (var builder = g.AddRasterRenderPass("TestPass1", out var passData)) + { + builder.SetRenderAttachmentDepth(buffers.depthBuffer, AccessFlags.Write); + builder.SetRenderAttachment(buffers.extraBuffers[0], 0, AccessFlags.WriteAll); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); + } + + var result = g.CompileNativeRenderGraph(g.ComputeGraphHash()); + var passes = result.contextData.GetNativePasses(); + + Assert.AreEqual(1, passes.Count); + Assert.AreEqual(2, passes[0].numGraphPasses); + + // Validate attachments + Assert.AreEqual(buffers.depthBuffer.handle.index, passes[0].attachments[0].handle.index); + Assert.AreEqual(buffers.extraBuffers[0].handle.index, passes[0].attachments[1].handle.index); + + ref var depthAttachment = ref passes[0].attachments[0]; + Assert.AreEqual(RenderBufferLoadAction.Load, depthAttachment.loadAction); + + // LoadAction is Clear because it was not used by another pass before, in other case it should be Load + ref var extraAttachment = ref passes[0].attachments[1]; + Assert.AreEqual(RenderBufferLoadAction.Clear, extraAttachment.loadAction); + } + + [Test] + public void MergeDiscardPassWithWrite() + { + var g = AllocateRenderGraph(); + + var buffers = ImportAndCreateBuffers(g); + + // Discard extra 0 + using (var builder = g.AddRasterRenderPass("TestPass0", out var passData)) + { + builder.SetRenderAttachmentDepth(buffers.depthBuffer, AccessFlags.Write); + builder.SetRenderAttachment(buffers.extraBuffers[0], 0, AccessFlags.Discard); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); + } + // Read extra 0 + using (var builder = g.AddRasterRenderPass("TestPass1", out var passData)) + { + builder.SetRenderAttachmentDepth(buffers.depthBuffer, AccessFlags.Write); + builder.SetRenderAttachment(buffers.extraBuffers[0], 0, AccessFlags.Read); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); + } + // Write to extra 0 + using (var builder = g.AddRasterRenderPass("TestPass2", out var passData)) + { + builder.SetRenderAttachmentDepth(buffers.depthBuffer, AccessFlags.Write); + builder.SetRenderAttachment(buffers.extraBuffers[0], 0, AccessFlags.Write); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); + } + // break pass using another depth, Read extra 0 + using (var builder = g.AddRasterRenderPass("TestPass1", out var passData)) + { + builder.SetRenderAttachmentDepth(buffers.extraDepthBuffer, AccessFlags.Write); + builder.SetRenderAttachment(buffers.extraBuffers[0], 0, AccessFlags.Read); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); + } + + var result = g.CompileNativeRenderGraph(g.ComputeGraphHash()); + var passes = result.contextData.GetNativePasses(); + + Assert.AreEqual(2, passes.Count); + Assert.AreEqual(3, passes[0].numGraphPasses); + + // Validate attachments + Assert.AreEqual(buffers.depthBuffer.handle.index, passes[0].attachments[0].handle.index); + Assert.AreEqual(buffers.extraBuffers[0].handle.index, passes[0].attachments[1].handle.index); + Assert.AreEqual(buffers.extraBuffers[0].handle.index, passes[1].attachments[1].handle.index); + + ref var depthAttachment = ref passes[0].attachments[0]; + Assert.AreEqual(RenderBufferLoadAction.Load, depthAttachment.loadAction); + + // As we have a discard flag in the pass the LoadAction is DontCare, but as it has also a Write flag it should Store the result for the next pass + ref var extraAttachmentPass0 = ref passes[0].attachments[1]; + Assert.AreEqual(RenderBufferLoadAction.DontCare, extraAttachmentPass0.loadAction); + Assert.AreEqual(RenderBufferStoreAction.Store, extraAttachmentPass0.storeAction); + + ref var extraAttachmentPass1 = ref passes[1].attachments[1]; + Assert.AreEqual(RenderBufferLoadAction.Load, extraAttachmentPass1.loadAction); + + } + [Test] public void VerifyMergeStateAfterMergingPasses() { @@ -1143,5 +1323,96 @@ namespace UnityEngine.Rendering.Tests Assert.IsTrue(firstNativePass.numGraphPasses == 2); } + + [Test] + public void DecreaseResourceVersionIfLastPassIsCulled() + { + var g = AllocateRenderGraph(); + var buffers = ImportAndCreateBuffers(g); + + // Bumping version of extraBuffer within RG to 1 as we write to it in first pass + using (var builder = g.AddRasterRenderPass("TestPass0", out var passData)) + { + builder.SetRenderAttachment(buffers.extraBuffers[0], 0); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); + builder.AllowPassCulling(false); + } + + // Bumping version of extraBuffer within RG to 2 as we write to it in second pass + using (var builder = g.AddRasterRenderPass("TestPass1", out var passData)) + { + builder.SetRenderAttachment(buffers.extraBuffers[0], 0); + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); + builder.AllowPassCulling(true); + } + + // First pass is preserved as requested but second pass is culled + var result = g.CompileNativeRenderGraph(g.ComputeGraphHash()); + var passes = result.contextData.GetNativePasses(); + + // Second pass has been culled + Assert.IsTrue(passes != null && passes.Count == 1 && passes[0].numGraphPasses == 1); + // extraBuffer version has decreased to 1 as it is only used by the first pass + Assert.AreEqual(passes[0].attachments[0].handle.version, 1); + } + + [Test] + public void GraphPassesDoesNotAlloc() + { + var g = AllocateRenderGraph(); + using (var builder = g.AddRasterRenderPass("TestPass0", out var passData)) + { + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); + builder.AllowPassCulling(false); + } + using (var builder = g.AddRasterRenderPass("TestPass1_Culled", out var passData)) + { + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); + builder.AllowPassCulling(true); + } + using (var builder = g.AddRasterRenderPass("TestPass2", out var passData)) + { + builder.SetRenderFunc((RenderGraphTestPassData data, RasterGraphContext context) => { }); + builder.AllowPassCulling(false); + } + + // First pass is preserved as requested but second pass is culled + var result = g.CompileNativeRenderGraph(g.ComputeGraphHash()); + var passes = result.contextData.GetNativePasses(); + + // Second pass has been culled + Assert.IsTrue(passes != null && passes.Count == 1 && passes[0].numGraphPasses == 2); + // Goes into possible alloc path + Assert.IsFalse(passes[0].lastGraphPass - passes[0].firstGraphPass + 1 == passes[0].numGraphPasses); + + + ValidateNoGCAllocs(() => + { + passes[0].GraphPasses(result.contextData); + }); + + // From RenderPassCullingTests.cs + void ValidateNoGCAllocs(Action action) + { + // Warmup - this will catch static c'tors etc. + CountGCAllocs(action); + + // Actual test. + var count = CountGCAllocs(action); + if (count != 0) + throw new AssertionException($"Expected 0 GC allocations but there were {count}"); + } + + int CountGCAllocs(Action action) + { + gcAllocRecorder.FilterToCurrentThread(); + gcAllocRecorder.enabled = true; + + action(); + + gcAllocRecorder.enabled = false; + return gcAllocRecorder.sampleBlockCount; + } + } } } diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/RenderGraph.ComputeGraphHash.cs b/Packages/com.unity.render-pipelines.core/Tests/Editor/RenderGraph.ComputeGraphHash.cs new file mode 100644 index 00000000..2173abae --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/RenderGraph.ComputeGraphHash.cs @@ -0,0 +1,447 @@ +using NUnit.Framework; +using UnityEngine.Experimental.Rendering; +using UnityEngine.Rendering.RenderGraphModule; + +namespace UnityEngine.Rendering.Tests +{ + partial class RenderGraphTests + { + class RegularMethodInRegularClass + { + public void RenderFunc(RenderGraphTestPassData data, RenderGraphContext context) + { + } + } + + static class StaticMethodInsideStaticClass + { + public static void RenderFunc(RenderGraphTestPassData data, RenderGraphContext context) + { + } + } + + class StaticMethodInsideRegularClass + { + public static void RenderFunc(RenderGraphTestPassData data, RenderGraphContext context) + { + } + + public static void RenderFunc2(RenderGraphTestPassData data, RenderGraphContext context) + { + } + } + + class StaticMethodInsideRegularClass2 + { + public static void RenderFunc(RenderGraphTestPassData data, RenderGraphContext context) + { + } + } + + void ClearCompiledGraphAndHash() + { + m_RenderGraph.ClearCurrentCompiledGraph(); + DelegateHashCodeUtils.ClearCache(); + } + + [Test] + public void ComputeGraphHash_WhenCalledMultipleTimes_CacheForDelegatesIsNotGrowingBetweenComputes() + { + //Method of the class instance + TextureHandle texture0 = m_RenderGraph.CreateTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }); + using (var builder = m_RenderGraph.AddRenderPass("TestPass0", out var passData)) + { + builder.UseColorBuffer(texture0, 0); + var firstInstance = new RegularMethodInRegularClass(); + builder.SetRenderFunc(firstInstance.RenderFunc); + } + + //Static method of the static class + TextureHandle texture1 = m_RenderGraph.CreateTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }); + using (var builder = m_RenderGraph.AddRenderPass("TestPass1", out var passData)) + { + builder.UseColorBuffer(texture1, 0); + builder.SetRenderFunc(StaticMethodInsideStaticClass.RenderFunc); + } + + //Lambdas with captured variable + TextureHandle texture2 = m_RenderGraph.CreateTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }); + using (var builder = m_RenderGraph.AddRenderPass("TestPass2", out var passData)) + { + builder.UseColorBuffer(texture2, 0); + builder.SetRenderFunc((data, context) => { Debug.Log(texture2.GetHashCode()); }); + } + + //Local method with captured variable + TextureHandle texture3 = m_RenderGraph.CreateTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }); + using (var builder = m_RenderGraph.AddRenderPass("TestPass3", out var passData)) + { + builder.UseColorBuffer(texture3, 0); + builder.SetRenderFunc(LocalMethod); + } + + void LocalMethod(RenderGraphTestPassData data, RenderGraphContext renderGraphContext) + { + Debug.Log(texture3.GetHashCode()); + } + + //Static method of the regular class + TextureHandle texture4 = m_RenderGraph.CreateTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }); + using (var builder = m_RenderGraph.AddRenderPass("TestPass4", out var passData)) + { + builder.UseColorBuffer(texture4, 0); + builder.SetRenderFunc(StaticMethodInsideRegularClass.RenderFunc); + } + + //Calculate delegate cache first time + m_RenderGraph.ComputeGraphHash(); + var initialCacheSize = DelegateHashCodeUtils.GetTotalCacheCount(); + + //Trigger multiple hash recalculations + m_RenderGraph.ComputeGraphHash(); + m_RenderGraph.ComputeGraphHash(); + m_RenderGraph.ComputeGraphHash(); + var cacheAfterMultipleCalculations = DelegateHashCodeUtils.GetTotalCacheCount(); + + Assert.That(initialCacheSize, Is.EqualTo(cacheAfterMultipleCalculations)); + } + + [Test] + public void ComputeGraphHash_WhenDifferentObjectsUsed_HashcodeIsDifferent() + { + RecordRenderGraph(m_RenderGraph, new RegularMethodInRegularClass()); + + var hash0 = m_RenderGraph.ComputeGraphHash(); + ClearCompiledGraphAndHash(); + + RecordRenderGraph(m_RenderGraph, new RegularMethodInRegularClass()); + + var hash1 = m_RenderGraph.ComputeGraphHash(); + ClearCompiledGraphAndHash(); + + Assert.AreNotEqual(hash0, hash1); + + void RecordRenderGraph(RenderGraph renderGraph, RegularMethodInRegularClass instance) + { + using var builder = m_RenderGraph.AddRenderPass("TestPass0", out var passData); + builder.SetRenderFunc(instance.RenderFunc); + } + } + + [Test] + public void ComputeGraphHash_WhenDifferentStaticMethodsWithTheSameNameUsed_HashcodeIsDifferent() + { + using (var builder = m_RenderGraph.AddRenderPass("TestPass0", out var passData)) + builder.SetRenderFunc(StaticMethodInsideRegularClass.RenderFunc); + + var hash0 = m_RenderGraph.ComputeGraphHash(); + ClearCompiledGraphAndHash(); + + using (var builder = m_RenderGraph.AddRenderPass("TestPass0", out var passData)) + builder.SetRenderFunc(StaticMethodInsideRegularClass2.RenderFunc); + + var hash1 = m_RenderGraph.ComputeGraphHash(); + ClearCompiledGraphAndHash(); + + Assert.AreNotEqual(hash0, hash1); + } + + [Test] + public void ComputeGraphHash_WhenManyDifferentPassesUsed_HashcodeIsDifferent() + { + using (var builder = m_RenderGraph.AddRenderPass("TestPass0", out var passData)) + { + } + + using (var builder = m_RenderGraph.AddRenderPass("TestPass1", out var passData)) + { + } + + using (var builder = m_RenderGraph.AddRenderPass("TestPass2", out var passData)) + { + } + + var hash0 = m_RenderGraph.ComputeGraphHash(); + ClearCompiledGraphAndHash(); + + using (var builder = m_RenderGraph.AddRenderPass("TestPass0", out var passData)) + { + } + + using (var builder = m_RenderGraph.AddRenderPass("TestPass1", out var passData)) + { + } + + var hash1 = m_RenderGraph.ComputeGraphHash(); + ClearCompiledGraphAndHash(); + + Assert.AreNotEqual(hash0, hash1); + } + + static TestCaseData[] s_TextureParametersCases = + { + new TestCaseData(new TextureDesc(Vector2.zero) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }, + new TextureDesc(Vector2.zero) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }, + true) + .SetName("All the Texture parameters are the same."), + new TestCaseData(new TextureDesc(Vector2.zero) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm, msaaSamples = MSAASamples.None }, + new TextureDesc(Vector2.zero) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm, msaaSamples = MSAASamples.MSAA4x }, + false) + .SetName("The msaaSamples parameter is different."), + new TestCaseData(new TextureDesc(256, 256) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }, + new TextureDesc(512, 512) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }, + false) + .SetName("The resolution parameter is different."), + new TestCaseData(new TextureDesc(Vector2.zero) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }, + new TextureDesc(Vector2.zero) { colorFormat = GraphicsFormat.R16G16B16_SInt }, + false) + .SetName("The colorFormat parameter is different."), + }; + + + [Test] + [TestCaseSource(nameof(s_TextureParametersCases))] + public void ComputeGraphHash_WithTextureParameters(TextureDesc first, TextureDesc second, bool hashCodeEquality) + { + RecordRenderGraph(m_RenderGraph, first); + + var hash0 = m_RenderGraph.ComputeGraphHash(); + ClearCompiledGraphAndHash(); + + RecordRenderGraph(m_RenderGraph, second); + + var hash1 = m_RenderGraph.ComputeGraphHash(); + ClearCompiledGraphAndHash(); + + Assert.That(hash0 == hash1, Is.EqualTo(hashCodeEquality)); + + void RecordRenderGraph(RenderGraph renderGraph, TextureDesc desc) + { + var texture0 = renderGraph.CreateTexture(desc); + using var builder = renderGraph.AddRenderPass("TestPass0", out var passData); + builder.UseColorBuffer(texture0, 0); + } + } + + //Lambda hashcode depends on the position in the code as they are generated by the compiler. + //They will be treated as separate methods in this case. + [Test] + public void ComputeGraphHash_WhenUsedLambdasDiffer_HashcodeIsDifferent() + { + using (var builder = m_RenderGraph.AddRenderPass("TestPass0", out var passData)) + builder.SetRenderFunc((_, _) => { }); + + var hash0 = m_RenderGraph.ComputeGraphHash(); + ClearCompiledGraphAndHash(); + + using (var builder = m_RenderGraph.AddRenderPass("TestPass0", out var passData)) + builder.SetRenderFunc((_, _) => { }); + + var hash1 = m_RenderGraph.ComputeGraphHash(); + ClearCompiledGraphAndHash(); + + Assert.AreNotEqual(hash0, hash1); + } + + [Test] + public void ComputeGraphHash_WhenUsedStaticMethodsDiffer_HashcodeIsDifferent() + { + using (var builder = m_RenderGraph.AddRenderPass("TestPass0", out var passData)) + builder.SetRenderFunc(StaticMethodInsideRegularClass.RenderFunc); + + var hash0 = m_RenderGraph.ComputeGraphHash(); + ClearCompiledGraphAndHash(); + + using (var builder = m_RenderGraph.AddRenderPass("TestPass0", out var passData)) + builder.SetRenderFunc(StaticMethodInsideRegularClass.RenderFunc2); + + var hash1 = m_RenderGraph.ComputeGraphHash(); + ClearCompiledGraphAndHash(); + + Assert.AreNotEqual(hash0, hash1); + } + + [Test] + public void ComputeGraphHashForTheSameSetup_WhenSamePassesUsed_HashcodeIsSame() + { + RecordRenderGraph(m_RenderGraph); + var hash0 = m_RenderGraph.ComputeGraphHash(); + ClearCompiledGraphAndHash(); + + RecordRenderGraph(m_RenderGraph); + var hash1 = m_RenderGraph.ComputeGraphHash(); + ClearCompiledGraphAndHash(); + + Assert.AreEqual(hash0, hash1); + + void RecordRenderGraph(RenderGraph renderGraph) + { + using (var builder = renderGraph.AddRenderPass("TestPass0", out var passData)) + { + } + + using (var builder = renderGraph.AddRenderPass("TestPass1", out var passData)) + { + } + + using (var builder = renderGraph.AddRenderPass("TestPass2", out var passData)) + { + } + } + } + + [Test] + public void ComputeGraphHashForTheSameSetup_WhenStaticsInStaticClassUsed_HashcodeIsSame() + { + using (var builder = m_RenderGraph.AddRenderPass("TestPass0", out var passData)) + builder.SetRenderFunc(StaticMethodInsideStaticClass.RenderFunc); + var hash0 = m_RenderGraph.ComputeGraphHash(); + ClearCompiledGraphAndHash(); + + using (var builder = m_RenderGraph.AddRenderPass("TestPass0", out var passData)) + builder.SetRenderFunc(StaticMethodInsideStaticClass.RenderFunc); + var hash1 = m_RenderGraph.ComputeGraphHash(); + ClearCompiledGraphAndHash(); + + Assert.AreEqual(hash0, hash1); + } + + [Test] + public void ComputeGraphHashForTheSameSetup_WhenStaticsInRegularClassUsed_HashcodeIsSame() + { + using (var builder = m_RenderGraph.AddRenderPass("TestPass0", out var passData)) + builder.SetRenderFunc(StaticMethodInsideRegularClass.RenderFunc); + var hash0 = m_RenderGraph.ComputeGraphHash(); + ClearCompiledGraphAndHash(); + + using (var builder = m_RenderGraph.AddRenderPass("TestPass0", out var passData)) + builder.SetRenderFunc(StaticMethodInsideRegularClass.RenderFunc); + var hash1 = m_RenderGraph.ComputeGraphHash(); + ClearCompiledGraphAndHash(); + + Assert.AreEqual(hash0, hash1); + } + + [Test] + public void ComputeGraphHashForTheSameSetup_WhenLambdasUsed_HashcodeIsSame() + { + RecordRenderGraph(m_RenderGraph); + + var hash0 = m_RenderGraph.ComputeGraphHash(); + ClearCompiledGraphAndHash(); + + RecordRenderGraph(m_RenderGraph); + + var hash1 = m_RenderGraph.ComputeGraphHash(); + ClearCompiledGraphAndHash(); + + Assert.AreEqual(hash0, hash1); + + static void RecordRenderGraph(RenderGraph renderGraph) + { + using (var builder = renderGraph.AddRenderPass("TestPass0", out var passData)) + builder.SetRenderFunc((p, c) => { }); + + using (var builder = renderGraph.AddRenderPass("TestPass1", out var passData)) + builder.SetRenderFunc((p, c) => { }); + + using (var builder = renderGraph.AddRenderPass("TestPass2", out var passData)) + builder.SetRenderFunc((p, c) => { }); + } + } + + [Test] + public void ComputeGraphHashForTheSameSetup_WhenLambdasWithCapturedVariablesUsed_HashcodeIsSame() + { + TextureHandle texture0 = m_RenderGraph.CreateTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }); + + RecordRenderGraph(m_RenderGraph, texture0); + + var hash0 = m_RenderGraph.ComputeGraphHash(); + ClearCompiledGraphAndHash(); + + RecordRenderGraph(m_RenderGraph, texture0); + + var hash1 = m_RenderGraph.ComputeGraphHash(); + ClearCompiledGraphAndHash(); + + Assert.AreEqual(hash0, hash1); + + void RecordRenderGraph(RenderGraph renderGraph, TextureHandle handle) + { + using var builder = m_RenderGraph.AddRenderPass("TestPass0", out var passData); + builder.SetRenderFunc((data, context) => + { + if (!handle.IsValid()) + return; + Debug.Log(handle.GetHashCode()); + }); + } + } + + [Test] + public void ComputeGraphHashForTheSameSetup_WhenLocalMethodsUsed_HashcodeIsSame() + { + RecordRenderGraph(m_RenderGraph); + + var hash0 = m_RenderGraph.ComputeGraphHash(); + ClearCompiledGraphAndHash(); + + RecordRenderGraph(m_RenderGraph); + var hash1 = m_RenderGraph.ComputeGraphHash(); + ClearCompiledGraphAndHash(); + + Assert.AreEqual(hash0, hash1); + + void RecordRenderGraph(RenderGraph renderGraph) + { + using (var builder = renderGraph.AddRenderPass("TestPass0", out var passData)) + builder.SetRenderFunc(LocalRenderFunc); + + using (var builder = renderGraph.AddRenderPass("TestPass1", out var passData)) + builder.SetRenderFunc(LocalRenderFunc); + + using (var builder = renderGraph.AddRenderPass("TestPass2", out var passData)) + builder.SetRenderFunc(LocalRenderFunc); + } + + void LocalRenderFunc(RenderGraphTestPassData data, RenderGraphContext renderGraphContext) + { + } + } + + [Test] + public void ComputeGraphHashForTheSameSetup_WhenLocalMethodsWithCapturedVariablesUsed_HashcodeIsSame() + { + RecordRenderGraph(m_RenderGraph); + + var hash0 = m_RenderGraph.ComputeGraphHash(); + ClearCompiledGraphAndHash(); + + RecordRenderGraph(m_RenderGraph); + + var hash1 = m_RenderGraph.ComputeGraphHash(); + ClearCompiledGraphAndHash(); + + Assert.AreEqual(hash0, hash1); + + void RecordRenderGraph(RenderGraph renderGraph) + { + var outerScopeVariable = "1"; + using (var builder = renderGraph.AddRenderPass("TestPass0", out var passData)) + builder.SetRenderFunc(LocalRenderFunc); + + outerScopeVariable = "2"; + using (var builder = renderGraph.AddRenderPass("TestPass1", out var passData)) + builder.SetRenderFunc(LocalRenderFunc); + + outerScopeVariable = "3"; + using (var builder = renderGraph.AddRenderPass("TestPass2", out var passData)) + builder.SetRenderFunc(LocalRenderFunc); + + void LocalRenderFunc(RenderGraphTestPassData data, RenderGraphContext renderGraphContext) + => Debug.Log(outerScopeVariable); + } + } + } +} diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/RenderGraph.ComputeGraphHash.cs.meta b/Packages/com.unity.render-pipelines.core/Tests/Editor/RenderGraph.ComputeGraphHash.cs.meta new file mode 100644 index 00000000..242ac651 --- /dev/null +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/RenderGraph.ComputeGraphHash.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 42aa68c398a54080bb27754435687636 +timeCreated: 1736444326 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/RenderGraphTests.cs b/Packages/com.unity.render-pipelines.core/Tests/Editor/RenderGraphTests.cs index e1684f47..c5d5fc6a 100644 --- a/Packages/com.unity.render-pipelines.core/Tests/Editor/RenderGraphTests.cs +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/RenderGraphTests.cs @@ -1,8 +1,8 @@ using NUnit.Framework; using System; +using System.Collections.Generic; using UnityEngine.Experimental.Rendering; using UnityEngine.Rendering.RenderGraphModule; -using System.Collections.Generic; using UnityEngine.TestTools; using Unity.Collections; @@ -29,7 +29,7 @@ namespace UnityEngine.Rendering.Tests } } - class RenderGraphTests + partial class RenderGraphTests { // For RG Record/Hash/Compile testing, use m_RenderGraph RenderGraph m_RenderGraph; @@ -41,6 +41,10 @@ namespace UnityEngine.Rendering.Tests RenderGraphTestPipelineAsset m_RenderGraphTestPipeline; RenderGraphTestGlobalSettings m_RenderGraphTestGlobalSettings; + // We need a camera to execute the render graph and a game object to attach a camera + GameObject m_GameObject; + Camera m_Camera; + // For the testing of the following RG steps: Execute and Submit (native) with camera rendering, use this custom RenderGraph render pipeline // through a camera render call to test the RG with a real ScriptableRenderContext class RenderGraphTestPipelineAsset : RenderPipelineAsset @@ -72,14 +76,14 @@ namespace UnityEngine.Rendering.Tests this.m_RenderGraph = asset.renderGraph; } - protected override void Render(ScriptableRenderContext renderContext, Camera[] cameras) + protected override void Render(ScriptableRenderContext renderContext, List cameras) { foreach (var camera in cameras) { if (!camera.enabled) continue; - var cmd = new CommandBuffer { name = "Rendering command buffer" }; + var cmd = CommandBufferPool.Get(); RenderGraphParameters rgParams = new() { @@ -96,6 +100,8 @@ namespace UnityEngine.Rendering.Tests m_RenderGraph.EndRecordingAndExecute(); renderContext.ExecuteCommandBuffer(cmd); + + CommandBufferPool.Release(cmd); } renderContext.Submit(); } @@ -128,6 +134,16 @@ namespace UnityEngine.Rendering.Tests // Getting the RG from the custom asset pipeline m_RenderGraph = m_RenderGraphTestPipeline.renderGraph; + + m_RenderGraph.nativeRenderPassesEnabled = true; + + // We need a real ScriptableRenderContext and a camera to execute the Render Graph + m_GameObject = new GameObject("testGameObject") + { + hideFlags = HideFlags.HideAndDontSave + }; + m_GameObject.tag = "MainCamera"; + m_Camera = m_GameObject.AddComponent(); } [OneTimeTearDown] @@ -147,12 +163,18 @@ namespace UnityEngine.Rendering.Tests EditorGraphicsSettings.SetRenderPipelineGlobalSettingsAsset(null); #endif Object.DestroyImmediate(m_RenderGraphTestGlobalSettings); + + GameObject.DestroyImmediate(m_GameObject); + m_GameObject = null; + m_Camera = null; } - [SetUp] - public void SetupRenderGraph() + [TearDown] + public void CleanupRenderGraph() { - m_RenderGraph.ClearCompiledGraph(); + // Cleaning all Render Graph resources and data structures + // Nothing remains, Render Graph in next test will start from scratch + m_RenderGraph.Cleanup(); } class RenderGraphTestPassData @@ -707,193 +729,6 @@ namespace UnityEngine.Rendering.Tests } } - [Test] - public void ComputeHashDifferentPerResolution() - { - static void RenderFunc(RenderGraphTestPassData data, RenderGraphContext context) { } - - TextureHandle texture0 = m_RenderGraph.CreateTexture(new TextureDesc(256, 256) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }); - - using (var builder = m_RenderGraph.AddRenderPass("TestPass0", out var passData)) - { - builder.UseColorBuffer(texture0, 0); - builder.SetRenderFunc(RenderFunc); - } - - var hash0 = m_RenderGraph.ComputeGraphHash(); - m_RenderGraph.ClearCompiledGraph(); - - TextureHandle texture1 = m_RenderGraph.CreateTexture(new TextureDesc(512, 512) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }); - - using (var builder = m_RenderGraph.AddRenderPass("TestPass0", out var passData)) - { - builder.UseColorBuffer(texture1, 0); - builder.SetRenderFunc(RenderFunc); - } - - var hash1 = m_RenderGraph.ComputeGraphHash(); - m_RenderGraph.ClearCompiledGraph(); - - Assert.AreNotEqual(hash0, hash1); - } - - [Test] - public void ComputeHashDifferentForMSAA() - { - static void RenderFunc(RenderGraphTestPassData data, RenderGraphContext context) { } - - TextureHandle texture0 = m_RenderGraph.CreateTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm, msaaSamples = MSAASamples.None }); - - using (var builder = m_RenderGraph.AddRenderPass("TestPass0", out var passData)) - { - builder.UseColorBuffer(texture0, 0); - builder.SetRenderFunc(RenderFunc); - } - - var hash0 = m_RenderGraph.ComputeGraphHash(); - m_RenderGraph.ClearCompiledGraph(); - - texture0 = m_RenderGraph.CreateTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm, msaaSamples = MSAASamples.MSAA4x }); - - using (var builder = m_RenderGraph.AddRenderPass("TestPass0", out var passData)) - { - builder.UseColorBuffer(texture0, 0); - builder.SetRenderFunc(RenderFunc); - } - - var hash1 = m_RenderGraph.ComputeGraphHash(); - m_RenderGraph.ClearCompiledGraph(); - - Assert.AreNotEqual(hash0, hash1); - } - - [Test] - public void ComputeHashDifferentForRenderFunc() - { - static void RenderFunc(RenderGraphTestPassData data, RenderGraphContext context) { } - static void RenderFunc2(RenderGraphTestPassData data, RenderGraphContext context) { } - - TextureHandle texture0 = m_RenderGraph.CreateTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }); - - using (var builder = m_RenderGraph.AddRenderPass("TestPass0", out var passData)) - { - builder.UseColorBuffer(texture0, 0); - builder.SetRenderFunc(RenderFunc); - } - - var hash0 = m_RenderGraph.ComputeGraphHash(); - m_RenderGraph.ClearCompiledGraph(); - - texture0 = m_RenderGraph.CreateTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }); - - using (var builder = m_RenderGraph.AddRenderPass("TestPass0", out var passData)) - { - builder.UseColorBuffer(texture0, 0); - builder.SetRenderFunc(RenderFunc2); - } - - var hash1 = m_RenderGraph.ComputeGraphHash(); - m_RenderGraph.ClearCompiledGraph(); - - Assert.AreNotEqual(hash0, hash1); - } - - [Test] - public void ComputeHashDifferentForMorePasses() - { - static void RenderFunc(RenderGraphTestPassData data, RenderGraphContext context) { } - static void RenderFunc2(RenderGraphTestPassData data, RenderGraphContext context) { } - static void RenderFunc3(RenderGraphTestPassData data, RenderGraphContext context) { } - - TextureHandle texture0 = m_RenderGraph.CreateTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }); - - using (var builder = m_RenderGraph.AddRenderPass("TestPass0", out var passData)) - { - builder.UseColorBuffer(texture0, 0); - builder.SetRenderFunc(RenderFunc); - } - - using (var builder = m_RenderGraph.AddRenderPass("TestPass1", out var passData)) - { - builder.WriteTexture(m_RenderGraph.ImportBackbuffer(0)); - builder.ReadTexture(texture0); - builder.SetRenderFunc(RenderFunc2); - } - - var hash0 = m_RenderGraph.ComputeGraphHash(); - m_RenderGraph.ClearCompiledGraph(); - - texture0 = m_RenderGraph.CreateTexture(new TextureDesc(Vector2.one) { format = GraphicsFormat.R8G8B8A8_UNorm }); - - using (var builder = m_RenderGraph.AddRenderPass("TestPass0", out var passData)) - { - builder.UseColorBuffer(texture0, 0); - builder.SetRenderFunc(RenderFunc); - } - - using (var builder = m_RenderGraph.AddRenderPass("TestPass1", out var passData)) - { - builder.UseColorBuffer(texture0, 0); - builder.SetRenderFunc(RenderFunc3); - } - - using (var builder = m_RenderGraph.AddRenderPass("TestPass2", out var passData)) - { - builder.WriteTexture(m_RenderGraph.ImportBackbuffer(0)); - builder.ReadTexture(texture0); - builder.SetRenderFunc(RenderFunc2); - } - - var hash1 = m_RenderGraph.ComputeGraphHash(); - m_RenderGraph.ClearCompiledGraph(); - - Assert.AreNotEqual(hash0, hash1); - } - - [Test] - public void ComputeHashSameForOneSetup() - { - static void RenderFunc(RenderGraphTestPassData data, RenderGraphContext context) { } - static void RenderFunc2(RenderGraphTestPassData data, RenderGraphContext context) { } - static void RenderFunc3(RenderGraphTestPassData data, RenderGraphContext context) { } - - static void RecordRenderGraph(RenderGraph renderGraph) - { - TextureHandle texture0 = renderGraph.CreateTexture(new TextureDesc(Vector2.one) { format = GraphicsFormat.R8G8B8A8_UNorm }); - - using (var builder = renderGraph.AddRenderPass("TestPass0", out var passData)) - { - builder.UseColorBuffer(texture0, 0); - builder.SetRenderFunc(RenderFunc); - } - - using (var builder = renderGraph.AddRenderPass("TestPass1", out var passData)) - { - builder.UseColorBuffer(texture0, 0); - builder.SetRenderFunc(RenderFunc3); - } - - using (var builder = renderGraph.AddRenderPass("TestPass2", out var passData)) - { - builder.WriteTexture(renderGraph.ImportBackbuffer(0)); - builder.ReadTexture(texture0); - builder.SetRenderFunc(RenderFunc2); - } - } - - RecordRenderGraph(m_RenderGraph); - - var hash0 = m_RenderGraph.ComputeGraphHash(); - m_RenderGraph.ClearCompiledGraph(); - - RecordRenderGraph(m_RenderGraph); - - var hash1 = m_RenderGraph.ComputeGraphHash(); - m_RenderGraph.ClearCompiledGraph(); - - Assert.AreEqual(hash0, hash1); - } - [Test] public void GetDescAndInfoForImportedTextureWorks() { @@ -1030,16 +865,6 @@ namespace UnityEngine.Rendering.Tests [Test] public void CreateLegacyRendererLists() { - // We need a real ScriptableRenderContext and a camera to call correctly the legacy RendererLists API - - // add the default camera - var gameObject = new GameObject("testGameObject") - { - hideFlags = HideFlags.HideAndDontSave - }; - gameObject.tag = "MainCamera"; - var camera = gameObject.AddComponent(); - // record and execute render graph calls m_RenderGraphTestPipeline.recordRenderGraphBody = (context, camera, cmd) => { @@ -1061,27 +886,16 @@ namespace UnityEngine.Rendering.Tests rendererListHandle = m_RenderGraph.CreateSkyboxRendererList(camera, Matrix4x4.identity, Matrix4x4.identity, Matrix4x4.identity, Matrix4x4.identity); Assert.IsTrue(rendererListHandle.IsValid()); }; - camera.Render(); - - GameObject.DestroyImmediate(gameObject); + m_Camera.Render(); } [Test] public void RenderPassWithNoRenderFuncThrows() { - // We need a real ScriptableRenderContext and a camera to execute the render graph - // add the default camera - var gameObject = new GameObject("testGameObject") - { - hideFlags = HideFlags.HideAndDontSave - }; - gameObject.tag = "MainCamera"; - var camera = gameObject.AddComponent(); - // record and execute render graph calls m_RenderGraphTestPipeline.recordRenderGraphBody = (context, camera, cmd) => { - using (var builder = m_RenderGraph.AddRenderPass("TestPassWithNoRenderFunc", out var passData)) + using (var builder = m_RenderGraph.AddRasterRenderPass("TestPassWithNoRenderFunc", out var passData)) { builder.AllowPassCulling(false); @@ -1090,9 +904,7 @@ namespace UnityEngine.Rendering.Tests }; LogAssert.Expect(LogType.Error, "Render Graph Execution error"); LogAssert.Expect(LogType.Exception, "InvalidOperationException: RenderPass TestPassWithNoRenderFunc was not provided with an execute function."); - camera.Render(); - - GameObject.DestroyImmediate(gameObject); + m_Camera.Render(); } /* @@ -1167,15 +979,6 @@ namespace UnityEngine.Rendering.Tests const int kHeight = 4; const GraphicsFormat format = GraphicsFormat.R8G8B8A8_SRGB; - // We need a real ScriptableRenderContext and a camera to execute the render graph - // add the default camera - var gameObject = new GameObject("testGameObject") - { - hideFlags = HideFlags.HideAndDontSave, - tag = "MainCamera" - }; - var camera = gameObject.AddComponent(); - NativeArray pixels = default; bool passExecuted = false; @@ -1208,7 +1011,7 @@ namespace UnityEngine.Rendering.Tests } }; - camera.Render(); + m_Camera.Render(); AsyncGPUReadback.WaitAllRequests(); @@ -1223,7 +1026,6 @@ namespace UnityEngine.Rendering.Tests } pixels.Dispose(); - GameObject.DestroyImmediate(gameObject); } void RenderGraphTest_AsyncReadbackCallback(AsyncGPUReadbackRequest request) @@ -1286,14 +1088,6 @@ namespace UnityEngine.Rendering.Tests [Test, ConditionalIgnore("IgnoreGraphicsAPI", "Compute Shaders are not supported for this Graphics API.")] public void ImportingBufferWorks() { - // We need a real ScriptableRenderContext and a camera to execute the render graph - // add the default camera - var gameObject = new GameObject("testGameObject") - { - hideFlags = HideFlags.HideAndDontSave, - tag = "MainCamera" - }; - var camera = gameObject.AddComponent(); #if UNITY_EDITOR var computeShader = AssetDatabase.LoadAssetAtPath(kPathToComputeShader); #else @@ -1344,7 +1138,7 @@ namespace UnityEngine.Rendering.Tests } }; - camera.Render(); + m_Camera.Render(); // Read back the data from the buffer float[] result2 = new float[bufferSize]; @@ -1358,5 +1152,183 @@ namespace UnityEngine.Rendering.Tests Assert.IsTrue(result2[i] == 1.0f); } } + + class RenderGraphTransientTestData + { + public TextureHandle transientTexture; + public TextureHandle whiteTexture; + } + + private static readonly int k_DefaultWhiteTextureID = Shader.PropertyToID("_DefaultWhiteTex"); + + [Test] + public void TransientHandleAreValidatedByCommandBufferSafetyLayer() + { + m_RenderGraphTestPipeline.recordRenderGraphBody = (context, camera, cmd) => + { + using (var builder = m_RenderGraph.AddUnsafePass("TransientPass", out var passData)) + { + builder.AllowPassCulling(false); + + var texDesc = new TextureDesc(Vector2.one, false, false) + { + width = 1920, + height = 1080, + format = GraphicsFormat.B10G11R11_UFloatPack32, + clearBuffer = true, + clearColor = Color.red, + name = "Transient Texture" + }; + passData.transientTexture = builder.CreateTransientTexture(texDesc); + passData.whiteTexture = m_RenderGraph.defaultResources.whiteTexture; + + builder.SetRenderFunc((RenderGraphTransientTestData data, UnsafeGraphContext context) => + { + // Will ensure the transient texture is valid or throw an exception otherwise + Assert.DoesNotThrow(delegate { context.cmd.SetGlobalTexture(k_DefaultWhiteTextureID, data.transientTexture); }); + // Put back white instead + context.cmd.SetGlobalTexture(k_DefaultWhiteTextureID, data.whiteTexture); + }); + } + }; + + m_Camera.Render(); + } + + class TempAllocTestData + { + public TextureHandle whiteTexture; + } + + [Test] + public void GetTempMaterialPropertyBlockAreReleasedAfterRenderGraphNodeExecution() + { + m_RenderGraphTestPipeline.recordRenderGraphBody = (context, camera, cmd) => + { + using (var builder = m_RenderGraph.AddUnsafePass("MPBPass", out var passData)) + { + builder.AllowPassCulling(false); + passData.whiteTexture = m_RenderGraph.defaultResources.whiteTexture; + + builder.SetRenderFunc((TempAllocTestData data, UnsafeGraphContext context) => + { + // no temp alloc yet + Assert.IsTrue(context.renderGraphPool.IsEmpty()); + + var mpb = context.renderGraphPool.GetTempMaterialPropertyBlock(); + mpb.SetTexture(k_DefaultWhiteTextureID, data.whiteTexture); + + // memory temporarily allocated + Assert.IsFalse(context.renderGraphPool.IsEmpty()); + }); + } + + using (var builder = m_RenderGraph.AddUnsafePass("PostPass", out var passData)) + { + builder.AllowPassCulling(false); + + builder.SetRenderFunc((TempAllocTestData data, UnsafeGraphContext context) => + { + // memory has been deallocated at the end of the previous RG node, no leak + Assert.IsTrue(context.renderGraphPool.IsEmpty()); + }); + } + }; + + m_Camera.Render(); + } + + class RenderGraphCleanupTestData + { + public TextureHandle textureToRelease; + } + + [Test] + public void Cleanup_ReleaseGraphicsResources_WhenCallingCleanup() + { + // We need to capture this variable in the lambda function of the CleanupPass unfortunately + RenderTexture renderTextureToRemove = null; + + m_RenderGraphTestPipeline.recordRenderGraphBody = (context, camera, cmd) => + { + using (var builder = m_RenderGraph.AddUnsafePass("CleanupPass", out var passData)) + { + builder.AllowPassCulling(false); + + var texDesc = new TextureDesc(Vector2.one, false, false) + { + width = 1920, + height = 1080, + format = GraphicsFormat.B10G11R11_UFloatPack32, + clearBuffer = true, + clearColor = Color.red, + name = "Texture To Release" + }; + passData.textureToRelease = m_RenderGraph.CreateTexture(texDesc); + builder.UseTexture(passData.textureToRelease); + builder.SetRenderFunc((RenderGraphCleanupTestData data, UnsafeGraphContext context) => + { + // textureToRelease has been allocated before executing this node + + renderTextureToRemove = (RenderTexture)data.textureToRelease; + Assert.IsNotNull(renderTextureToRemove); + + // textureToRelease will returned to the texture pool after executing this node + }); + } + }; + + // Render Graph hasn't started yet, no texture allocated + Assert.IsNull(renderTextureToRemove); + + m_Camera.Render(); + + // Cleanup pass has been executed + // RG resource has been created and then released to the pool + // but the graphics resource has not been released, still attached to the pooled resource + // in case a next pass will reuse it + Assert.IsNotNull(renderTextureToRemove); + + m_RenderGraph.Cleanup(); + + // All RG resources and data structures have been released + Assert.IsTrue(renderTextureToRemove == null); + } + + [Test] + public void Cleanup_RenderAgain_AfterCallingCleanup() + { + m_RenderGraphTestPipeline.recordRenderGraphBody = (context, camera, cmd) => + { + using (var builder = m_RenderGraph.AddUnsafePass("MidCleanupPass", out var passData)) + { + builder.AllowPassCulling(false); + + var texDesc = new TextureDesc(Vector2.one, false, false) + { + width = 1920, + height = 1080, + format = GraphicsFormat.B10G11R11_UFloatPack32, + clearBuffer = true, + clearColor = Color.red, + name = "Texture To Release Twice" + }; + + passData.textureToRelease = m_RenderGraph.CreateTexture(texDesc); + builder.SetRenderFunc((RenderGraphCleanupTestData data, UnsafeGraphContext context) => + { + /// + }); + } + }; + + m_Camera.Render(); + + // Cleanup everything in Render Graph, even the native data structures + m_RenderGraph.Cleanup(); + + // Ensure that the Render Graph data structures can be reinitialized at runtime, even native ones + Assert.DoesNotThrow(() => m_Camera.Render()); + } } } diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/RenderGraphViewerTests.cs b/Packages/com.unity.render-pipelines.core/Tests/Editor/RenderGraphViewerTests.cs index ecfa37ce..411c21ec 100644 --- a/Packages/com.unity.render-pipelines.core/Tests/Editor/RenderGraphViewerTests.cs +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/RenderGraphViewerTests.cs @@ -4,6 +4,7 @@ using System.Reflection; using System.Runtime.CompilerServices; using NUnit.Framework; using UnityEngine; +using UnityEngine.UIElements; namespace UnityEditor.Rendering.Tests { @@ -76,5 +77,51 @@ namespace UnityEditor.Rendering.Tests } string GetCallerFilePath([CallerFilePath] string filePath = null) => filePath; + + static readonly Foldout k_FoldoutElement = new Foldout(); + static IEnumerable SearchFilterTestCases() + { + // To simplify the test, we use square brackets "[]" to indicate search match highlight. + string FormatWithSearchTag(string str) => + str.Replace("[", RenderGraphViewer.k_SelectionColorBeginTag).Replace("]", RenderGraphViewer.k_SelectionColorEndTag); + + TestCaseData MakeTestCase(string content, string searchString, string result, bool isMatch) + { + var dict = new Dictionary>(); + dict[k_FoldoutElement] = new List() { new() { text = content } }; + var testCase = new TestCaseData(dict, searchString, new List { FormatWithSearchTag(result) }, isMatch); + testCase.SetName($"Searching \"{content}\" for \"{searchString}\" results in \"{result}\" (match={isMatch})"); + return testCase; + } + + // Basic string matches + yield return MakeTestCase("Text", "Te", "[Te]xt", true); + yield return MakeTestCase("Text", "xt", "Te[xt]", true); + yield return MakeTestCase("Text", "Foo", "Text", false); + yield return MakeTestCase("Text", "", "Text", true); + // Only first match per string is highlighted + yield return MakeTestCase("Text Text Text", "Text", "[Text] Text Text", true); + // Verify tags inside target text don't get broken + yield return MakeTestCase("Bold Text", "Text", "Bold [Text]", true); + yield return MakeTestCase("Bold Text", "b", "[B]old Text", true); + yield return MakeTestCase("No Match Here", "b", "No Match Here", false); + yield return MakeTestCase("Multiple Tags", "i", "Mult[i]ple Tags", true); + yield return MakeTestCase("Many Tags", "i", "Many Tags", false); + yield return MakeTestCase("Text
On
Three Lines", "On", "Text
[On]
Three Lines", true); + + } + + [Test, TestCaseSource(nameof(SearchFilterTestCases))] + public void SearchFiltering(Dictionary> content, string searchString, List expectedResults, bool isMatch) + { + RenderGraphViewer.PerformSearch(content, searchString); + + var elements = content[k_FoldoutElement]; + for (int i = 0; i < elements.Count; i++) + { + Assert.AreEqual(elements[i].text, expectedResults[i]); + Assert.AreEqual(k_FoldoutElement.style.display.value, isMatch ? DisplayStyle.Flex : DisplayStyle.None); + } + } } } diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/RenderPipeline/DummyRenderPipeline.cs b/Packages/com.unity.render-pipelines.core/Tests/Editor/RenderPipeline/DummyRenderPipeline.cs index f0c2afd4..410f7dd1 100644 --- a/Packages/com.unity.render-pipelines.core/Tests/Editor/RenderPipeline/DummyRenderPipeline.cs +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/RenderPipeline/DummyRenderPipeline.cs @@ -1,11 +1,12 @@ -using UnityEngine; +using System.Collections.Generic; +using UnityEngine; using UnityEngine.Rendering; namespace UnityEditor.Rendering { class DummyRenderPipeline : RenderPipeline { - protected override void Render(ScriptableRenderContext context, Camera[] cameras) + protected override void Render(ScriptableRenderContext context, List cameras) { throw new System.NotImplementedException(); } diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/ShaderStripping/DummyPipelineShader.shader b/Packages/com.unity.render-pipelines.core/Tests/Editor/ShaderStripping/DummyPipelineShader.shader index 610d7e26..de0c09ab 100644 --- a/Packages/com.unity.render-pipelines.core/Tests/Editor/ShaderStripping/DummyPipelineShader.shader +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/ShaderStripping/DummyPipelineShader.shader @@ -1,4 +1,4 @@ -Shader "DummyPipeline/VariantStrippingTestsShader" +Shader "Hidden/DummyPipeline/VariantStrippingTestsShader" { Properties { diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/ShaderStripping/ShaderExtensionsTests.cs b/Packages/com.unity.render-pipelines.core/Tests/Editor/ShaderStripping/ShaderExtensionsTests.cs index 94232d91..9a51708f 100644 --- a/Packages/com.unity.render-pipelines.core/Tests/Editor/ShaderStripping/ShaderExtensionsTests.cs +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/ShaderStripping/ShaderExtensionsTests.cs @@ -10,7 +10,7 @@ namespace UnityEditor.Rendering.Tests.ShaderStripping new TestCaseData(Shader.Find("Hidden/Internal-Colored")) .SetName("Given a shader from Built-in, the render pipeline tag is not found and is empty") .Returns((false,string.Empty)), - new TestCaseData(Shader.Find("DummyPipeline/VariantStrippingTestsShader")) + new TestCaseData(Shader.Find("Hidden/DummyPipeline/VariantStrippingTestsShader")) .SetName("Given a shader with a render pipeline tag, the pipeline is found") .Returns((true, "DummyPipeline")) }; diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/ShaderStripping/ShaderStrippingTests.cs b/Packages/com.unity.render-pipelines.core/Tests/Editor/ShaderStripping/ShaderStrippingTests.cs index 661061ce..9fe634e3 100644 --- a/Packages/com.unity.render-pipelines.core/Tests/Editor/ShaderStripping/ShaderStrippingTests.cs +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/ShaderStripping/ShaderStrippingTests.cs @@ -130,7 +130,7 @@ namespace UnityEditor.Rendering.Tests.ShaderStripping new TestCaseData(typeof(StripHalf), Shader.Find("Hidden/Internal-Colored"), 6) .SetName("Given a stripper that reduces the variants to the half, just half of the variants are stripped") .Returns(3), - new TestCaseData(typeof(StripNothing), Shader.Find("DummyPipeline/VariantStrippingTestsShader"), 2) + new TestCaseData(typeof(StripNothing), Shader.Find("Hidden/DummyPipeline/VariantStrippingTestsShader"), 2) .SetName("Given a shader that is not from the current pipeline, all the variants are stripped") .Returns(0), }; diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/Unity.RenderPipelines.Core.Editor.Tests.asmdef b/Packages/com.unity.render-pipelines.core/Tests/Editor/Unity.RenderPipelines.Core.Editor.Tests.asmdef index 2a2c33c5..00eb3608 100644 --- a/Packages/com.unity.render-pipelines.core/Tests/Editor/Unity.RenderPipelines.Core.Editor.Tests.asmdef +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/Unity.RenderPipelines.Core.Editor.Tests.asmdef @@ -9,7 +9,8 @@ "GUID:d8b63aba1907145bea998dd612889d6b", "GUID:4fd6538c1c56b409fb53fdf0183170ec", "GUID:e0cd26848372d4e5c891c569017e11f1", - "GUID:bf043f86dbf1bda4398ec83eebe40b8c" + "GUID:bf043f86dbf1bda4398ec83eebe40b8c", + "GUID:aa4a944c34c4c5449b84975fb1570dad" ], "includePlatforms": [ "Editor" diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/Volumes/RenderPipelineTests.cs b/Packages/com.unity.render-pipelines.core/Tests/Editor/Volumes/RenderPipelineTests.cs index 02f7e8eb..65a1988f 100644 --- a/Packages/com.unity.render-pipelines.core/Tests/Editor/Volumes/RenderPipelineTests.cs +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/Volumes/RenderPipelineTests.cs @@ -5,7 +5,7 @@ using UnityEngine.Rendering; namespace UnityEditor.Rendering.Tests { - class RenderPipelineTests + internal class RenderPipelineTests { RenderPipelineAsset m_PreviousRenderPipelineAssetInGraphicsSettings; RenderPipelineAsset m_PreviousRenderPipelineAssetInQualitySettings; diff --git a/Packages/com.unity.render-pipelines.core/Tests/Runtime/AssemblyInfos.cs b/Packages/com.unity.render-pipelines.core/Tests/Runtime/AssemblyInfos.cs index 89789ef4..d1f436ba 100644 --- a/Packages/com.unity.render-pipelines.core/Tests/Runtime/AssemblyInfos.cs +++ b/Packages/com.unity.render-pipelines.core/Tests/Runtime/AssemblyInfos.cs @@ -1,3 +1,5 @@ using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("Unity.RenderPipelines.Core.Editor.Tests")] +[assembly: InternalsVisibleTo("SRPSmoke.Runtime.Tests")] +[assembly: InternalsVisibleTo("SRPSmoke.Editor.Tests")] diff --git a/Packages/com.unity.render-pipelines.core/Tests/Runtime/CustomRenderPipelineAsset.cs b/Packages/com.unity.render-pipelines.core/Tests/Runtime/CustomRenderPipelineAsset.cs index 5b521f81..acea501b 100644 --- a/Packages/com.unity.render-pipelines.core/Tests/Runtime/CustomRenderPipelineAsset.cs +++ b/Packages/com.unity.render-pipelines.core/Tests/Runtime/CustomRenderPipelineAsset.cs @@ -1,5 +1,6 @@ using UnityEngine; using UnityEngine.Rendering; +using System.Collections.Generic; namespace UnityEngine.Rendering.Tests { @@ -11,7 +12,7 @@ namespace UnityEngine.Rendering.Tests class CustomRenderPipeline : RenderPipeline { - protected override void Render(ScriptableRenderContext context, Camera[] cameras) + protected override void Render(ScriptableRenderContext context, List cameras) { } } diff --git a/Packages/com.unity.render-pipelines.core/Tests/Runtime/SecondCustomRenderPipelineAsset.cs b/Packages/com.unity.render-pipelines.core/Tests/Runtime/SecondCustomRenderPipelineAsset.cs index 04b76cf4..a81a244e 100644 --- a/Packages/com.unity.render-pipelines.core/Tests/Runtime/SecondCustomRenderPipelineAsset.cs +++ b/Packages/com.unity.render-pipelines.core/Tests/Runtime/SecondCustomRenderPipelineAsset.cs @@ -1,5 +1,6 @@ using UnityEngine; using UnityEngine.Rendering; +using System.Collections.Generic; namespace UnityEngine.Rendering.Tests { @@ -11,7 +12,7 @@ namespace UnityEngine.Rendering.Tests class SecondCustomRenderPipeline : RenderPipeline { - protected override void Render(ScriptableRenderContext context, Camera[] cameras) + protected override void Render(ScriptableRenderContext context, List cameras) { } } diff --git a/Packages/com.unity.render-pipelines.core/Tests/Runtime/Threading/FunctionTests.cs b/Packages/com.unity.render-pipelines.core/Tests/Runtime/Threading/FunctionTests.cs index 302bd474..703ddd0b 100644 --- a/Packages/com.unity.render-pipelines.core/Tests/Runtime/Threading/FunctionTests.cs +++ b/Packages/com.unity.render-pipelines.core/Tests/Runtime/Threading/FunctionTests.cs @@ -171,6 +171,7 @@ class ThreadingEmulationFunctionTests : IPrebuildSetup } [Test] + [UnityPlatform(exclude = new[] { RuntimePlatform.WindowsEditor, RuntimePlatform.WSAPlayerX64, RuntimePlatform.WindowsPlayer })] //https://jira.unity3d.com/browse/UUM-78016 public void WaveTest([Values]Kernel kernel, [Values]WaveSizeKeyword waveSizeKeyword) { int groupSize = (int)GroupSizeKeyword.GROUP_SIZE_128; diff --git a/Packages/com.unity.render-pipelines.core/package.json b/Packages/com.unity.render-pipelines.core/package.json index 95eb1599..08e08c87 100644 --- a/Packages/com.unity.render-pipelines.core/package.json +++ b/Packages/com.unity.render-pipelines.core/package.json @@ -1,9 +1,9 @@ { "name": "com.unity.render-pipelines.core", "description": "SRP Core makes it easier to create or customize a Scriptable Render Pipeline (SRP). SRP Core contains reusable code, including boilerplate code for working with platform-specific graphics APIs, utility functions for common rendering operations, and shader libraries. The code in SRP Core is use by the High Definition Render Pipeline (HDRP) and Universal Render Pipeline (URP). If you are creating a custom SRP from scratch or customizing a prebuilt SRP, using SRP Core will save you time.", - "version": "17.0.4", - "unity": "6000.0", - "displayName": "Core RP Library", + "version": "17.1.0", + "unity": "6000.1", + "displayName": "Scriptable Render Pipeline Core", "dependencies": { "com.unity.burst": "1.8.14", "com.unity.mathematics": "1.3.2", @@ -14,5 +14,5 @@ "com.unity.modules.jsonserialize": "1.0.0", "com.unity.rendering.light-transport": "1.0.1" }, - "_fingerprint": "481f548ebf36dd66c48f9774f47850ae22390918" + "_fingerprint": "e1ccf0da7b7866fa5b58ea14860297de7848dfd2" } diff --git a/Packages/com.unity.render-pipelines.high-definition-config/CHANGELOG.md b/Packages/com.unity.render-pipelines.high-definition-config/CHANGELOG.md index 0e324f92..bce83452 100644 --- a/Packages/com.unity.render-pipelines.high-definition-config/CHANGELOG.md +++ b/Packages/com.unity.render-pipelines.high-definition-config/CHANGELOG.md @@ -12,7 +12,7 @@ The version number for this package has increased due to a version update of a r ## [17.0.3] - 2025-02-13 -This version is compatible with Unity 6000.0.39f1. +This version is compatible with Unity 6000.2.0a1. Version Updated The version number for this package has increased due to a version update of a related graphics package. diff --git a/Packages/com.unity.render-pipelines.high-definition-config/package.json b/Packages/com.unity.render-pipelines.high-definition-config/package.json index c931e037..92dcc54d 100644 --- a/Packages/com.unity.render-pipelines.high-definition-config/package.json +++ b/Packages/com.unity.render-pipelines.high-definition-config/package.json @@ -1,11 +1,11 @@ { "name": "com.unity.render-pipelines.high-definition-config", "description": "Configuration files for the High Definition Render Pipeline.", - "version": "17.0.4", - "unity": "6000.0", - "displayName": "High Definition RP Config", + "version": "17.1.0", + "unity": "6000.1", + "displayName": "High Definition Render Pipeline Config", "dependencies": { - "com.unity.render-pipelines.core": "17.0.4" + "com.unity.render-pipelines.core": "17.1.0" }, - "_fingerprint": "88d6678364c971316dc9885a738d3462b1306ad0" + "_fingerprint": "df264f43ceeeb27fd645ba51a52555c620dd9154" } diff --git a/Packages/com.unity.render-pipelines.high-definition/CHANGELOG.md b/Packages/com.unity.render-pipelines.high-definition/CHANGELOG.md index 206189f8..b86905bc 100644 --- a/Packages/com.unity.render-pipelines.high-definition/CHANGELOG.md +++ b/Packages/com.unity.render-pipelines.high-definition/CHANGELOG.md @@ -12,9 +12,12 @@ The version number for this package has increased due to a version update of a r ## [17.0.3] - 2025-02-13 -This version is compatible with Unity 6000.0.39f1. +This version is compatible with Unity 6000.2.0a1. ### Changed +- Wizard - Simplified the list of validations for IRenderPipelineGraphicsSettings. +- Improved the water sample by adding a cave scene using caustics and deformation texture. +- Improved Depth usage performance for some platforms. - Added SG custom refraction example to Transparency sample. - Added environment samples showcasing environment effects together. - Optimised the water vertex shader. @@ -28,6 +31,38 @@ This version is compatible with Unity 6000.0.39f1. - Improved water sample by adding a cave scene using caustics and deformation texture. ### Fixed +- Fixed layer index out of range in LayeredLitGUI. +- Fixed advanced upsampler settings not visible on platforms where they are not supported. +- Fixed cloud layers not being drawn behind transparent refractive objects. +- Fixed HairVertex instancing-related shader-compilation issues. +- Ignore material variants with log message. +- Ensure custom post-processing effects are disabled when post-processing is disabled. +- Fixed black line artifacts on top of the screen with DRS and downsampled SSAO. +- Fixed wrong SSR when using a shader graph with a clear coat value of 0. +- Fixed Screen-Space Subsurface Scattering leaking from material with a subsurface mask set to 0. +- Fixed a bug that caused HDAdditionalLightData with preserveCachedShadow to be evicted from the cachedShadowManager. +- Fixed an issue where DebugDisplay Camera list grew beyond number of active cameras, every time a camera was registered or unregistered. +- Fixed a shader error when using water excluder with entities. +- Fixed an issue by adding clamp to HairAngleWorld to prevent nan from FastASin. +- Fixed an issue to avoid calling the Cleanup method twice so the celestial data remains. +- Fixed errors that would occur when building the XR player with Water System enabled. +- Removed the "Setting MRTs without a depth buffer is not supported" error in Volumetric Clouds Combine pass. +- Fixed visual artifacts when using the Graphics Compositor on the editor on MacOS. The issue occurred when changing the "Output Camera" and the "Clear Color" field was disabled. +- Fixed invalid global state pushed when using override camera rendering in the CustomPassUtils functions. +- Fixed shader warning in sub-surface scattering compute. +- Fixed color pyramid sampling when distortion is enabled after the distortion pass. +- Removed the FixAll button from the High Definition Render Pipeline (HDRP) Wizard when no automated fix is available. +- Added a condition to the Receiver Motion Rejection feature that checks whether a pixel has actually moved. +- Fixed an issue where High Definition Render Pipeline (HDRP) ambient scene lighting was leaking into the material preview window. +- Fixed an issue that prevented changing the Shadow Map resolution for `HDAdditionalLightData` when using `preserveCachedShadow`. +- Fixed an issue with High Definition Render Pipeline (HDRP) sky rendering when Camera Relative Rendering is disabled. + + +- Fixed visual artifacts that occurred when blending cascade shadows and distance shadow masks. +- Updated the High Definition Render Pipeline (HDRP) Wizard to no longer assume a check failure while awaiting a reply from the Package Manager. The Wizard now displays a specific pending icon during this process. +- Fixed an issue where the padding in the Lighting window was different between tabs. +- Fixed a Sensor SDK compilation issue in DXR-enabled HDRP projects. +- Fixed an issue where underwater collider bounds checks were inaccurate when the collider was rotated. - Added framesettings to render volumetric clouds in half resolution to reduce jittering. - Fixed invalid AABB errors for some projects. - Fixed an issuse with viewport flickering when multi-frame rendering API is used with certain parameters. diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/HDRPPreprocessBuild.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/HDRPPreprocessBuild.cs index a6d5bedf..5a9a9371 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/HDRPPreprocessBuild.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/HDRPPreprocessBuild.cs @@ -113,6 +113,10 @@ namespace UnityEditor.Rendering.HighDefinition private static void GetSupportedShaderFeaturesFromAssets(ref List hdrpAssets, ref List rendererFeaturesList) { + bool useBicubicLightmapSampling = false; + if (GraphicsSettings.TryGetRenderPipelineSettings(out var lightmapSamplingSettings)) + useBicubicLightmapSampling = lightmapSamplingSettings.useBicubicLightmapSampling; + for (int hdrpAssetIndex = 0; hdrpAssetIndex < hdrpAssets.Count; hdrpAssetIndex++) { // Get the asset and check if it's valid @@ -124,7 +128,7 @@ namespace UnityEditor.Rendering.HighDefinition ShaderFeatures hdrpAssetShaderFeatures = GetSupportedShaderFeaturesFromAsset(ref hdrpAsset); // Creates a struct containing all the prefiltering settings for this asset - ShaderPrefilteringData spd = CreatePrefilteringSettings(ref hdrpAssetShaderFeatures); + ShaderPrefilteringData spd = CreatePrefilteringSettings(ref hdrpAssetShaderFeatures, useBicubicLightmapSampling); // Update the Prefiltering settings for this URP asset hdrpAsset.UpdateShaderKeywordPrefiltering(ref spd); @@ -144,11 +148,12 @@ namespace UnityEditor.Rendering.HighDefinition return hdrpAssetShaderFeatures; } - private static ShaderPrefilteringData CreatePrefilteringSettings(ref ShaderFeatures shaderFeatures) + private static ShaderPrefilteringData CreatePrefilteringSettings(ref ShaderFeatures shaderFeatures, bool useBicubicLightmapSampling) { ShaderPrefilteringData spd = new(); spd.useLegacyLightmaps = IsFeatureEnabled(shaderFeatures, ShaderFeatures.UseLegacyLightmaps); + spd.useBicubicLightmapSampling = useBicubicLightmapSampling; return spd; } diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/HDRPPreprocessShaders.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/HDRPPreprocessShaders.cs index 7635e711..5449cf26 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/HDRPPreprocessShaders.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/HDRPPreprocessShaders.cs @@ -290,6 +290,16 @@ namespace UnityEditor.Rendering.HighDefinition (!settings.supportProbeVolume || settings.probeVolumeSHBands != ProbeVolumeSHBands.SphericalHarmonicsL2)) return true; + bool hasBicubicKeyword = shader.keywordSpace.FindKeyword(m_LightmapBicubicSampling.name).isValid; + if (hasBicubicKeyword) + { + bool useBicubicLightmapSampling = false; + if (GraphicsSettings.TryGetRenderPipelineSettings(out var lightmapSamplingSettings)) + useBicubicLightmapSampling = lightmapSamplingSettings.useBicubicLightmapSampling; + if (inputData.shaderKeywordSet.IsEnabled(m_LightmapBicubicSampling) != useBicubicLightmapSampling) + return true; + } + #if !ENABLE_SENSOR_SDK // If the SensorSDK package is not present, make sure that all code related to it is stripped away if (inputData.shaderKeywordSet.IsEnabled(m_SensorEnableLidar) || inputData.shaderKeywordSet.IsEnabled(m_SensorOverrideReflectance)) diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Lighting/VolumetricLighting/LocalVolumetricFogEditor.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Lighting/VolumetricLighting/LocalVolumetricFogEditor.cs index 74741678..b640ac13 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Lighting/VolumetricLighting/LocalVolumetricFogEditor.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Lighting/VolumetricLighting/LocalVolumetricFogEditor.cs @@ -111,7 +111,7 @@ namespace UnityEditor.Rendering.HighDefinition || s_ShapeBox == null || s_ShapeBox.Equals(null)) return; - using (new Handles.DrawingScope(Matrix4x4.TRS(localVolumetricFog.transform.position, localVolumetricFog.transform.rotation, Vector3.one))) + using (new Handles.DrawingScope(Matrix4x4.TRS(localVolumetricFog.transform.position, localVolumetricFog.transform.rotation, localVolumetricFog.effectiveScale))) { // Blend box s_BlendBox.center = CenterBlendLocalPosition(localVolumetricFog); @@ -131,7 +131,7 @@ namespace UnityEditor.Rendering.HighDefinition void OnSceneGUI() { //Note: for each handle to be independent when multi-selecting LocalVolumetricFog, - //We cannot rely hereon SerializedLocalVolumetricFog which is the collection of + //We cannot rely here on SerializedLocalVolumetricFog which is the collection of //selected LocalVolumetricFog. Thus code is almost the same of the UI. LocalVolumetricFog localVolumetricFog = target as LocalVolumetricFog; @@ -139,7 +139,7 @@ namespace UnityEditor.Rendering.HighDefinition switch (EditMode.editMode) { case k_EditBlend: - using (new Handles.DrawingScope(Matrix4x4.TRS(localVolumetricFog.transform.position, localVolumetricFog.transform.rotation, Vector3.one))) + using (new Handles.DrawingScope(Matrix4x4.TRS(localVolumetricFog.transform.position, localVolumetricFog.transform.rotation, localVolumetricFog.effectiveScale))) { //contained must be initialized in all case s_ShapeBox.center = Vector3.zero; @@ -186,10 +186,10 @@ namespace UnityEditor.Rendering.HighDefinition case k_EditShape: //important: if the origin of the handle's space move along the handle, //handles displacement will appears as moving two time faster. - using (new Handles.DrawingScope(Matrix4x4.TRS(Vector3.zero, localVolumetricFog.transform.rotation, Vector3.one))) + using (new Handles.DrawingScope(Matrix4x4.TRS(localVolumetricFog.transform.position, localVolumetricFog.transform.rotation, localVolumetricFog.effectiveScale))) { //contained must be initialized in all case - s_ShapeBox.center = Quaternion.Inverse(localVolumetricFog.transform.rotation) * localVolumetricFog.transform.position; + s_ShapeBox.center = Vector3.zero; s_ShapeBox.size = localVolumetricFog.parameters.size; Vector3 previousSize = localVolumetricFog.parameters.size; @@ -257,9 +257,6 @@ namespace UnityEditor.Rendering.HighDefinition 1.0f - (newSize.y > 0.00000001 ? (newSize.y - newUniformFade) / newSize.y : 0f), 1.0f - (newSize.z > 0.00000001 ? (newSize.z - newUniformFade) / newSize.z : 0f)); } - - Vector3 delta = localVolumetricFog.transform.rotation * s_ShapeBox.center - localVolumetricFog.transform.position; - localVolumetricFog.transform.position += delta; } } break; diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Lighting/VolumetricLighting/LocalVolumetricFogUI.Drawer.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Lighting/VolumetricLighting/LocalVolumetricFogUI.Drawer.cs index 4fdedfa0..24298da7 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Lighting/VolumetricLighting/LocalVolumetricFogUI.Drawer.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Lighting/VolumetricLighting/LocalVolumetricFogUI.Drawer.cs @@ -79,6 +79,8 @@ namespace UnityEditor.Rendering.HighDefinition Vector3 previousPositiveFade = serialized.editorPositiveFade.vector3Value; Vector3 previousNegativeFade = serialized.editorNegativeFade.vector3Value; + EditorGUILayout.PropertyField(serialized.scaleMode, Styles.s_ScaleMode); + EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(serialized.size, Styles.s_Size); if (EditorGUI.EndChangeCheck()) diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Lighting/VolumetricLighting/LocalVolumetricFogUI.Skin.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Lighting/VolumetricLighting/LocalVolumetricFogUI.Skin.cs index 576feb02..fd6f24e3 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Lighting/VolumetricLighting/LocalVolumetricFogUI.Skin.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Lighting/VolumetricLighting/LocalVolumetricFogUI.Skin.cs @@ -16,6 +16,7 @@ namespace UnityEditor.Rendering.HighDefinition EditorGUIUtility.IconContent("PreMatCube", "|Modify the influence volume. (SHIFT+2)") }; + public static readonly GUIContent s_ScaleMode = new GUIContent("Scale Mode", "Specifies the scaling mode to apply to the Local Volumetric Fog Volume."); public static readonly GUIContent s_Size = new GUIContent("Size", "Modify the size of this Local Volumetric Fog. This is independent of the Transform's Scale."); public static readonly GUIContent s_AlbedoLabel = new GUIContent("Single Scattering Albedo", "The color this fog scatters light to."); public static readonly GUIContent s_MeanFreePathLabel = new GUIContent("Fog Distance", "Density at the base of the fog. Determines how far you can see through the fog in meters."); diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Lighting/VolumetricLighting/SerializedLocalVolumetricFog.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Lighting/VolumetricLighting/SerializedLocalVolumetricFog.cs index 33f03f41..2785963a 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Lighting/VolumetricLighting/SerializedLocalVolumetricFog.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Lighting/VolumetricLighting/SerializedLocalVolumetricFog.cs @@ -16,6 +16,7 @@ namespace UnityEditor.Rendering.HighDefinition public SerializedProperty textureScroll; public SerializedProperty textureTile; + public SerializedProperty scaleMode; public SerializedProperty size; SerializedProperty positiveFade; @@ -54,6 +55,7 @@ namespace UnityEditor.Rendering.HighDefinition textureScroll = densityParams.FindPropertyRelative("textureScrollingSpeed"); textureTile = densityParams.FindPropertyRelative("textureTiling"); + scaleMode = densityParams.FindPropertyRelative("scaleMode"); size = densityParams.FindPropertyRelative("size"); positiveFade = densityParams.FindPropertyRelative("positiveFade"); diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/BaseShaderPreprocessor.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/BaseShaderPreprocessor.cs index 31f83ed8..77978a8b 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/BaseShaderPreprocessor.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/BaseShaderPreprocessor.cs @@ -85,6 +85,7 @@ namespace UnityEditor.Rendering.HighDefinition protected ShaderKeyword m_ScreenSpaceShadowONKeywords; protected ShaderKeyword m_ProbeVolumesL1; protected ShaderKeyword m_ProbeVolumesL2; + protected ShaderKeyword m_LightmapBicubicSampling; protected ShaderKeyword m_DecalSurfaceGradient; protected ShaderKeyword m_EditorVisualization; protected ShaderKeyword m_SupportWater; @@ -132,6 +133,7 @@ namespace UnityEditor.Rendering.HighDefinition m_ScreenSpaceShadowONKeywords = new ShaderKeyword("SCREEN_SPACE_SHADOWS_ON"); m_ProbeVolumesL1 = new ShaderKeyword("PROBE_VOLUMES_L1"); m_ProbeVolumesL2 = new ShaderKeyword("PROBE_VOLUMES_L2"); + m_LightmapBicubicSampling = new ShaderKeyword("LIGHTMAP_BICUBIC_SAMPLING"); m_DecalSurfaceGradient = new ShaderKeyword("DECAL_SURFACE_GRADIENT"); m_EditorVisualization = new ShaderKeyword("EDITOR_VISUALIZATION"); m_SupportWater = new ShaderKeyword("SUPPORT_WATER"); diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/DiffusionProfile/DiffusionProfileSettingsEditor.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/DiffusionProfile/DiffusionProfileSettingsEditor.cs index f5f9a9a1..06891343 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/DiffusionProfile/DiffusionProfileSettingsEditor.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/DiffusionProfile/DiffusionProfileSettingsEditor.cs @@ -160,6 +160,8 @@ namespace UnityEditor.Rendering.HighDefinition DualSliderWithFields(Styles.smoothnessMultipliers, m_SerializedDiffusionProfileSettings.smoothnessMultipliers, 0.0f, 2.0f); EditorGUILayout.PropertyField(m_SerializedDiffusionProfileSettings.lobeMix); EditorGUILayout.PropertyField(m_SerializedDiffusionProfileSettings.diffusePower); + if (HDRenderPipeline.currentAsset == null || HDRenderPipeline.currentAsset.currentPlatformRenderPipelineSettings.subsurfaceScatteringAttenuation) + EditorGUILayout.PropertyField(m_SerializedDiffusionProfileSettings.borderAttenuationColor); } EditorGUILayout.Space(); diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/DiffusionProfile/SerializedDiffusionProfileSettings.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/DiffusionProfile/SerializedDiffusionProfileSettings.cs index 03136645..9bb5c502 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/DiffusionProfile/SerializedDiffusionProfileSettings.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/DiffusionProfile/SerializedDiffusionProfileSettings.cs @@ -18,6 +18,7 @@ namespace UnityEditor.Rendering.HighDefinition internal SerializedProperty smoothnessMultipliers; internal SerializedProperty lobeMix; internal SerializedProperty diffusePower; + internal SerializedProperty borderAttenuationColor; internal SerializedProperty transmissionMode; internal SerializedProperty thicknessRemap; internal SerializedProperty worldScale; @@ -47,6 +48,7 @@ namespace UnityEditor.Rendering.HighDefinition smoothnessMultipliers = rp.Find(x => x.smoothnessMultipliers); lobeMix = rp.Find(x => x.lobeMix); diffusePower = rp.Find(x => x.diffuseShadingPower); + borderAttenuationColor = rp.Find(x => x.borderAttenuationColor); transmissionMode = rp.Find(x => x.transmissionMode); thicknessRemap = rp.Find(x => x.thicknessRemap); worldScale = rp.Find(x => x.worldScale); diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Lit/ShaderGraph/HDLitSubTarget.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Lit/ShaderGraph/HDLitSubTarget.cs index 04b1797e..ac6a03af 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Lit/ShaderGraph/HDLitSubTarget.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Lit/ShaderGraph/HDLitSubTarget.cs @@ -61,7 +61,7 @@ namespace UnityEditor.Rendering.HighDefinition.ShaderGraph descriptor.passes.Add(HDShaderPasses.GenerateLitDepthOnly(TargetsVFX(), systemData.tessellation)); descriptor.passes.Add(HDShaderPasses.GenerateGBuffer(TargetsVFX(), systemData.tessellation)); descriptor.passes.Add(HDShaderPasses.GenerateLitForward(TargetsVFX(), systemData.tessellation)); - if (!systemData.tessellation) // Raytracing don't support tessellation neither VFX + if (!systemData.tessellation && supportRaytracing) // Raytracing don't support tessellation descriptor.passes.Add(HDShaderPasses.GenerateLitRaytracingPrepass()); return descriptor; diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Lit/ShaderGraph/ShaderPass.template.hlsl b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Lit/ShaderGraph/ShaderPass.template.hlsl index cbd72ac7..c9a5e997 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Lit/ShaderGraph/ShaderPass.template.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Lit/ShaderGraph/ShaderPass.template.hlsl @@ -50,6 +50,7 @@ void BuildSurfaceData(FragInputs fragInputs, inout SurfaceDescription surfaceDes // These static material feature allow compile time optimization surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD; #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING + if (surfaceData.subsurfaceMask > 0) surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING; #endif diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/HDSubTarget.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/HDSubTarget.cs index 49ef88a4..02c1f8fb 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/HDSubTarget.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/HDSubTarget.cs @@ -213,7 +213,9 @@ namespace UnityEditor.Rendering.HighDefinition.ShaderGraph { if (passDescriptor.defines == null) passDescriptor.defines = new(); - passDescriptor.defines.Add(CoreDefines.SupportGlobalMipBias); + + if (!passDescriptor.defines.Any(d => d.descriptor.referenceName == CoreDefines.SupportGlobalMipBias.First().descriptor.referenceName)) + passDescriptor.defines.Add(CoreDefines.SupportGlobalMipBias); } CollectPassKeywords(ref passDescriptor); @@ -287,7 +289,9 @@ namespace UnityEditor.Rendering.HighDefinition.ShaderGraph { if (passDescriptor.defines == null) passDescriptor.defines = new(); - passDescriptor.defines.Add(CoreDefines.SupportGlobalMipBias); + + if (!passDescriptor.defines.Any(d => d.descriptor.referenceName == CoreDefines.SupportGlobalMipBias.First().descriptor.referenceName)) + passDescriptor.defines.Add(CoreDefines.SupportGlobalMipBias); } CollectPassKeywords(ref passDescriptor); diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/HDTarget.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/HDTarget.cs index 6e1e8ebd..d4c6b13e 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/HDTarget.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/HDTarget.cs @@ -1881,6 +1881,15 @@ namespace UnityEditor.Rendering.HighDefinition.ShaderGraph definition = KeywordDefinition.MultiCompile, scope = KeywordScope.Global }; + + public static KeywordDescriptor LightmapBicubicSampling = new KeywordDescriptor() + { + displayName = "Lightmap Bicubic Sampling", + referenceName = "LIGHTMAP_BICUBIC_SAMPLING", + type = KeywordType.Boolean, + definition = KeywordDefinition.MultiCompile, + scope = KeywordScope.Global + }; } #endregion diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/LightingSubTarget.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/LightingSubTarget.cs index 6469ba0e..229f5885 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/LightingSubTarget.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/LightingSubTarget.cs @@ -119,6 +119,7 @@ namespace UnityEditor.Rendering.HighDefinition.ShaderGraph pass.keywords.Add(CoreKeywordDescriptors.DirectionalLightmapCombined); pass.keywords.Add(CoreKeywordDescriptors.ProbeVolumes); pass.keywords.Add(CoreKeywordDescriptors.DynamicLightmap); + pass.keywords.Add(CoreKeywordDescriptors.LightmapBicubicSampling); if (!pass.IsRelatedToRaytracing()) { diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/Templates/ShaderPass.template b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/Templates/ShaderPass.template index 1c23a0e1..a495b07f 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/Templates/ShaderPass.template +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/Templates/ShaderPass.template @@ -394,7 +394,7 @@ Pass #if !defined(SHADER_STAGE_RAY_TRACING) #include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/VisualEffectVertex.hlsl" #else - $features.graphVFX: $include("IntersectionShader.template.hlsl") + $features.graphVFX: $RaytracingVFX: $include("IntersectionShader.template.hlsl") #endif #endif diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/TerrainLit/TerrainLitGUI.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/TerrainLit/TerrainLitGUI.cs index 3995b330..4d47228f 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/TerrainLit/TerrainLitGUI.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/TerrainLit/TerrainLitGUI.cs @@ -98,7 +98,7 @@ namespace UnityEditor.Rendering.HighDefinition heightTransition = prop; else if (prop.name == kEnableInstancedPerPixelNormal) enableInstancedPerPixelNormal = prop; - else if ((prop.flags & (MaterialProperty.PropFlags.HideInInspector | MaterialProperty.PropFlags.PerRendererData)) == 0) + else if ((prop.propertyFlags & (ShaderPropertyFlags.HideInInspector | ShaderPropertyFlags.PerRendererData)) == 0) customProperties.Add(prop); } } diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/SurfaceOptionUIBlock.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/SurfaceOptionUIBlock.cs index 7e49b97d..4035bc60 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/SurfaceOptionUIBlock.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/UIBlocks/SurfaceOptionUIBlock.cs @@ -325,7 +325,7 @@ namespace UnityEditor.Rendering.HighDefinition transmissionEnable = FindProperty(kTransmissionEnable); clearCoatEnabled = FindProperty(kClearCoatEnabled); - + excludeFromTUAndAA = FindProperty(kExcludeFromTUAndAA); if ((m_Features & Features.DoubleSidedNormalMode) != 0) @@ -874,6 +874,15 @@ namespace UnityEditor.Rendering.HighDefinition materialEditor.ShaderProperty(depthOffsetEnable, Styles.depthOffsetEnableText); EditorGUI.indentLevel--; } + + if (displaceMode != DisplacementMode.None && materials[0].GetTexture(kHeightMap) == null) + { + EditorGUILayout.Space(); + EditorGUI.indentLevel++; + + EditorGUILayout.HelpBox("Please set a valid HeightMap (in the 'Surface Inputs' category) to apply any displacement.", MessageType.Warning); + EditorGUI.indentLevel--; + } } } diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/Node/EvaluateScatteringColor_Water.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/Node/EvaluateScatteringColor_Water.cs index 174a3fbd..30090ab0 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/Node/EvaluateScatteringColor_Water.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/Node/EvaluateScatteringColor_Water.cs @@ -27,8 +27,8 @@ namespace UnityEditor.Rendering.HighDefinition const int kLowFrequencyHeightInputSlotId = 1; const string kLowFrequencyHeightInputSlotName = "LowFrequencyHeight"; - const int kHorizontalDisplacementInputSlotId = 2; - const string kHorizontalDisplacementInputSlotName = "HorizontalDisplacement"; + const int kDisplacementInputSlotId = 2; + const string kDisplacementInputSlotName = "Displacement"; const int kDeepFoamInputSlotId = 3; const string kDeepFoamInputSlotName = "DeepFoam"; @@ -43,7 +43,7 @@ namespace UnityEditor.Rendering.HighDefinition // Input AddSlot(new Vector3MaterialSlot(kAbsorptionTintInputSlotId, kAbsorptionTintInputSlotName, kAbsorptionTintInputSlotName, SlotType.Input, Vector3.zero, ShaderStageCapability.Fragment)); AddSlot(new Vector1MaterialSlot(kLowFrequencyHeightInputSlotId, kLowFrequencyHeightInputSlotName, kLowFrequencyHeightInputSlotName, SlotType.Input, 0, ShaderStageCapability.Fragment)); - AddSlot(new Vector1MaterialSlot(kHorizontalDisplacementInputSlotId, kHorizontalDisplacementInputSlotName, kHorizontalDisplacementInputSlotName, SlotType.Input, 0, ShaderStageCapability.Fragment)); + AddSlot(new Vector3MaterialSlot(kDisplacementInputSlotId, kDisplacementInputSlotName, kDisplacementInputSlotName, SlotType.Input, Vector3.zero, ShaderStageCapability.Fragment)); AddSlot(new Vector1MaterialSlot(kDeepFoamInputSlotId, kDeepFoamInputSlotName, kDeepFoamInputSlotName, SlotType.Input, 0, ShaderStageCapability.Fragment)); // Output @@ -54,7 +54,7 @@ namespace UnityEditor.Rendering.HighDefinition // Input kAbsorptionTintInputSlotId, kLowFrequencyHeightInputSlotId, - kHorizontalDisplacementInputSlotId, + kDisplacementInputSlotId, kDeepFoamInputSlotId, // Output @@ -70,7 +70,7 @@ namespace UnityEditor.Rendering.HighDefinition sb.AppendLine("$precision3 {5} = EvaluateScatteringColor(IN.{0}.xzy, {1}, {2}, {3}, {4});", ShaderGeneratorNames.GetUVName(UVChannel.UV0), GetSlotValue(kLowFrequencyHeightInputSlotId, generationMode), - GetSlotValue(kHorizontalDisplacementInputSlotId, generationMode), + GetSlotValue(kDisplacementInputSlotId, generationMode), GetSlotValue(kAbsorptionTintInputSlotId, generationMode), GetSlotValue(kDeepFoamInputSlotId, generationMode), GetVariableNameForSlot(kScatteringColorOutputSlotId)); diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/Node/EvaluateSimulationAdditionalData_Water.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/Node/EvaluateSimulationAdditionalData_Water.cs index b32922e1..e025fafb 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/Node/EvaluateSimulationAdditionalData_Water.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/Node/EvaluateSimulationAdditionalData_Water.cs @@ -62,8 +62,8 @@ namespace UnityEditor.Rendering.HighDefinition sb.AppendLine("ZERO_INITIALIZE(WaterAdditionalData, waterAdditionalData);"); // Evaluate the data - sb.AppendLine("EvaluateWaterAdditionalData(IN.{0}.xzy, IN.WorldSpacePosition, IN.WorldSpaceNormal, waterAdditionalData);", - ShaderGeneratorNames.GetUVName(UVChannel.UV0)); + sb.AppendLine("EvaluateWaterAdditionalData(IN.{0}.xzy, IN.WorldSpacePosition, IN.WorldSpaceNormal, float2(IN.{0}.w, IN.{1}.w), waterAdditionalData);", + ShaderGeneratorNames.GetUVName(UVChannel.UV0), ShaderGeneratorNames.GetUVName(UVChannel.UV1)); // Output the data sb.AppendLine("$precision3 {0} = waterAdditionalData.normalWS;", diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/Node/UnpackData_Water.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/Node/UnpackData_Water.cs index 921f10de..14e8fe8d 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/Node/UnpackData_Water.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/Node/UnpackData_Water.cs @@ -24,8 +24,8 @@ namespace UnityEditor.Rendering.HighDefinition const int kLowFrequencyHeightOutputSlotId = 0; const string kLowFrequencyHeightSlotName = "LowFrequencyHeight"; - const int kHorizontalDisplacementOutputSlotId = 1; - const string kHorizontalDisplacementSlotName = "HorizontalDisplacement"; + const int kDisplacementOutputSlotId = 1; + const string kDisplacementSlotName = "Displacement"; public override bool hasPreview { get { return false; } } @@ -33,13 +33,13 @@ namespace UnityEditor.Rendering.HighDefinition { // Outputs AddSlot(new Vector1MaterialSlot(kLowFrequencyHeightOutputSlotId, kLowFrequencyHeightSlotName, kLowFrequencyHeightSlotName, SlotType.Output, 0)); - AddSlot(new Vector1MaterialSlot(kHorizontalDisplacementOutputSlotId, kHorizontalDisplacementSlotName, kHorizontalDisplacementSlotName, SlotType.Output, 0)); + AddSlot(new Vector3MaterialSlot(kDisplacementOutputSlotId, kDisplacementSlotName, kDisplacementSlotName, SlotType.Output, Vector3.zero)); RemoveSlotsNameNotMatching(new[] { // Outputs kLowFrequencyHeightOutputSlotId, - kHorizontalDisplacementOutputSlotId, + kDisplacementOutputSlotId, }); } @@ -48,15 +48,16 @@ namespace UnityEditor.Rendering.HighDefinition // See PackWaterVertexData // Low Frequency Height - sb.AppendLine("$precision {0} = saturate(IN.{1}.w);", + sb.AppendLine("$precision {0} = saturate(IN.{1}.z);", GetVariableNameForSlot(kLowFrequencyHeightOutputSlotId), - ShaderGeneratorNames.GetUVName(UVChannel.UV1) + ShaderGeneratorNames.GetUVName(UVChannel.UV0) ); - // Horizontal Displacement - sb.AppendLine("$precision {0} = IN.{1}.w;", - GetVariableNameForSlot(kHorizontalDisplacementOutputSlotId), - ShaderGeneratorNames.GetUVName(UVChannel.UV0) + // Displacement + sb.AppendLine("$precision3 {0} = float3(IN.{1}.w, IN.{1}.z, IN.{2}.w);", + GetVariableNameForSlot(kDisplacementOutputSlotId), + ShaderGeneratorNames.GetUVName(UVChannel.UV0), + ShaderGeneratorNames.GetUVName(UVChannel.UV1) ); } diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/Vertex.template.hlsl b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/Vertex.template.hlsl index c5e43486..edf74755 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/Vertex.template.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/Vertex.template.hlsl @@ -25,13 +25,8 @@ void PackWaterVertexData(VertexDescription vertex, out float4 uv0, out float4 uv uv0 = float4(vertex.Displacement, 1.0); uv1 = float4(vertex.Position, 1.0); #else - uv0.xy = vertex.Position.xz; - uv0.z = vertex.Displacement.y; - uv0.w = length(vertex.Displacement.xz); - - if (_GridSize.x >= 0) - uv1.xyz = TransformObjectToWorld(vertex.Position + vertex.Displacement); - uv1.w = vertex.LowFrequencyHeight; + uv0 = float4(vertex.Position.x, vertex.Position.z, vertex.Displacement.y, vertex.Displacement.x); + uv1 = float4(TransformObjectToWorld(vertex.Position + vertex.Displacement), vertex.Displacement.z); #endif } diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/WaterDecalShaderPass.template b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/WaterDecalShaderPass.template index 7be872b1..a8253f9d 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/WaterDecalShaderPass.template +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/WaterDecalShaderPass.template @@ -115,8 +115,10 @@ PackedVaryings Vert(Attributes input) return packedOutput; } -#ifdef PASS_DEFORMATION_AND_FOAM - #define TARGET_TYPE float3 +#ifdef PASS_DEFORMATION + #define TARGET_TYPE float4 +#elif defined(PASS_FOAM) + #define TARGET_TYPE float2 #elif defined(PASS_MASK) #define TARGET_TYPE float4 #elif defined(PASS_LARGE_CURRENT) @@ -132,14 +134,14 @@ TARGET_TYPE Frag(PackedVaryings packedInput) : SV_Target SurfaceDescriptionInputs inputs = BuildSurfaceDescriptionInputs(varyings); SurfaceDescription surface = SurfaceDescriptionFunction(inputs); - float deformation = 0.0f; + float3 deformation = 0.0f; float2 foam = 0.0f; float4 mask = 1.0f; float3 largeCurrent = 0.0f; float3 ripplesCurrent = 0.0f; #if _AFFECTS_DEFORMATION == 1 - $Material.Deformation: deformation = surface.Deformation; + $Material.Deformation: deformation = float3(surface.Deformation, surface.HorizontalDeformation.x, surface.HorizontalDeformation.y); #endif #if _AFFECTS_FOAM == 1 @@ -162,8 +164,10 @@ TARGET_TYPE Frag(PackedVaryings packedInput) : SV_Target $Material.RipplesCurrentInfluence: ripplesCurrent.z = saturate(surface.RipplesCurrentInfluence); #endif -#ifdef PASS_DEFORMATION_AND_FOAM - return float3(deformation, foam); +#ifdef PASS_DEFORMATION + return float4(surface.Deformation, surface.HorizontalDeformation.x, surface.HorizontalDeformation.y, 0); +#elif defined(PASS_FOAM) + return float2(foam); #elif defined(PASS_MASK) return mask; #elif defined(PASS_LARGE_CURRENT) diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/WaterDecalSubTarget.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/WaterDecalSubTarget.cs index 56feeca4..e4d66212 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/WaterDecalSubTarget.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/WaterDecalSubTarget.cs @@ -87,8 +87,10 @@ namespace UnityEditor.Rendering.HighDefinition.ShaderGraph pipelineTag = HDRenderPipeline.k_ShaderTagName, }; - if (m_Data.affectsDeformation || m_Data.affectsFoam) - result.passes.Add(GeneratePass(WaterDecal.PassType.DeformationAndFoam)); + if (m_Data.affectsDeformation) + result.passes.Add(GeneratePass(WaterDecal.PassType.Deformation)); + if (m_Data.affectsFoam) + result.passes.Add(GeneratePass(WaterDecal.PassType.Foam)); if (m_Data.affectsSimulationMask) result.passes.Add(GeneratePass(WaterDecal.PassType.SimulationMask)); if (m_Data.affectsLargeCurrent) @@ -141,6 +143,7 @@ namespace UnityEditor.Rendering.HighDefinition.ShaderGraph // Water specific block descriptors public static BlockFieldDescriptor Deformation = new BlockFieldDescriptor(name, "Deformation", "Deformation", "SURFACEDESCRIPTION_DEFORMATION", new FloatControl(0.0f), ShaderStage.Fragment); + public static BlockFieldDescriptor DeformationHorizontal = new BlockFieldDescriptor(name, "HorizontalDeformation", "Horizontal Deformation", "SURFACEDESCRIPTION_HORIZONTALDEFORMATION", new Vector2Control(Vector2.zero), ShaderStage.Fragment); public static BlockFieldDescriptor SurfaceFoam = new BlockFieldDescriptor(name, "SurfaceFoam", "SurfaceFoam", "SURFACEDESCRIPTION_SURFACE_FOAM", new FloatControl(0.0f), ShaderStage.Fragment); public static BlockFieldDescriptor DeepFoam = new BlockFieldDescriptor(name, "DeepFoam", "DeepFoam", "SURFACEDESCRIPTION_DEEP_FOAM", new FloatControl(0.0f), ShaderStage.Fragment); public static BlockFieldDescriptor SimulationMask = new BlockFieldDescriptor(name, "SimulationMask", "SimulationMask", "SURFACEDESCRIPTION_SIMULATION_MASK", new Vector3Control(Vector3.one), ShaderStage.Fragment); @@ -155,6 +158,7 @@ namespace UnityEditor.Rendering.HighDefinition.ShaderGraph return new BlockFieldDescriptor[] { Deformation, + DeformationHorizontal, SurfaceFoam, DeepFoam, SimulationMask, @@ -170,7 +174,10 @@ namespace UnityEditor.Rendering.HighDefinition.ShaderGraph public override void GetActiveBlocks(ref TargetActiveBlockContext context) { if (m_Data.affectsDeformation) + { context.AddBlock(WaterDecalBlocks.Deformation); + context.AddBlock(WaterDecalBlocks.DeformationHorizontal); + } if (m_Data.affectsFoam) { context.AddBlock(WaterDecalBlocks.SurfaceFoam); @@ -297,10 +304,19 @@ namespace UnityEditor.Rendering.HighDefinition.ShaderGraph #region Defines struct WaterDecalDefines { - static readonly KeywordDescriptor deformFoamKeyword = new KeywordDescriptor + static readonly KeywordDescriptor deformKeyword = new KeywordDescriptor + { + displayName = "Deformation Pass", + referenceName = "PASS_DEFORMATION", + type = KeywordType.Boolean, + definition = KeywordDefinition.Predefined, + stages = KeywordShaderStage.Fragment, + }; + + static readonly KeywordDescriptor foamKeyword = new KeywordDescriptor { displayName = "Deformation And Foam Pass", - referenceName = "PASS_DEFORMATION_AND_FOAM", + referenceName = "PASS_FOAM", type = KeywordType.Boolean, definition = KeywordDefinition.Predefined, stages = KeywordShaderStage.Fragment, @@ -335,7 +351,8 @@ namespace UnityEditor.Rendering.HighDefinition.ShaderGraph static Dictionary s_PassDefines = new() { - { WaterDecal.PassType.DeformationAndFoam, deformFoamKeyword }, + { WaterDecal.PassType.Foam, foamKeyword }, + { WaterDecal.PassType.Deformation, deformKeyword }, { WaterDecal.PassType.SimulationMask, maskKeyword }, { WaterDecal.PassType.LargeCurrent, largeKeyword }, { WaterDecal.PassType.RipplesCurrent, ripplesKeyword }, @@ -395,8 +412,10 @@ namespace UnityEditor.Rendering.HighDefinition.ShaderGraph KeywordCollection keywords = new(); switch (pass) { - case WaterDecal.PassType.DeformationAndFoam: + case WaterDecal.PassType.Deformation: keywords.Add(new KeywordCollection { { AffectsDeformation, new FieldCondition(WaterDecalFields.AffectsDeformation, data.affectsDeformation) } }); + break; + case WaterDecal.PassType.Foam: keywords.Add(new KeywordCollection { { AffectsFoam, new FieldCondition(WaterDecalFields.AffectsFoam, data.affectsFoam) } }); break; case WaterDecal.PassType.SimulationMask: diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/WaterSubTarget.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/WaterSubTarget.cs index fb38cedf..860def89 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/WaterSubTarget.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/WaterSubTarget.cs @@ -461,8 +461,8 @@ namespace UnityEditor.Rendering.HighDefinition.ShaderGraph GenerateWaterGBufferPass(false, true, systemData.debugSymbols), // Low res gbuffer GenerateWaterGBufferPass(true, false, systemData.debugSymbols), - // Debug pass, always use tessellation to reduce variants - GenerateWaterDebugPass(false, true, systemData.debugSymbols), + // Debug pass, never use tessellation to reduce variants + GenerateWaterDebugPass(false, false, systemData.debugSymbols), GenerateWaterDebugPass(true, false, systemData.debugSymbols), }; return passes; diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/CustomPass/DrawRenderersCustomPassDrawer.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/CustomPass/DrawRenderersCustomPassDrawer.cs index 0f8e081b..db30da3c 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/CustomPass/DrawRenderersCustomPassDrawer.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/CustomPass/DrawRenderersCustomPassDrawer.cs @@ -43,6 +43,8 @@ namespace UnityEditor.Rendering.HighDefinition public static GUIContent overrideShaderPass = new GUIContent("Pass Name", "The pass for the override material to use."); public static GUIContent overrideMode = new GUIContent("Override Mode", "Choose the material override mode. Material: override the material and all properties. Shader: override the shader and maintain current properties."); public static GUIContent sortingCriteria = new GUIContent("Sorting", "Sorting settings used to render objects in a certain order."); + public static GUIContent variableRateShading = new GUIContent("Variable Rate Shading", "Enable variable rate shading. Requires a generated shading-rate-image texture."); + public static GUIContent shaderPass = new GUIContent("Shader Pass", "Sets which pass will be used to render the materials. If the pass does not exist, the material will not be rendered."); //Depth Settings @@ -128,6 +130,9 @@ namespace UnityEditor.Rendering.HighDefinition SerializedProperty m_SortingCriteria; SerializedProperty m_ShaderPass; + // VRS + SerializedProperty m_VariableRateShading; + // Override depth state SerializedProperty m_OverrideDepthState; SerializedProperty m_DepthCompareFunction; @@ -174,6 +179,9 @@ namespace UnityEditor.Rendering.HighDefinition m_OverrideMode = customPass.FindPropertyRelative("overrideMode"); m_SortingCriteria = customPass.FindPropertyRelative("sortingCriteria"); + // Variable Rate Shading options + m_VariableRateShading = customPass.FindPropertyRelative("variableRateShading"); + // Depth options m_OverrideDepthState = customPass.FindPropertyRelative("overrideDepthState"); m_DepthCompareFunction = customPass.FindPropertyRelative("depthCompareFunction"); @@ -240,6 +248,9 @@ namespace UnityEditor.Rendering.HighDefinition EditorGUI.indentLevel--; } + + EditorGUI.PropertyField(rect, m_VariableRateShading, Styles.variableRateShading); + rect.y += Styles.defaultLineSpace; } // Tell if we need to show a warning for rendering opaque object and we're in deferred. @@ -544,6 +555,7 @@ namespace UnityEditor.Rendering.HighDefinition #endif height += Styles.defaultLineSpace; // sorting criteria; + height += Styles.defaultLineSpace; // vrs } return height; diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/CustomPass/VrsCustomPassDrawer.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/CustomPass/VrsCustomPassDrawer.cs new file mode 100644 index 00000000..ad3d6660 --- /dev/null +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/CustomPass/VrsCustomPassDrawer.cs @@ -0,0 +1,49 @@ +using UnityEngine; +using UnityEditor; +using UnityEngine.Rendering; +using UnityEngine.Rendering.HighDefinition; + +namespace UnityEditor.Rendering.HighDefinition +{ + /// + /// FullScreen custom pass drawer + /// + [CustomPassDrawerAttribute(typeof(VrsCustomPass))] + class VrsCustomPassDrawer : CustomPassDrawer + { + private class Styles + { + public static float defaultLineSpace = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + public static float helpBoxHeight = EditorGUIUtility.singleLineHeight * 2; + + public static GUIContent vrsColorMask = new GUIContent("Color Mask", "Color mask texture used to generate the shading-rate-image texture for variable rate shading."); + } + + // Vrs pass + SerializedProperty m_VrsColorMask; + + protected override PassUIFlag commonPassUIFlags => PassUIFlag.Name; + protected override void Initialize(SerializedProperty customPass) + { + m_VrsColorMask = customPass.FindPropertyRelative("vrsColorMask"); + } + + protected override void DoPassGUI(SerializedProperty customPass, Rect rect) + { + if (HDRenderPipeline.currentAsset == null || !HDRenderPipeline.currentAsset.currentPlatformRenderPipelineSettings.supportVariableRateShading) + HDEditorUtils.QualitySettingsHelpBox("The current HDRP asset does not support Variable Rate Shading.", MessageType.Error, + HDRenderPipelineUI.ExpandableGroup.Rendering, "m_RenderPipelineSettings.supportVariableRateShading"); + + EditorGUI.PropertyField(rect, m_VrsColorMask, Styles.vrsColorMask); + rect.y += Styles.defaultLineSpace; + } + + protected override float GetPassHeight(SerializedProperty customPass) + { + int lineCount = 1; // m_vrsColorMask + int height = (int)(Styles.defaultLineSpace * lineCount); + + return height; + } + } +} diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/CustomPass/VrsCustomPassDrawer.cs.meta b/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/CustomPass/VrsCustomPassDrawer.cs.meta new file mode 100644 index 00000000..9b003b28 --- /dev/null +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/CustomPass/VrsCustomPassDrawer.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: dcb375c3fc1741bd93c885cc6daf61d8 +timeCreated: 1731089796 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/HDRenderPipelineUI.Skin.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/HDRenderPipelineUI.Skin.cs index cc23e11f..b2a8067c 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/HDRenderPipelineUI.Skin.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/HDRenderPipelineUI.Skin.cs @@ -127,6 +127,7 @@ namespace UnityEditor.Rendering.HighDefinition public static readonly GUIContent supportWaterFoamContent = EditorGUIUtility.TrTextContent("Foam", "When enabled, HDRP allocates additional memory to support water foam."); public static readonly GUIContent foamAtlasSizeContent = EditorGUIUtility.TrTextContent("Foam Atlas Size", "Specifies the size of the atlas used to store texture water foam."); public static readonly GUIContent supportWaterExclusionContent = EditorGUIUtility.TrTextContent("Exclusion", "When enabled, HDRP allocates a stencil bit to support water excluders."); + public static readonly GUIContent supportWaterHorizontalDeformationContent = EditorGUIUtility.TrTextContent("Horizontal Deformation", "When enabled, HDRP allocates additional memory to support water horizontal deformation. Enabling this property limits compatibility with other water system features (like scripts interactions or underwater), refer to the documentation for more details."); // High Quality Line Rendering public static readonly GUIContent highQualityLineRenderingSubTitle = EditorGUIUtility.TrTextContent("High Quality Line Rendering"); @@ -154,6 +155,7 @@ namespace UnityEditor.Rendering.HighDefinition public static readonly GUIContent supportSSGIContent = EditorGUIUtility.TrTextContent("Screen Space Global Illumination", "When enabled, HDRP allocates memory for processing screen space global illumination (SSGI). This allows you to use SSGI in your Unity Project."); public static readonly GUIContent renderingLayerMaskBuffer = EditorGUIUtility.TrTextContent("Rendering Layer Mask Buffer", "When enabled, HDRP writes Rendering Layer Mask of Renderers to a buffer target that can be sampled in a shader in order to create fullscreen effects.\nThis comes with a performance and a memory cost."); public static readonly GUIContent supportedSSSContent = EditorGUIUtility.TrTextContent("Subsurface Scattering", "When enabled, HDRP allocates memory for processing subsurface scattering (SSS). This allows you to use SSS in your Unity Project."); + public static readonly GUIContent subsurfaceScatteringBorderAttenuation = EditorGUIUtility.TrTextContent("Support Border Attenuation", "When enabled, the subsurface scattering takes into account the occlusion of near objects with no subsurface-scattering or a different diffusion profile."); public static readonly GUIContent sssSampleBudget = EditorGUIUtility.TrTextContent("Sample Budget", "Maximum number of samples the Subsurface Scattering algorithm is allowed to take."); public static readonly GUIContent sssDownsampleSteps = EditorGUIUtility.TrTextContent("Downsample Level", "The number of downsample steps done to the source irradance textrure before it is used by the Subsurface Scattering algorithm. Higher value will improve performance, but might lower quality."); public static readonly GUIContent supportVolumetricFogContent = EditorGUIUtility.TrTextContent("Volumetric Fog", "When enabled, HDRP allocates Shader variants and memory for volumetric effects. This allows you to use volumetric lighting and fog in your Unity Project."); @@ -162,6 +164,7 @@ namespace UnityEditor.Rendering.HighDefinition public static readonly GUIContent supportLightLayerContent = EditorGUIUtility.TrTextContent("Light Layers", "When enabled, HDRP allocates memory for processing Light Layers. This allows you to use Light Layers in your Unity Project. For deferred rendering, this allocation includes an extra render target in memory and extra cost."); public static readonly GUIContent colorBufferFormatContent = EditorGUIUtility.TrTextContent("Color Buffer Format", "Specifies the format used by the scene color render target. R11G11B10 is a faster option and should have sufficient precision."); public static readonly GUIContent supportCustomPassContent = EditorGUIUtility.TrTextContent("Custom Pass", "When enabled, HDRP allocates a custom pass buffer. It also enable custom passes inside Custom Pass Volume components."); + public static readonly GUIContent supportVariableRateShadingContent = EditorGUIUtility.TrTextContent("Variable Rate Shading", "When enabled, HDRP enables the usage of variable rate shading in custom passes."); public static readonly GUIContent customBufferFormatContent = EditorGUIUtility.TrTextContent("Custom Buffer Format", "Specifies the format used by the custom pass render target."); public static readonly GUIContent supportLitShaderModeContent = EditorGUIUtility.TrTextContent("Lit Shader Mode", "Specifies the rendering modes HDRP supports for Lit Shaders. HDRP removes all allocated memory and Shader variants for modes you do not specify."); public static readonly GUIContent MSAASampleCountContent = EditorGUIUtility.TrTextContent("Multisample Anti-aliasing Quality", "Specifies the default quality for MSAA. Set Lit Shader Mode to Forward Only or Both to use this feature.\nMSAA is not supported when water or raytracing is enabled"); @@ -351,8 +354,8 @@ namespace UnityEditor.Rendering.HighDefinition public static readonly GUIContent volumeProfileLabel = EditorGUIUtility.TrTextContent("Volume Profile", "Settings that will override the values defined in the Default Volume Profile set in the Render Pipeline Global settings. Local Volumes inside scenes may override these settings further."); public static System.Lazy volumeProfileContextMenuStyle = new(() => new GUIStyle(CoreEditorStyles.contextMenuStyle) { margin = new RectOffset(0, 1, 3, 0) }); - public static readonly GUIContent[] shadowBitDepthNames = { new GUIContent("32 bit"), new GUIContent("16 bit") }; - public static readonly int[] shadowBitDepthValues = { (int)DepthBits.Depth32, (int)DepthBits.Depth16 }; + public static readonly GUIContent[] shadowBitDepthNames = { new GUIContent("32 bit"), new GUIContent("16 bit"), new GUIContent("24 bit") }; + public static readonly int[] shadowBitDepthValues = { (int)DepthBits.Depth32, (int)DepthBits.Depth16, (int)DepthBits.Depth24 }; public static readonly GUIContent gpuResidentDrawerMode = EditorGUIUtility.TrTextContent("GPU Resident Drawer", "Enables draw submission through the GPU Resident Drawer, which can improve CPU performance"); public static readonly GUIContent smallMeshScreenPercentage = EditorGUIUtility.TrTextContent("Small-Mesh Screen-Percentage", "Default minimum screen percentage (0-20%) gpu-driven Renderers can cover before getting culled. If a Renderer is part of a LODGroup, this will be ignored."); diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/HDRenderPipelineUI.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/HDRenderPipelineUI.cs index a05e56c7..4fbbdad5 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/HDRenderPipelineUI.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/HDRenderPipelineUI.cs @@ -987,6 +987,9 @@ namespace UnityEditor.Rendering.HighDefinition // Exclusion EditorGUILayout.PropertyField(serialized.renderPipelineSettings.supportWaterExclusion, Styles.supportWaterExclusionContent); + // Horizontal Deformation + EditorGUILayout.PropertyField(serialized.renderPipelineSettings.supportWaterHorizontalDeformation, Styles.supportWaterHorizontalDeformationContent); + // CPU Simulation EditorGUILayout.PropertyField(serialized.renderPipelineSettings.waterScriptInteractionsMode); @@ -1279,6 +1282,10 @@ namespace UnityEditor.Rendering.HighDefinition { ++EditorGUI.indentLevel; EditorGUILayout.PropertyField(serialized.renderPipelineSettings.customBufferFormat, Styles.customBufferFormatContent); + + // VRS is consumed only by custom passes for the time being; put it dependent in the settings too + EditorGUILayout.PropertyField(serialized.renderPipelineSettings.supportVariableRateShading, Styles.supportVariableRateShadingContent); + --EditorGUI.indentLevel; } @@ -1382,6 +1389,9 @@ namespace UnityEditor.Rendering.HighDefinition || !serialized.renderPipelineSettings.supportSubsurfaceScattering.boolValue)) { ++EditorGUI.indentLevel; + + EditorGUILayout.PropertyField(serialized.renderPipelineSettings.subsurfaceScatteringBorderAttenuation, Styles.subsurfaceScatteringBorderAttenuation); + serialized.renderPipelineSettings.sssSampleBudget.ValueGUI(Styles.sssSampleBudget); EditorGUI.BeginChangeCheck(); diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/SerializedRenderPipelineSettings.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/SerializedRenderPipelineSettings.cs index 6a153bbb..b96f3ff0 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/SerializedRenderPipelineSettings.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/RenderPipeline/Settings/SerializedRenderPipelineSettings.cs @@ -24,6 +24,7 @@ namespace UnityEditor.Rendering.HighDefinition public SerializedProperty supportSSAO; public SerializedProperty supportSSGI; public SerializedProperty supportSubsurfaceScattering; + public SerializedProperty subsurfaceScatteringBorderAttenuation; public SerializedScalableSetting sssSampleBudget; public SerializedScalableSetting sssDownsampleSteps; [FormerlySerializedAs("supportVolumetric")] @@ -35,6 +36,7 @@ namespace UnityEditor.Rendering.HighDefinition public SerializedProperty waterSimulationResolution; public SerializedProperty supportWaterExclusion; public SerializedProperty supportWaterDecals; + public SerializedProperty supportWaterHorizontalDeformation; public SerializedProperty waterDecalAtlasSize; public SerializedProperty maximumWaterDecalCount; public SerializedProperty waterScriptInteractionsMode; @@ -48,6 +50,7 @@ namespace UnityEditor.Rendering.HighDefinition public SerializedProperty supportedLitShaderMode; public SerializedProperty colorBufferFormat; public SerializedProperty supportCustomPass; + public SerializedProperty supportVariableRateShading; public SerializedProperty customBufferFormat; public SerializedProperty renderingLayerMaskBuffer; public SerializedScalableSetting planarReflectionResolution; @@ -81,7 +84,7 @@ namespace UnityEditor.Rendering.HighDefinition public SerializedProperty supportScreenSpaceLensFlare; public SerializedProperty supportDataDrivenLensFlare; - + public SerializedGlobalLightLoopSettings lightLoopSettings; public SerializedHDShadowInitParameters hdShadowInitParams; public SerializedGlobalDecalSettings decalSettings; @@ -115,6 +118,7 @@ namespace UnityEditor.Rendering.HighDefinition supportSSAO = root.Find((RenderPipelineSettings s) => s.supportSSAO); supportSSGI = root.Find((RenderPipelineSettings s) => s.supportSSGI); supportSubsurfaceScattering = root.Find((RenderPipelineSettings s) => s.supportSubsurfaceScattering); + subsurfaceScatteringBorderAttenuation = root.Find((RenderPipelineSettings s) => s.subsurfaceScatteringAttenuation); sssSampleBudget = new SerializedScalableSetting(root.Find((RenderPipelineSettings s) => s.sssSampleBudget)); sssDownsampleSteps = new SerializedScalableSetting(root.Find((RenderPipelineSettings s) => s.sssDownsampleSteps)); supportVolumetrics = root.Find((RenderPipelineSettings s) => s.supportVolumetrics); @@ -125,6 +129,7 @@ namespace UnityEditor.Rendering.HighDefinition waterSimulationResolution = root.Find((RenderPipelineSettings s) => s.waterSimulationResolution); supportWaterExclusion = root.Find((RenderPipelineSettings s) => s.supportWaterExclusion); supportWaterDecals = root.Find((RenderPipelineSettings s) => s.supportWaterDecals); + supportWaterHorizontalDeformation = root.Find((RenderPipelineSettings s) => s.supportWaterHorizontalDeformation); waterDecalAtlasSize = root.Find((RenderPipelineSettings s) => s.waterDecalAtlasSize); maximumWaterDecalCount = root.Find((RenderPipelineSettings s) => s.maximumWaterDecalCount); waterScriptInteractionsMode = root.Find((RenderPipelineSettings s) => s.waterScriptInteractionsMode); @@ -139,6 +144,7 @@ namespace UnityEditor.Rendering.HighDefinition customBufferFormat = root.Find((RenderPipelineSettings s) => s.customBufferFormat); renderingLayerMaskBuffer = root.Find((RenderPipelineSettings s) => s.renderingLayerMaskBuffer); supportCustomPass = root.Find((RenderPipelineSettings s) => s.supportCustomPass); + supportVariableRateShading = root.Find((RenderPipelineSettings s) => s.supportVariableRateShading); supportedLitShaderMode = root.Find((RenderPipelineSettings s) => s.supportedLitShaderMode); planarReflectionResolution = new SerializedScalableSetting(root.Find((RenderPipelineSettings s) => s.planarReflectionResolution)); cubeReflectionResolution = new SerializedScalableSetting(root.Find((RenderPipelineSettings s) => s.cubeReflectionResolution)); @@ -177,7 +183,7 @@ namespace UnityEditor.Rendering.HighDefinition lowresTransparentSettings = new SerializedLowResTransparencySettings(root.Find((RenderPipelineSettings s) => s.lowresTransparentSettings)); xrSettings = new SerializedXRSettings(root.Find((RenderPipelineSettings s) => s.xrSettings)); postProcessQualitySettings = new SerializedPostProcessingQualitySettings(root.Find((RenderPipelineSettings s) => s.postProcessQualitySettings)); - + supportScreenSpaceLensFlare = root.Find((RenderPipelineSettings s) => s.supportScreenSpaceLensFlare); supportDataDrivenLensFlare = root.Find((RenderPipelineSettings s) => s.supportDataDrivenLensFlare); diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Outputs/VFXLitSphereOutput.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Outputs/VFXLitSphereOutput.cs index f1cbf74a..8caac1c7 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Outputs/VFXLitSphereOutput.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Outputs/VFXLitSphereOutput.cs @@ -43,7 +43,7 @@ namespace UnityEditor.VFX.HDRP { get { - var orient = VFXBlock.CreateImplicitBlock(GetData()); + var orient = GetOrCreateImplicitBlock(GetData()); orient.mode = Orient.Mode.FaceCameraPosition; yield return orient; } diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/Mesh/PassDepthOrMV.template b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/Mesh/PassDepthOrMV.template index d9912909..b003e52f 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/Mesh/PassDepthOrMV.template +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/Mesh/PassDepthOrMV.template @@ -99,4 +99,4 @@ ${VFXHDRPLitFillVaryings} ${VFXEnd} ${VFXInclude("Shaders/ParticleMeshes/Pass.template")} -${VFXPassDepthCommonFragmentLit} +${VFXIncludeRP("Templates/VFXPassDepthCommonFragmentLit.template")} diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/Mesh/PassForward.template b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/Mesh/PassForward.template index b63ab12d..f10abbe1 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/Mesh/PassForward.template +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/Mesh/PassForward.template @@ -20,10 +20,9 @@ Pass #pragma multi_compile_fragment _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 #endif #pragma multi_compile _ DEBUG_DISPLAY - //#pragma enable_d3d11_debug_symbols ${VFXIncludeRP("VFXLitVaryings.template")} - ${VFXIncludeRP("VFXVertexProbeSampling.template"),VFX_MATERIAL_TYPE_SIX_WAY_SMOKE} + ${VFXIncludeRP("VFXSixWayIncludes.template"),VFX_MATERIAL_TYPE_SIX_WAY_SMOKE} struct ps_input { float4 pos : SV_POSITION; diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/PlanarPrimitive/DXR/Lit/IntersectionFunctions.template b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/PlanarPrimitive/DXR/Lit/IntersectionFunctions.template index a18cbf4b..c481d57b 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/PlanarPrimitive/DXR/Lit/IntersectionFunctions.template +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/PlanarPrimitive/DXR/Lit/IntersectionFunctions.template @@ -1,5 +1,5 @@ // Needs to be included after the VFX includes - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/VFXGraph/Shaders/VFXRayTracingCommon.hlsl" + #include "Packages/com.unity.visualeffectgraph/Shaders/VFXRayTracingCommon.hlsl" // Visibility function required for the intersection shader bool AABBPrimitiveIsVisible(RayTracingProceduralData rtProceduralData, float2 uv) { diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/PlanarPrimitive/DXR/Unlit/EvaluateMaterialData.template b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/PlanarPrimitive/DXR/Unlit/EvaluateMaterialData.template index d2ba12ff..fa694289 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/PlanarPrimitive/DXR/Unlit/EvaluateMaterialData.template +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/PlanarPrimitive/DXR/Unlit/EvaluateMaterialData.template @@ -9,6 +9,7 @@ void EvaluateUnlitMaterialData(in AttributeData attributeData, out float4 outCol // Load the VFX attributes that we need for this ${VFXLoadAttributes} ${VFXProcessBlocks} + float2 uv = attributeData.barycentrics; ${VFXGetColorRT} // Return the color diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/PlanarPrimitive/DXR/Unlit/IntersectionFunctions.template b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/PlanarPrimitive/DXR/Unlit/IntersectionFunctions.template index aa26e18d..34a5752b 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/PlanarPrimitive/DXR/Unlit/IntersectionFunctions.template +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/PlanarPrimitive/DXR/Unlit/IntersectionFunctions.template @@ -1,5 +1,5 @@ // Needs to be included after the VFX includes - #include "Packages/com.unity.render-pipelines.high-definition/Runtime/VFXGraph/Shaders/VFXRayTracingCommon.hlsl" + #include "Packages/com.unity.visualeffectgraph/Shaders/VFXRayTracingCommon.hlsl" // Visibility function required for the intersection shader bool AABBPrimitiveIsVisible(RayTracingProceduralData rtProceduralData, float2 uv) { diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/PlanarPrimitive/PassDepthOrMV.template b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/PlanarPrimitive/PassDepthOrMV.template index ef88ff7e..8f518131 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/PlanarPrimitive/PassDepthOrMV.template +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/PlanarPrimitive/PassDepthOrMV.template @@ -102,4 +102,4 @@ ${VFXHDRPLitFillVaryings} ${VFXEnd} ${VFXInclude("Shaders/ParticlePlanarPrimitives/Pass.template")} -${VFXPassDepthCommonFragmentLit} +${VFXIncludeRP("Templates/VFXPassDepthCommonFragmentLit.template")} diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/PlanarPrimitive/PassForward.template b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/PlanarPrimitive/PassForward.template index 184fa7c1..565d6708 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/PlanarPrimitive/PassForward.template +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/PlanarPrimitive/PassForward.template @@ -21,10 +21,9 @@ Pass #pragma multi_compile_fragment _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 #endif #pragma multi_compile _ DEBUG_DISPLAY - //#pragma enable_d3d11_debug_symbols ${VFXIncludeRP("VFXLitVaryings.template")} - ${VFXIncludeRP("VFXVertexProbeSampling.template"),VFX_MATERIAL_TYPE_SIX_WAY_SMOKE} + ${VFXIncludeRP("VFXSixWayIncludes.template"),VFX_MATERIAL_TYPE_SIX_WAY_SMOKE} struct ps_input { diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/VFXPassDepthCommonFragmentLit.template b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/VFXPassDepthCommonFragmentLit.template new file mode 100644 index 00000000..bc8a47a3 --- /dev/null +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/VFXPassDepthCommonFragmentLit.template @@ -0,0 +1,117 @@ +#if VFX_PASSDEPTH == VFX_PASSDEPTH_MOTION_VECTOR +${VFXPassVelocityDefine} +#elif VFX_PASSDEPTH == VFX_PASSDEPTH_SHADOW +${VFXPassShadowDefine} +#else +${VFXPassDepthDefine} +#endif +${VFXIncludeRP("VFXLit.template")} + +${SHADERGRAPH_PIXEL_CODE_DEPTHONLY} + +#if VFX_PASSDEPTH == VFX_PASSDEPTH_SELECTION +int _ObjectId; +int _PassValue; +#elif VFX_PASSDEPTH == VFX_PASSDEPTH_PICKING +float4 _SelectionID; +#endif + +#pragma fragment frag +void frag(ps_input i +#if USE_DOUBLE_SIDED + , bool frontFace : SV_IsFrontFace +#endif +#if VFX_PASSDEPTH == VFX_PASSDEPTH_MOTION_VECTOR + #ifdef WRITE_MSAA_DEPTH + // We need the depth color as SV_Target0 for alpha to coverage + , out float4 outDepthColor : SV_Target0 + , out float4 outMotionVector : SV_Target1 + #ifdef WRITE_NORMAL_BUFFER + , out float4 outNormalBuffer : SV_Target2 + #endif + #else + // When no MSAA, the motion vector is always the first buffer + , out float4 outMotionVector : SV_Target0 + #ifdef WRITE_NORMAL_BUFFER + , out float4 outNormalBuffer : SV_Target1 + #endif + #endif +#elif VFX_PASSDEPTH == VFX_PASSDEPTH_ACTUAL + #ifdef WRITE_MSAA_DEPTH + // We need the depth color as SV_Target0 for alpha to coverage + , out float4 outDepthColor : SV_Target0 + #ifdef WRITE_NORMAL_BUFFER + , out float4 outNormalBuffer : SV_Target1 + #endif + #elif defined(WRITE_NORMAL_BUFFER) + , out float4 outNormalBuffer : SV_Target0 + #endif +#elif VFX_PASSDEPTH == VFX_PASSDEPTH_SELECTION || VFX_PASSDEPTH == VFX_PASSDEPTH_PICKING + , out float4 outColor : SV_Target0 +#endif +) +{ + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); + VFXTransformPSInputs(i); + ${VFXComputeNormalWS} + + #ifdef VFX_SHADERGRAPH + ${VFXAdditionalInterpolantsPreparation} + ${SHADERGRAPH_PIXEL_CALL_DEPTHONLY} + float alpha = OUTSG.${SHADERGRAPH_PARAM_ALPHA}; + #else + + float alpha = VFXGetFragmentColor(i).a; + + #if HDRP_USE_BASE_COLOR_MAP_ALPHA + alpha *= VFXGetTextureColor(VFX_SAMPLER(baseColorMap),i).a; + #endif + #if VFX_MATERIAL_TYPE_SIX_WAY_SMOKE + #ifndef VFX_VARYING_NORMAL + const VFXUVData uvData = GetUVData(i); + #endif + alpha *= SampleTexture(VFX_SAMPLER(positiveAxesLightmap),uvData).a; + #if VFX_SIX_WAY_USE_ALPHA_REMAP + alpha = SampleCurve(i.VFX_VARYING_ALPHA_REMAP, alpha); + #endif + #endif + #endif + VFXClipFragmentColor(alpha,i); + + #ifdef WRITE_NORMAL_BUFFER + #ifndef VFX_SHADERGRAPH + VFXComputePixelOutputToNormalBuffer(i,normalWS,uvData,outNormalBuffer); + #else + #if HAS_SHADERGRAPH_PARAM_NORMAL + float3 n = OUTSG.Normal_8; + normalWS = mul(n,tbn); + #endif + SurfaceData surface = (SurfaceData)0; + surface.normalWS = normalWS; + EncodeIntoNormalBuffer(ConvertSurfaceDataToNormalData(surface), outNormalBuffer); + #endif + #endif + + #ifdef WRITE_MSAA_DEPTH + outDepthColor = i.VFX_VARYING_POSCS.z; + #if VFX_USE_ALPHA_TO_MASK + outDepthColor.a = alpha; + #endif + #endif + + #if VFX_PASSDEPTH == VFX_PASSDEPTH_MOTION_VECTOR + ${VFXComputeOutputMotionVector} + outMotionVector = encodedMotionVector; + #elif VFX_PASSDEPTH == VFX_PASSDEPTH_SELECTION + // We use depth prepass for scene selection in the editor, this code allow to output the outline correctly + outColor = float4(_ObjectId, _PassValue, 1.0, 1.0); + #elif VFX_PASSDEPTH == VFX_PASSDEPTH_PICKING + outColor = _SelectionID; + #elif VFX_PASSDEPTH == VFX_PASSDEPTH_ACTUAL + //void + #elif VFX_PASSDEPTH == VFX_PASSDEPTH_SHADOW + //void + #else + #error VFX_PASSDEPTH undefined + #endif +} diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/VFXPassDepthCommonFragmentLit.template.meta b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/VFXPassDepthCommonFragmentLit.template.meta new file mode 100644 index 00000000..54c62fd3 --- /dev/null +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/Templates/VFXPassDepthCommonFragmentLit.template.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 897583fdf4fd456992f4162e0c64ceb2 +timeCreated: 1720611237 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/VFXLitVaryings.template b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/VFXLitVaryings.template index 93f1da5d..6ee83352 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/VFXLitVaryings.template +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/VFXLitVaryings.template @@ -1,6 +1,7 @@ #define HDRP_NEEDS_UVS (HDRP_USE_BASE_COLOR_MAP || HDRP_USE_MASK_MAP || USE_NORMAL_MAP || HDRP_USE_EMISSIVE_MAP) #define HDRP_USE_EMISSIVE (HDRP_USE_EMISSIVE_MAP || HDRP_USE_EMISSIVE_COLOR || HDRP_USE_ADDITIONAL_EMISSIVE_COLOR) +${VFXIncludeRP("VFXVertexProbeSampling.template"), VFX_MATERIAL_TYPE_SIX_WAY_SMOKE} ${VFXInclude("Shaders/SixWay/SixWayVaryings.template"), VFX_MATERIAL_TYPE_SIX_WAY_SMOKE} ${VFXBegin:VFXHDRPLitVaryingsMacros} diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/VFXPasses.template b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/VFXPasses.template index 1ce02c7d..e88ce588 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/VFXPasses.template +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/VFXPasses.template @@ -22,139 +22,6 @@ ${VFXBegin:VFXPassDepthAdditionalPragma}#pragma multi_compile _ WRITE_MSAA_DEPTH ${VFXBegin:VFXPassForwardAdditionalPragma}#pragma multi_compile _ DEBUG_DISPLAY${VFXEnd} ${VFXBegin:VFXPassVelocityAdditionalPragma}#pragma multi_compile _ WRITE_MSAA_DEPTH${VFXEnd} -${VFXBegin:VFXShaderGraphFunctionsInclude} -#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" -#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl" -#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl" -#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl" -#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl" -#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinGIUtilities.hlsl" -#ifndef SHADERPASS -#error Shaderpass should be defined at this stage. -#endif -#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderGraphFunctions.hlsl" -${VFXEnd} - -${VFXBegin:VFXPassDepthCommonFragmentLit} -#if VFX_PASSDEPTH == VFX_PASSDEPTH_MOTION_VECTOR -${VFXPassVelocityDefine} -#elif VFX_PASSDEPTH == VFX_PASSDEPTH_SHADOW -${VFXPassShadowDefine} -#else -${VFXPassDepthDefine} -#endif -${VFXIncludeRP("VFXLit.template")} - -${SHADERGRAPH_PIXEL_CODE_DEPTHONLY} - -#if VFX_PASSDEPTH == VFX_PASSDEPTH_SELECTION -int _ObjectId; -int _PassValue; -#elif VFX_PASSDEPTH == VFX_PASSDEPTH_PICKING -float4 _SelectionID; -#endif - -#pragma fragment frag -void frag(ps_input i -#if USE_DOUBLE_SIDED - , bool frontFace : SV_IsFrontFace -#endif -#if VFX_PASSDEPTH == VFX_PASSDEPTH_MOTION_VECTOR - #ifdef WRITE_MSAA_DEPTH - // We need the depth color as SV_Target0 for alpha to coverage - , out float4 outDepthColor : SV_Target0 - , out float4 outMotionVector : SV_Target1 - #ifdef WRITE_NORMAL_BUFFER - , out float4 outNormalBuffer : SV_Target2 - #endif - #else - // When no MSAA, the motion vector is always the first buffer - , out float4 outMotionVector : SV_Target0 - #ifdef WRITE_NORMAL_BUFFER - , out float4 outNormalBuffer : SV_Target1 - #endif - #endif -#elif VFX_PASSDEPTH == VFX_PASSDEPTH_ACTUAL - #ifdef WRITE_MSAA_DEPTH - // We need the depth color as SV_Target0 for alpha to coverage - , out float4 outDepthColor : SV_Target0 - #ifdef WRITE_NORMAL_BUFFER - , out float4 outNormalBuffer : SV_Target1 - #endif - #elif defined(WRITE_NORMAL_BUFFER) - , out float4 outNormalBuffer : SV_Target0 - #endif -#elif VFX_PASSDEPTH == VFX_PASSDEPTH_SELECTION || VFX_PASSDEPTH == VFX_PASSDEPTH_PICKING - , out float4 outColor : SV_Target0 -#endif -) -{ - UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); - VFXTransformPSInputs(i); - ${VFXComputeNormalWS} - - #ifdef VFX_SHADERGRAPH - ${VFXAdditionalInterpolantsPreparation} - ${SHADERGRAPH_PIXEL_CALL_DEPTHONLY} - float alpha = OUTSG.${SHADERGRAPH_PARAM_ALPHA}; - #else - - float alpha = VFXGetFragmentColor(i).a; - - #if HDRP_USE_BASE_COLOR_MAP_ALPHA - alpha *= VFXGetTextureColor(VFX_SAMPLER(baseColorMap),i).a; - #endif - #if VFX_MATERIAL_TYPE_SIX_WAY_SMOKE - #ifndef VFX_VARYING_NORMAL - const VFXUVData uvData = GetUVData(i); - #endif - alpha *= SampleTexture(VFX_SAMPLER(positiveAxesLightmap),uvData).a; - #if VFX_SIX_WAY_USE_ALPHA_REMAP - alpha = SampleCurve(i.VFX_VARYING_ALPHA_REMAP, alpha); - #endif - #endif - #endif - VFXClipFragmentColor(alpha,i); - - #ifdef WRITE_NORMAL_BUFFER - #ifndef VFX_SHADERGRAPH - VFXComputePixelOutputToNormalBuffer(i,normalWS,uvData,outNormalBuffer); - #else - #if HAS_SHADERGRAPH_PARAM_NORMAL - float3 n = OUTSG.Normal_8; - normalWS = mul(n,tbn); - #endif - SurfaceData surface = (SurfaceData)0; - surface.normalWS = normalWS; - EncodeIntoNormalBuffer(ConvertSurfaceDataToNormalData(surface), outNormalBuffer); - #endif - #endif - - #ifdef WRITE_MSAA_DEPTH - outDepthColor = i.VFX_VARYING_POSCS.z; - #if VFX_USE_ALPHA_TO_MASK - outDepthColor.a = alpha; - #endif - #endif - - #if VFX_PASSDEPTH == VFX_PASSDEPTH_MOTION_VECTOR - ${VFXComputeOutputMotionVector} - outMotionVector = encodedMotionVector; - #elif VFX_PASSDEPTH == VFX_PASSDEPTH_SELECTION - // We use depth prepass for scene selection in the editor, this code allow to output the outline correctly - outColor = float4(_ObjectId, _PassValue, 1.0, 1.0); - #elif VFX_PASSDEPTH == VFX_PASSDEPTH_PICKING - outColor = _SelectionID; - #elif VFX_PASSDEPTH == VFX_PASSDEPTH_ACTUAL - //void - #elif VFX_PASSDEPTH == VFX_PASSDEPTH_SHADOW - //void - #else - #error VFX_PASSDEPTH undefined - #endif -} -${VFXEnd} - ${VFXBegin:VFXPassFullScreenDebugCommonVertex} #if !defined(SHADER_API_METAL) if (_DebugFullScreenMode == FULLSCREENDEBUGMODE_VERTEX_DENSITY) @@ -174,7 +41,7 @@ ${VFXBegin:VFXPassFullScreenDebugCommonFragment} UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); VFXTransformPSInputs(i); VFX_FRAG_SETUP_INSTANCE_ID(i); - + #ifdef PLATFORM_SUPPORTS_PRIMITIVE_ID_IN_PIXEL_SHADER if (_DebugFullScreenMode == FULLSCREENDEBUGMODE_QUAD_OVERDRAW) { diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/VFXSixWayIncludes.template b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/VFXSixWayIncludes.template new file mode 100644 index 00000000..c0168dca --- /dev/null +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/VFXSixWayIncludes.template @@ -0,0 +1,6 @@ +#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl" +#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Lighting.hlsl" +#define HAS_LIGHTLOOP +#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoopDef.hlsl" +#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/SixWayLit/SixWaySmokeLit.hlsl" +#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.hlsl" diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/VFXSixWayIncludes.template.meta b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/VFXSixWayIncludes.template.meta new file mode 100644 index 00000000..8b356853 --- /dev/null +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/VFXSixWayIncludes.template.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c85765940feb499eb9a99878c4c7eea6 +timeCreated: 1720611358 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/VFXVertexProbeSampling.template b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/VFXVertexProbeSampling.template index ef731b89..677c8516 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/VFXVertexProbeSampling.template +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/VFXGraph/Shaders/VFXVertexProbeSampling.template @@ -26,13 +26,3 @@ float4 inTangent = o.VFX_VARYING_TANGENT; o.VFX_VARYING_BAKE_DIFFUSE_LIGHTING[2]); #endif ${VFXEnd} - - -#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl" -#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Lighting.hlsl" -#define HAS_LIGHTLOOP -#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoopDef.hlsl" -#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/SixWayLit/SixWaySmokeLit.hlsl" -#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.hlsl" - - diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Water/WaterDecal/WaterDecalSurfaceOptionsUIBlock.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Water/WaterDecal/WaterDecalSurfaceOptionsUIBlock.cs index 0ff5eb95..1acf10c7 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Water/WaterDecal/WaterDecalSurfaceOptionsUIBlock.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Water/WaterDecal/WaterDecalSurfaceOptionsUIBlock.cs @@ -10,11 +10,12 @@ namespace UnityEditor.Rendering.HighDefinition { public static GUIContent header { get; } = EditorGUIUtility.TrTextContent("Surface Options"); - public static GUIContent affectsDeformationText = new GUIContent("Affect Deformation", "When enabled, this decal can affect deformation.\nDeformation should be a normalized value between -1 and 1."); + public static GUIContent affectsDeformationText = new GUIContent("Affect Deformation", "When enabled, this decal can affect deformation."); public static GUIContent affectsFoamText = new GUIContent("Affect Foam", "When enabled, this decal can affect foam."); public static GUIContent affectsSimulationMaskText = new GUIContent("Affect Simulation Mask", "When enabled, this decal can affect simulation mask and simulation foam mask."); public static GUIContent affectsLargeCurrentText = new GUIContent("Affect Large Current", "When enabled, this decal can affect the swell current on oceans and the agitation current current on rivers."); public static GUIContent affectsRipplesCurrentText = new GUIContent("Affect Ripples Current", "When enabled, this decal can affect ripples current."); + public static string warningSupportWaterHorizontalDeformation = "The current HDRP Asset only support vertical water deformation. If the shader graph uses Horizontal Deformation output, enable horizontal deformation in the current HDRP asset to allow for 3D deformation."; } MaterialProperty affectsDeformation; @@ -68,6 +69,14 @@ namespace UnityEditor.Rendering.HighDefinition AffectProperty(affectsSimulationMask, Styles.affectsSimulationMaskText, true); AffectProperty(affectsLargeCurrent, Styles.affectsLargeCurrentText, true); AffectProperty(affectsRipplesCurrent, Styles.affectsRipplesCurrentText, true); + + // We display a warning in the inspector if affect deformation is checked and supportWaterHorizontalDeformation isn't in the current HDRP asset + bool supportHorizontalDeformation = HDRenderPipeline.currentAsset.currentPlatformRenderPipelineSettings.supportWaterHorizontalDeformation; + if (affectsDeformation != null && affectsDeformation.floatValue > 0.0f && !supportHorizontalDeformation) + { + EditorGUILayout.Space(); + HDEditorUtils.QualitySettingsHelpBox(Styles.warningSupportWaterHorizontalDeformation, MessageType.Warning, HDRenderPipelineUI.ExpandableGroup.Rendering, "m_RenderPipelineSettings.supportWaterHorizontalDeformation"); + } } } } diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Water/WaterSurface/VFX/SampleWaterSurface.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Water/WaterSurface/VFX/SampleWaterSurface.cs index 15e58885..8f36e0ff 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Water/WaterSurface/VFX/SampleWaterSurface.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Water/WaterSurface/VFX/SampleWaterSurface.cs @@ -20,9 +20,7 @@ namespace UnityEditor.Rendering.HighDefinition } } } - - - [VFXHelpURL("Operator-SampleWaterSurface")] + [VFXInfo(category = "Sampling")] class SampleWaterSurface : VFXOperator { @@ -64,7 +62,7 @@ namespace UnityEditor.Rendering.HighDefinition [Tooltip("Returns the normal of the Water Surface at the sampled position.")] public Vector3 normal; [Tooltip("Vector that gives the local current orientation.")] - public Vector3 currentDirectionWS; + public Vector2 currentDirectionWS; } public static(string errorID, string errorDesc) ComputeHDRPConfigurationError() @@ -121,7 +119,7 @@ namespace UnityEditor.Rendering.HighDefinition VFXExpression outputPosition = new VFXExpressionHLSL("ProjectPoint", ProjectPoint, typeof(Vector3), inputExpression, Array.Empty()); VFXExpression outputHeight = new VFXExpressionHLSL("EvaluateHeight", EvaluateHeight, typeof(float), inputExpression, Array.Empty()); VFXExpression outputNormal = new VFXExpressionHLSL("EvaluateNormal", EvaluateNormal, typeof(Vector3), inputExpression, Array.Empty()); - VFXExpression outputCurrent = new VFXExpressionHLSL("EvaluateCurrent", EvaluateCurrent, typeof(Vector3), inputExpression, Array.Empty()); + VFXExpression outputCurrent = new VFXExpressionHLSL("EvaluateCurrent", EvaluateCurrent, typeof(Vector2), inputExpression, Array.Empty()); return new [] { outputPosition, outputHeight, outputNormal, outputCurrent }; } } diff --git a/Packages/com.unity.render-pipelines.high-definition/Editor/Wizard/HDWizard.UserSettings.cs b/Packages/com.unity.render-pipelines.high-definition/Editor/Wizard/HDWizard.UserSettings.cs index 198b2176..f69d0c22 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Editor/Wizard/HDWizard.UserSettings.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Editor/Wizard/HDWizard.UserSettings.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using UnityEditorInternal; using UnityEngine; namespace UnityEditor.Rendering.HighDefinition @@ -81,7 +82,13 @@ namespace UnityEditor.Rendering.HighDefinition public static bool wizardIsStartPopup { - get => instance.m_WizardPopupAtStart; + get + { + if (!InternalEditorUtility.isHumanControllingUs || AssetDatabase.IsAssetImportWorkerProcess()) + return false; + + return instance.m_WizardPopupAtStart; + } set { instance.m_WizardPopupAtStart = value; diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Compositor/CompositionLayer.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Compositor/CompositionLayer.cs index c75a63ad..5e2e61e2 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Compositor/CompositionLayer.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Compositor/CompositionLayer.cs @@ -247,7 +247,7 @@ namespace UnityEngine.Rendering.HighDefinition.Compositor // - is not shared between layers // - is not used in an mage/video layer (in this case the camera is not exposed at all, so it makes sense to let the compositor manage it) // - it does not force-clear the RT (the first layer of a stack, even if disabled by the user), still clears the RT - bool shouldClear = !enabled && m_LayerPositionInStack == 0 && m_Camera; + bool shouldClear = m_LayerPositionInStack == 0 && m_Camera; bool isImageOrVideo = (m_Type == LayerType.Image || m_Type == LayerType.Video); if (!isImageOrVideo && !hasLayerOverrides && !shouldClear && !compositor.IsThisCameraShared(m_Camera)) { @@ -287,7 +287,7 @@ namespace UnityEngine.Rendering.HighDefinition.Compositor if (m_OutputTarget != OutputTarget.CameraStack && m_RenderTarget == null) { // If we don't have a valid camera (zero width or height) avoid creating the RT - if (compositor.outputCamera.pixelWidth > 0 && compositor.outputCamera.pixelHeight > 0) + if (compositor.outputCamera && compositor.outputCamera.pixelWidth > 0 && compositor.outputCamera.pixelHeight > 0) { float resScale = EnumToScale(m_ResolutionScale); int scaledWidth = (int)(resScale * compositor.outputCamera.pixelWidth); @@ -615,15 +615,19 @@ namespace UnityEngine.Rendering.HighDefinition.Compositor { if (m_LayerCamera && m_Camera) { - m_LayerCamera.enabled = true; - m_LayerCamera.cullingMask = 0; var cameraData = m_LayerCamera.GetComponent(); var cameraDataOrig = m_Camera.GetComponent(); - cameraData.clearColorMode = cameraDataOrig.clearColorMode; - cameraData.clearDepth = true; + if (cameraData && cameraDataOrig) + { + m_LayerCamera.enabled = true; + m_LayerCamera.cullingMask = 0; + + cameraData.clearColorMode = cameraDataOrig.clearColorMode; + cameraData.clearDepth = true; - m_ClearsBackGround = true; + m_ClearsBackGround = true; + } } } diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs index 1c5c84cc..07f2a024 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs @@ -1078,6 +1078,7 @@ namespace UnityEngine.Rendering.HighDefinition { var container = new DebugUI.Container() { + displayName = "#MaterialRenderingLayers", isHiddenCallback = () => !IsDebuggingRenderingLayers(), children = { @@ -1099,45 +1100,17 @@ namespace UnityEngine.Rendering.HighDefinition } }; - var field = new DebugUI.BitField + var renderingLayersField = new DebugUI.RenderingLayerField() { nameAndTooltip = LightingStrings.LightLayersFilterLayers, - getter = () => data.lightingDebugSettings.debugLightLayersFilterMask, - setter = value => data.lightingDebugSettings.debugLightLayersFilterMask = (RenderingLayerMask)value, - enumType = typeof(RenderingLayerMask), - isHiddenCallback = () => data.lightingDebugSettings.debugSelectionLightLayers + getter = () => (uint)data.lightingDebugSettings.debugLightLayersFilterMask, + setter = value => data.lightingDebugSettings.debugLightLayersFilterMask = (RenderingLayerMask)(uint)value, + getRenderingLayerColor = index => data.lightingDebugSettings.debugRenderingLayersColors[index], + setRenderingLayerColor = (value, index) => data.lightingDebugSettings.debugRenderingLayersColors[index] = value, + isHiddenCallback = () => data.lightingDebugSettings.debugSelectionLightLayers, }; - var renderingLayers = new List(); - for (int i = 0; i < 32; i++) - renderingLayers.Add($"Unused Rendering Layer {i}"); - - var names = UnityEngine.RenderingLayerMask.GetDefinedRenderingLayerNames(); - for (int i = 0; i < names.Length; i++) - { - var index = UnityEngine.RenderingLayerMask.NameToRenderingLayer(names[i]); - renderingLayers[index] = names[i]; - } - - for (int i = 0; i < field.enumNames.Length - 1; i++) - field.enumNames[i + 1].text = renderingLayers[i]; - - container.children.Add(field); - - var layersColor = new DebugUI.Foldout() { nameAndTooltip = LightingStrings.LightLayersColor, flags = DebugUI.Flags.EditorOnly }; - for (int i = 0; i < renderingLayers.Count; i++) - { - int index = i; - layersColor.children.Add(new DebugUI.ColorField - { - displayName = renderingLayers[i], - flags = DebugUI.Flags.EditorOnly, - getter = () => data.lightingDebugSettings.debugRenderingLayersColors[index], - setter = value => data.lightingDebugSettings.debugRenderingLayersColors[index] = value - }); - } - - container.children.Add(layersColor); + container.children.Add(renderingLayersField); list.Add(container); } @@ -1247,7 +1220,6 @@ namespace UnityEngine.Rendering.HighDefinition public static readonly NameAndTooltip LightLayersUseSelectedLight = new() { name = "Filter Light Layers by Light", tooltip = "Highlight Renderers affected by the selected light." }; public static readonly NameAndTooltip LightLayersSwitchToLightShadowLayers = new() { name = "Use Light's Shadow Layer Mask", tooltip = "Highlight Renderers that cast shadows for the selected light." }; public static readonly NameAndTooltip LightLayersFilterLayers = new() { name = "Filter Layers", tooltip = "Use the drop-down to filter light layers that you want to visialize." }; - public static readonly NameAndTooltip LightLayersColor = new() { name = "Layers Color", tooltip = "Select the display color of each light layer." }; // Material Overrides public static readonly NameAndTooltip OverrideSmoothness = new() { name = "Override Smoothness", tooltip = "Enable the checkbox to override the smoothness for the entire Scene." }; diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/HDVolumeDebugSettings.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/HDVolumeDebugSettings.cs index 70109c39..a0075497 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/HDVolumeDebugSettings.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/HDVolumeDebugSettings.cs @@ -5,11 +5,25 @@ using UnityEditor; namespace UnityEngine.Rendering.HighDefinition { /// - /// Volume debug settings. + /// Represents the debug settings for handling volumes in the Rendering Debugger. + /// This class extends and allows customization of the volume stack, + /// layer mask, and position for the selected camera in the HDRP pipeline. It manages the camera-specific configurations + /// to ensure accurate rendering in the volume system. /// + /// + /// This class provides access to debug settings for the volume stack and layer mask in the High Definition Render Pipeline (HDRP). + /// It is useful for visualizing and adjusting volume settings for specific cameras during development. + /// public partial class HDVolumeDebugSettings : VolumeDebugSettings { - /// Selected camera volume stack. + /// + /// Gets the selected camera's volume stack. If no camera is selected, it defaults to the global volume stack. + /// This stack holds all the volume components affecting the camera. + /// + /// + /// This property retrieves the volume stack associated with the currently selected camera. If the camera is not found, + /// the global volume stack is used as a fallback. This stack defines how volumes are applied to the camera's view. + /// public override VolumeStack selectedCameraVolumeStack { get @@ -17,19 +31,27 @@ namespace UnityEngine.Rendering.HighDefinition Camera cam = selectedCamera; if (cam == null) return null; + var stack = HDCamera.GetOrCreate(cam).volumeStack; return stack ?? VolumeManager.instance.stack; } } - /// Selected camera volume layer mask. + /// + /// Gets the selected camera's volume layer mask. This determines which volumes will affect the selected camera. + /// If the scene view is active, it will use the main camera's volume layer mask. + /// + /// + /// This property manages the layer mask for volumes, which is important for determining which volumes apply to the selected camera. + /// It considers special cases like the scene view camera to provide accurate results in different contexts. + /// public override LayerMask selectedCameraLayerMask { get { if (selectedCamera != null) { -#if UNITY_EDITOR + #if UNITY_EDITOR // For scene view, use main camera volume layer mask. See HDCamera.cs if (selectedCamera == SceneView.lastActiveSceneView.camera) { @@ -39,16 +61,22 @@ namespace UnityEngine.Rendering.HighDefinition return sceneCameraAdditionalCameraData.volumeLayerMask; return HDCamera.GetSceneViewLayerMaskFallback(); } -#endif + #endif if (selectedCamera.TryGetComponent(out var selectedCameraAdditionalData)) return selectedCameraAdditionalData.volumeLayerMask; } - return 1; // "Default" + return 1; // Default } } - /// Selected camera volume position. + /// + /// Gets the selected camera's volume position. If no camera is selected, the position defaults to . + /// + /// + /// This property returns the position of the volume anchor for the selected camera. If the camera's anchor has not been initialized, + /// it will attempt to retrieve or set the anchor manually. This is important for adjusting the position of the camera in relation to the volume system. + /// public override Vector3 selectedCameraPosition { get @@ -58,12 +86,13 @@ namespace UnityEngine.Rendering.HighDefinition return Vector3.zero; var anchor = HDCamera.GetOrCreate(cam).volumeAnchor; - if (anchor == null) // means the hdcamera has not been initialized + if (anchor == null) // If the HDCamera has not been initialized { - // So we have to update the stack manually + // Manually update the stack if (cam.TryGetComponent(out var data)) anchor = data.volumeAnchorOverride; if (anchor == null) anchor = cam.transform; + var stack = selectedCameraVolumeStack; if (stack != null) VolumeManager.instance.Update(stack, anchor, selectedCameraLayerMask); @@ -72,4 +101,5 @@ namespace UnityEngine.Rendering.HighDefinition } } } + } diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Deprecated.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Deprecated.cs index 12d3bc41..5efe2014 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Deprecated.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Deprecated.cs @@ -79,11 +79,16 @@ namespace UnityEngine.Rendering.HighDefinition { } - /// Light Layers. + /// + /// This enum is obsolete as it has been renamed to which can now use 16 bits. + /// + /// + /// Options for defining LayerMasks to make lights or effects affect only specific renderers. + /// [Flags, Obsolete("LightLayersEnum has been renamed and can now use 16 bits. Use RenderingLayerMask instead @from(2023.1) (UnityUpgradable) -> RenderingLayerMask")] public enum LightLayerEnum { - /// The light will no affect any object. + /// The light doesn't affect any object. Nothing = 0, // Custom name for "Nothing" option /// Light Layer 0. LightLayerDefault = 1 << 0, @@ -105,11 +110,16 @@ namespace UnityEngine.Rendering.HighDefinition Everything = 0xFF, // Custom name for "Everything" option } - /// Decal Layers. + /// + /// This enum is obsolete as it has been renamed to which can now use 16 bits. + /// + /// + /// Options for defining LayerMasks to make decals affect only specific renderers. + /// [Flags, Obsolete("DecalLayerEnum has been renamed and can now use 16 bits. Use RenderingLayerMask instead @from(2023.1) (UnityUpgradable) -> RenderingLayerMask")] public enum DecalLayerEnum { - /// The light will no affect any object. + /// The decal doesn't affect any object. Nothing = 0, // Custom name for "Nothing" option /// Decal Layer 0. DecalLayerDefault = 1 << 0, @@ -132,8 +142,11 @@ namespace UnityEngine.Rendering.HighDefinition } /// - /// Debug Light Layers Filtering. + /// This enum is obsolete as it has been renamed to which can now use 16 bits. /// + /// + /// Options for defining LayerMasks to make lights or effects affect only specific renderers. + /// [Flags, Obsolete("DebugLightLayersMask has been renamed and can now use 16 bits. Use RenderingLayerMask instead @from(2023.1)")] public enum DebugLightLayersMask { diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Light/HDAdditionalLightData.Types.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Light/HDAdditionalLightData.Types.cs index 38b5dd48..96c92dd9 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Light/HDAdditionalLightData.Types.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Light/HDAdditionalLightData.Types.cs @@ -19,8 +19,35 @@ namespace UnityEngine.Rendering.HighDefinition } /// - /// Rendering Layer Mask. + /// Options for defining which RenderingLayers affect which renderers. /// + /// + /// This enum is a bitfield, which means that you can combine multiple values using the bitwise OR operator (|). + /// + /// + /// (); + /// if (renderer != null) + /// { + /// // If the Renderer component exists, we set the desired rendering layer mask + /// renderer.renderingLayerMask = (uint)desiredLayerMask; + /// } + /// } + /// } + /// ]]> + /// [Flags] public enum RenderingLayerMask { diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/HDShadow.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/HDShadow.hlsl index 6a91a495..0e74aa8e 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/HDShadow.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/HDShadow.hlsl @@ -49,10 +49,11 @@ float GetPunctualShadowAttenuation(HDShadowContext shadowContext, float2 positio if (pointLight) { - sd.rot0 = shadowContext.shadowDatas[shadowDataIndex + CubeMapFaceID(-L)].rot0; - sd.rot1 = shadowContext.shadowDatas[shadowDataIndex + CubeMapFaceID(-L)].rot1; - sd.rot2 = shadowContext.shadowDatas[shadowDataIndex + CubeMapFaceID(-L)].rot2; - sd.atlasOffset = shadowContext.shadowDatas[shadowDataIndex + CubeMapFaceID(-L)].atlasOffset; + const int cubeFaceOffset = CubeMapFaceID(-L); + sd.rot0 = shadowContext.shadowDatas[shadowDataIndex + cubeFaceOffset].rot0; + sd.rot1 = shadowContext.shadowDatas[shadowDataIndex + cubeFaceOffset].rot1; + sd.rot2 = shadowContext.shadowDatas[shadowDataIndex + cubeFaceOffset].rot2; + sd.atlasOffset = shadowContext.shadowDatas[shadowDataIndex + cubeFaceOffset].atlasOffset; } if (sd.isInCachedAtlas > 0) // This is a scalar branch. @@ -77,11 +78,12 @@ float GetPunctualShadowClosestDistance(HDShadowContext shadowContext, SamplerSta if (pointLight) { - sd.shadowToWorld = shadowContext.shadowDatas[shadowDataIndex + CubeMapFaceID(-L)].shadowToWorld; - sd.atlasOffset = shadowContext.shadowDatas[shadowDataIndex + CubeMapFaceID(-L)].atlasOffset; - sd.rot0 = shadowContext.shadowDatas[shadowDataIndex + CubeMapFaceID(-L)].rot0; - sd.rot1 = shadowContext.shadowDatas[shadowDataIndex + CubeMapFaceID(-L)].rot1; - sd.rot2 = shadowContext.shadowDatas[shadowDataIndex + CubeMapFaceID(-L)].rot2; + const int cubeFaceOffset = CubeMapFaceID(-L); + sd.shadowToWorld = shadowContext.shadowDatas[shadowDataIndex + cubeFaceOffset].shadowToWorld; + sd.atlasOffset = shadowContext.shadowDatas[shadowDataIndex + cubeFaceOffset].atlasOffset; + sd.rot0 = shadowContext.shadowDatas[shadowDataIndex + cubeFaceOffset].rot0; + sd.rot1 = shadowContext.shadowDatas[shadowDataIndex + cubeFaceOffset].rot1; + sd.rot2 = shadowContext.shadowDatas[shadowDataIndex + cubeFaceOffset].rot2; } if (sd.isInCachedAtlas > 0) // This is a scalar branch. diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.hlsl index 7b9a6772..00f5920d 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.hlsl @@ -192,6 +192,9 @@ void LightLoop( float3 V, PositionInputs posInput, PreLightData preLightData, BS // With XR single-pass and camera-relative: offset position to do lighting computations from the combined center view (original camera matrix). // This is required because there is only one list of lights generated on the CPU. Shadows are also generated once and shared between the instanced views. + // We keep the unmodified per-eye position around since we use it to sample APV. Passing the modified world space position to GetAbsolutePositionWS after + // this point would give incorrect results. + float3 unmodifiedPositionWS = posInput.positionWS; ApplyCameraRelativeXR(posInput.positionWS); LightLoopContext context; @@ -497,7 +500,7 @@ void LightLoop( float3 V, PositionInputs posInput, PreLightData preLightData, BS // Reflect normal to get lighting for reflection probe tinting float3 R = reflect(-V, bsdfData.normalWS); - EvaluateAdaptiveProbeVolume(GetAbsolutePositionWS(posInput.positionWS), + EvaluateAdaptiveProbeVolume(GetAbsolutePositionWS(unmodifiedPositionWS), bsdfData.normalWS, -bsdfData.normalWS, R, diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Reflection/ReflectionProbeTextureCache.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Reflection/ReflectionProbeTextureCache.cs index 970e72a8..615bc768 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Reflection/ReflectionProbeTextureCache.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Reflection/ReflectionProbeTextureCache.cs @@ -641,8 +641,8 @@ namespace UnityEngine.Rendering.HighDefinition public void ReserveReflectionProbeSlot(HDProbe probe) { Texture texture = probe.texture; - Assert.IsTrue(texture.width == texture.height); - Assert.IsTrue(texture.dimension == TextureDimension.Tex2D || texture.dimension == TextureDimension.Cube); + Assert.IsTrue(texture.width == texture.height, "Reflection probe should be a square texture. Check the import settings of the texture, or your Texture Importer presets"); + Assert.IsTrue(texture.dimension == TextureDimension.Tex2D || texture.dimension == TextureDimension.Cube, "Reflection probe should be a 2D or Cube texture. Check the import settings of the texture, or your Texture Importer presets"); int textureId = GetTextureIDAndSize(probe, out int textureSize); diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowManager.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowManager.cs index 0034a8ba..9188e49f 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowManager.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowManager.cs @@ -367,7 +367,7 @@ namespace UnityEngine.Rendering.HighDefinition return new HDShadowAtlasInitParams() { shadowAtlasResolution = k_DefaultShadowAtlasResolution, - shadowAtlasDepthBits = k_DefaultShadowMapDepthBits, + shadowAtlasDepthBits = CoreUtils.GetDefaultDepthBufferBits(), useDynamicViewportRescale = true }; } @@ -376,7 +376,7 @@ namespace UnityEngine.Rendering.HighDefinition internal static HDShadowInitParameters NewDefault() => new HDShadowInitParameters() { maxShadowRequests = k_DefaultMaxShadowRequests, - directionalShadowsDepthBits = k_DefaultShadowMapDepthBits, + directionalShadowsDepthBits = CoreUtils.GetDefaultDepthBufferBits(), punctualLightShadowAtlas = HDShadowAtlasInitParams.GetDefault(), areaLightShadowAtlas = HDShadowAtlasInitParams.GetDefault(), cachedPunctualLightShadowAtlas = 2048, @@ -398,7 +398,6 @@ namespace UnityEngine.Rendering.HighDefinition internal const int k_DefaultShadowAtlasResolution = 4096; internal const int k_DefaultMaxShadowRequests = 128; - internal const DepthBits k_DefaultShadowMapDepthBits = DepthBits.Depth32; /// Maximum number of shadow requests at the same time. public int maxShadowRequests; diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricClouds/HDRenderPipeline.VolumetricCloudsFullResolution.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricClouds/HDRenderPipeline.VolumetricCloudsFullResolution.cs index 3f710ba6..8633f2af 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricClouds/HDRenderPipeline.VolumetricCloudsFullResolution.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricClouds/HDRenderPipeline.VolumetricCloudsFullResolution.cs @@ -1,4 +1,3 @@ -using UnityEngine.Experimental.Rendering; using UnityEngine.Rendering.RenderGraphModule; namespace UnityEngine.Rendering.HighDefinition @@ -56,7 +55,6 @@ namespace UnityEngine.Rendering.HighDefinition static void TraceVolumetricClouds_FullResolution(CommandBuffer cmd, VolumetricCloudsParameters_FullResolution parameters, GraphicsBuffer ambientProbeBuffer, RTHandle colorBuffer, RTHandle depthPyramid, - RTHandle intermediateCloudsLighting, RTHandle intermediateCloudsDepth, RTHandle cloudsLighting, RTHandle cloudsDepth) { // Compute the number of tiles to evaluate @@ -74,10 +72,6 @@ namespace UnityEngine.Rendering.HighDefinition // Ray-march the clouds for this frame DoVolumetricCloudsTrace(cmd, finalTX, finalTY, parameters.viewCount, in parameters.commonData, ambientProbeBuffer, colorBuffer, depthPyramid, - intermediateCloudsLighting, intermediateCloudsDepth); - - DoVolumetricCloudsUpscale(cmd, parameters.combineKernel, finalTX, finalTY, parameters.viewCount, in parameters.commonData, - intermediateCloudsLighting, intermediateCloudsDepth, colorBuffer, depthPyramid, cloudsLighting, cloudsDepth); } @@ -91,10 +85,6 @@ namespace UnityEngine.Rendering.HighDefinition public TextureHandle depthPyramid; public BufferHandle ambientProbeBuffer; - // Intermediate buffers - public TextureHandle tracedCloudsLighting; - public TextureHandle tracedCloudsDepth; - // Output buffer public TextureHandle cloudsLighting; public TextureHandle cloudsDepth; @@ -115,7 +105,6 @@ namespace UnityEngine.Rendering.HighDefinition passData.depthPyramid = builder.ReadTexture(depthPyramid); passData.ambientProbeBuffer = builder.ReadBuffer(renderGraph.ImportBuffer(m_CloudsDynamicProbeBuffer)); - CreateTracingTextures(renderGraph, builder, settings, 1.0f, out passData.tracedCloudsLighting, out passData.tracedCloudsDepth); CreateOutputTextures(renderGraph, builder, settings, out passData.cloudsLighting, out passData.cloudsDepth); builder.SetRenderFunc( @@ -123,7 +112,6 @@ namespace UnityEngine.Rendering.HighDefinition { TraceVolumetricClouds_FullResolution(ctx.cmd, data.parameters, data.ambientProbeBuffer, data.colorBuffer, data.depthPyramid, - data.tracedCloudsLighting, data.tracedCloudsDepth, data.cloudsLighting, data.cloudsDepth); }); diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricClouds/VolumetricClouds.compute b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricClouds/VolumetricClouds.compute index 82bedf9c..5fb00d2a 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricClouds/VolumetricClouds.compute +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricClouds/VolumetricClouds.compute @@ -76,13 +76,14 @@ void REPROJECT_CLOUDS(uint3 dispatchThreadId : SV_DispatchThreadID, // 2. Check history validity float2 motionVector = EvaluateCloudMotionVectors(fullResCoord, currentCloudDepth, 1.0); - float2 historyUV = (intermediateCoord.xy + 0.5) / _IntermediateScreenSize.xy - motionVector; + float2 historyUV = (intermediateCoord.xy + 0.5) * _IntermediateScreenSize.zw - motionVector; float4 history = SAMPLE_TEXTURE2D_X_LOD(_HistoryVolumetricClouds1Texture, s_linear_clamp_sampler, historyUV * _HistoryViewportScale, 0); float previousSampleCount = history.x; // History is invalid if sample is out of screen or scene depth was too different - if (all(historyUV == saturate(historyUV)) && previousSampleCount >= 0.5f && EvaluateDepthDifference(history.y, currentSceneDepth)) + float2 historyUVMax = 1.0 - 0.5 * _IntermediateScreenSize.zw - 0.000001; // To avoid lerp with garbage pixels + if (all(0.0 <= float4(historyUV, historyUVMax - historyUV)) && previousSampleCount >= 0.5f && EvaluateDepthDifference(history.y, currentSceneDepth)) { float4 previousColor = SAMPLE_TEXTURE2D_X_LOD(_HistoryVolumetricClouds0Texture, s_linear_clamp_sampler, historyUV * _HistoryViewportScale, 0); previousColor.xyz *= GetInversePreviousExposureMultiplier() * GetCurrentExposureMultiplier(); diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/HDRenderPipeline.VolumetricLighting.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/HDRenderPipeline.VolumetricLighting.cs index 71585fc1..45c53bb1 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/HDRenderPipeline.VolumetricLighting.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/HDRenderPipeline.VolumetricLighting.cs @@ -877,10 +877,12 @@ namespace UnityEngine.Rendering.HighDefinition ulong cameraSceneCullingMask = HDUtils.GetSceneCullingMaskFromCamera(hdCamera.camera); foreach (var volume in volumes) { + var transform = volume.transform; + Vector3 scaleSize = volume.GetScaledSize(transform); Vector3 center = volume.transform.position; // Reject volumes that are completely fade out or outside of the volumetric fog using bounding sphere - float boundingSphereRadius = Vector3.Magnitude(volume.parameters.size); + float boundingSphereRadius = Vector3.Magnitude(scaleSize); float minObbDistance = Vector3.Magnitude(center - camPosition) - hdCamera.camera.nearClipPlane - boundingSphereRadius; if (minObbDistance > volume.parameters.distanceFadeEnd || minObbDistance > fog.depthExtent.value) continue; @@ -892,8 +894,8 @@ namespace UnityEngine.Rendering.HighDefinition // Handle camera-relative rendering. center -= camOffset; - var transform = volume.transform; - var bounds = GeometryUtils.OBBToAABB(transform.right, transform.up, transform.forward, volume.parameters.size, center); + + var bounds = GeometryUtils.OBBToAABB(transform.right, transform.up, transform.forward, scaleSize, center); // Frustum cull on the CPU for now. TODO: do it on the GPU. // TODO: account for custom near and far planes of the V-Buffer's frustum. @@ -908,7 +910,7 @@ namespace UnityEngine.Rendering.HighDefinition } // TODO: cache these? - var obb = new OrientedBBox(Matrix4x4.TRS(transform.position - camOffset, transform.rotation, volume.parameters.size)); + var obb = new OrientedBBox(Matrix4x4.TRS(transform.position - camOffset, transform.rotation, scaleSize)); m_VisibleVolumeBounds.Add(obb); m_GlobalVolumeIndices.Add(volume.GetGlobalIndex()); var visibleData = volume.parameters.ConvertToEngineData(); diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/LocalVolumetricFog.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/LocalVolumetricFog.cs index 33f0cc97..f1f3c018 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/LocalVolumetricFog.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/LocalVolumetricFog.cs @@ -8,6 +8,17 @@ using UnityEditor.SceneManagement; namespace UnityEngine.Rendering.HighDefinition { + /// The scaling mode to apply to Local Volumetric Fog. + public enum LocalVolumetricFogScaleMode + { + /// Ignores the transformation hierarchy and uses the scale values in the Local Volumetric Fog component directly. + [InspectorName("Scale Invariant")] + ScaleInvariant, + /// Multiplies the lossy scale of the Transform with the Local Volumetric Fog's size then applies this to the Local Volumetric Fog component. + [InspectorName("Inherit from Hierarchy")] + InheritFromHierarchy, + } + /// Artist-friendly Local Volumetric Fog parametrization. [Serializable] public partial struct LocalVolumetricFogArtistParameters @@ -55,6 +66,9 @@ namespace UnityEngine.Rendering.HighDefinition [SerializeField, FormerlySerializedAs("advancedFade"), FormerlySerializedAs("m_AdvancedFade")] internal bool m_EditorAdvancedFade; + /// The scaling mode to apply to Local Volumetric Fog. + public LocalVolumetricFogScaleMode scaleMode; + /// Dimensions of the volume. public Vector3 size; /// Inverts the fade gradient. @@ -98,6 +112,7 @@ namespace UnityEngine.Rendering.HighDefinition textureTiling = Vector3.one; textureOffset = textureScrollingSpeed; + scaleMode = LocalVolumetricFogScaleMode.ScaleInvariant; size = Vector3.one; positiveFade = Vector3.one * 0.1f; @@ -198,6 +213,12 @@ namespace UnityEngine.Rendering.HighDefinition [NonSerialized] internal Material textureMaterial; + /// stores the current effective scale, Vector3.one if the component is Scale Invariant, or lossy scale if the component Inherit From Hiearchy. + internal Vector3 effectiveScale; + + /// stores the final scale of the local volumetric fog component. + internal Vector3 scaledSize; + /// Gather and Update any parameters that may have changed. internal void PrepareParameters(float time) { @@ -274,11 +295,14 @@ namespace UnityEngine.Rendering.HighDefinition // We can put this in global m_RenderingProperties.SetBuffer(HDShaderIDs._VolumetricMaterialData, LocalVolumetricFogManager.manager.volumetricMaterialDataBuffer); + effectiveScale = GetEffectiveScale(this.transform); + scaledSize = GetScaledSize(this.transform); + // Send local properties inside constants instead of structured buffer to optimize GPU reads var engineData = parameters.ConvertToEngineData(); var tr = transform; var position = tr.position; - var bounds = new OrientedBBox(Matrix4x4.TRS(position, tr.rotation, parameters.size)); + var bounds = new OrientedBBox(Matrix4x4.TRS(position, tr.rotation, scaledSize)); m_RenderingProperties.SetVector(HDShaderIDs._VolumetricMaterialObbRight, bounds.right); m_RenderingProperties.SetVector(HDShaderIDs._VolumetricMaterialObbUp, bounds.up); m_RenderingProperties.SetVector(HDShaderIDs._VolumetricMaterialObbExtents, new Vector3(bounds.extentX, bounds.extentY, bounds.extentZ)); @@ -319,6 +343,16 @@ namespace UnityEngine.Rendering.HighDefinition Graphics.RenderPrimitivesIndexedIndirect(renderParams, MeshTopology.Triangles, LocalVolumetricFogManager.manager.volumetricMaterialIndexBuffer, LocalVolumetricFogManager.manager.globalIndirectBuffer, 1, m_GlobalIndex); } + internal Vector3 GetEffectiveScale(Transform tr) + { + return (parameters.scaleMode == LocalVolumetricFogScaleMode.InheritFromHierarchy) ? tr.lossyScale : Vector3.one; + } + + internal Vector3 GetScaledSize(Transform tr) + { + return Vector3.Max(Vector3.one * 0.001f, Vector3.Scale(parameters.size, GetEffectiveScale(tr))); + } + #if UNITY_EDITOR void UpdateLocalVolumetricFogVisibility() { @@ -326,6 +360,7 @@ namespace UnityEngine.Rendering.HighDefinition UpdateLocalVolumetricFogVisibility(isVisible); } + void UpdateLocalVolumetricFogVisibilityPrefabStage(SceneView sv) { var stage = PrefabStageUtility.GetCurrentPrefabStage(); diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/LocalVolumetricFogManager.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/LocalVolumetricFogManager.cs index f5026f75..250e8f64 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/LocalVolumetricFogManager.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/LocalVolumetricFogManager.cs @@ -105,12 +105,12 @@ namespace UnityEngine.Rendering.HighDefinition unsafe void AllocateIndirectBuffers(int count) { - globalIndirectBuffer = new GraphicsBuffer(GraphicsBuffer.Target.IndirectArguments, count, sizeof(GraphicsBuffer.IndirectDrawArgs)); + globalIndirectBuffer = new GraphicsBuffer(GraphicsBuffer.Target.IndirectArguments, count, sizeof(GraphicsBuffer.IndirectDrawIndexedArgs)); globalIndirectionBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Raw, count, sizeof(uint)); // Initialize with zeros to prevent weird behaviours - var zeros = new NativeArray(count * Mathf.Max(sizeof(GraphicsBuffer.IndirectDrawArgs), sizeof(uint)), Allocator.Temp, NativeArrayOptions.ClearMemory); - globalIndirectBuffer.SetData(zeros, 0, 0, count * sizeof(GraphicsBuffer.IndirectDrawArgs)); + var zeros = new NativeArray(count * Mathf.Max(sizeof(GraphicsBuffer.IndirectDrawIndexedArgs), sizeof(uint)), Allocator.Temp, NativeArrayOptions.ClearMemory); + globalIndirectBuffer.SetData(zeros, 0, 0, count * sizeof(GraphicsBuffer.IndirectDrawIndexedArgs)); globalIndirectionBuffer.SetData(zeros, 0, 0, count * sizeof(uint)); zeros.Dispose(); } diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxF.shader b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxF.shader index ca5e56cb..ded9cab9 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxF.shader +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/AxF/AxF.shader @@ -512,6 +512,7 @@ Shader "HDRP/AxF" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile_fragment _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ DYNAMICLIGHTMAP_ON #pragma multi_compile _ USE_LEGACY_LIGHTMAPS @@ -643,6 +644,7 @@ Shader "HDRP/AxF" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 #pragma multi_compile _ DYNAMICLIGHTMAP_ON @@ -692,6 +694,7 @@ Shader "HDRP/AxF" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 #pragma multi_compile _ DYNAMICLIGHTMAP_ON @@ -738,6 +741,7 @@ Shader "HDRP/AxF" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ MINIMAL_GBUFFER #pragma multi_compile _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinGIUtilities.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinGIUtilities.hlsl index 3dc884ef..ae9d5b96 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinGIUtilities.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/BuiltinGIUtilities.hlsl @@ -221,7 +221,11 @@ float4 SampleShadowMask(float3 positionRWS, float2 uvStaticLightmap) // normalWS { #if defined(LIGHTMAP_ON) float2 uv = uvStaticLightmap * unity_LightmapST.xy + unity_LightmapST.zw; + #if defined(LIGHTMAP_BICUBIC_SAMPLING) + return SampleLightmapBicubic(SHADOWMASK_NAME, SHADOWMASK_SAMPLER_NAME, SHADOWMASK_SAMPLE_EXTRA_ARGS); + #else return SAMPLE_TEXTURE2D_LIGHTMAP(SHADOWMASK_NAME, SHADOWMASK_SAMPLER_NAME, SHADOWMASK_SAMPLE_EXTRA_ARGS); // Can't reuse sampler from Lightmap because with shader graph, the compile could optimize out the lightmaps if metal is 1 + #endif #elif (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) return 1; #else diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalData.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalData.hlsl index d4fa1b48..438f4fe9 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalData.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalData.hlsl @@ -135,7 +135,7 @@ void GetSurfaceData(FragInputs input, float3 V, PositionInputs posInput, float a #else // DECAL_SURFACE_GRADIENT #ifdef _NORMALMAP - float3 normalTS = UnpackNormalmapRGorAG(SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, texCoords)); + float3 normalTS = UnpackNormalMapRGorAG(SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, texCoords)); #else float3 normalTS = float3(0.0, 0.0, 1.0); #endif diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl index 13abc7d4..6e0892a1 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalUtilities.hlsl @@ -181,7 +181,7 @@ void EvalDecalMask( PositionInputs posInput, float3 vtxNormal, float3 positionRW float2 deriv = UnpackDerivativeNormalRGorAG(atlasData); src.xyz = SurfaceGradientFromTBN(deriv, tangentToWorld[0], tangentToWorld[1]); #else - normalTS = UnpackNormalmapRGorAG(atlasData); + normalTS = UnpackNormalMapRGorAG(atlasData); #endif } diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs index 25dad9ac..470aa7ec 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/DiffusionProfile/DiffusionProfileSettings.cs @@ -64,6 +64,9 @@ namespace UnityEngine.Rendering.HighDefinition public float lobeMix; [Range(1.0f, 3.0f), Tooltip("Exponent on the cosine component of the diffuse lobe.\nHelps to simulate surfaces with strong subsurface scattering.")] public float diffuseShadingPower; + [ColorUsage(false, false)] + [Tooltip("The color used when a subsurface scattering sample encounters a border. A border is defined by a material not having the same diffusion profile.")] + public Color borderAttenuationColor; public TransmissionMode transmissionMode; public Vector2 thicknessRemap; // X = min, Y = max (in millimeters) public float worldScale; // Size of the world unit in meters @@ -95,6 +98,7 @@ namespace UnityEngine.Rendering.HighDefinition thicknessRemap = new Vector2(0f, 5f); worldScale = 1f; ior = 1.4f; // Typical value for skin specular reflectance + borderAttenuationColor = Color.black; } internal void Validate() @@ -228,6 +232,7 @@ namespace UnityEngine.Rendering.HighDefinition transmissionTint == other.transmissionTint && texturingMode == other.texturingMode && transmissionMode == other.transmissionMode && + borderAttenuationColor == other.borderAttenuationColor && thicknessRemap == other.thicknessRemap && worldScale == other.worldScale && ior == other.ior; @@ -249,6 +254,7 @@ namespace UnityEngine.Rendering.HighDefinition [NonSerialized] internal Vector4 transmissionTintAndFresnel0; // RGB = color, A = fresnel0 [NonSerialized] internal Vector4 disabledTransmissionTintAndFresnel0; // RGB = black, A = fresnel0 - For debug to remove the transmission [NonSerialized] internal Vector4 dualLobeAndDiffusePower; // R = Smoothness A, G = Smoothness B, B = Lobe Mix, A = Diffuse Power - 1 (to have 0 as neutral value) + [NonSerialized] internal Vector4 borderAttenuationColorMultiplier; // RGB = color, A = not used [NonSerialized] internal int updateCount; /// @@ -335,6 +341,17 @@ namespace UnityEngine.Rendering.HighDefinition set { profile.transmissionTint = value; profile.Validate(); UpdateCache(); } } + /// + /// Color used when the diffusion profile samples encounters a different diffusion profile index. + /// Setting this color to black have the same effect as occluding the subsurface scattering. + /// This property only works if the "Support Border Attenuation" property is enabled in the HDRP asset. + /// + public Color borderAttenuationColor + { + get => profile.borderAttenuationColor; + set { profile.borderAttenuationColor = value; profile.Validate(); UpdateCache(); } + } + void OnEnable() { if (profile == null) @@ -387,6 +404,7 @@ namespace UnityEngine.Rendering.HighDefinition disabledTransmissionTintAndFresnel0 = new Vector4(0.0f, 0.0f, 0.0f, fresnel0); float smoothnessB = profile.lobeMix == 0.0f ? 1.0f : profile.smoothnessMultipliers.y; // this helps shader determine if dual lobe is active dualLobeAndDiffusePower = new Vector4(profile.smoothnessMultipliers.x, smoothnessB, profile.lobeMix, profile.diffuseShadingPower - 1.0f); + borderAttenuationColorMultiplier = profile.borderAttenuationColor; updateCount++; } diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLit.shader b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLit.shader index 775c6aeb..0a3e4dd0 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLit.shader +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLit.shader @@ -680,6 +680,7 @@ Shader "HDRP/LayeredLit" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile_fragment _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ DYNAMICLIGHTMAP_ON #pragma multi_compile _ USE_LEGACY_LIGHTMAPS @@ -1063,6 +1064,7 @@ Shader "HDRP/LayeredLit" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile_fragment _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ DYNAMICLIGHTMAP_ON #pragma multi_compile _ USE_LEGACY_LIGHTMAPS @@ -1248,6 +1250,7 @@ Shader "HDRP/LayeredLit" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ DYNAMICLIGHTMAP_ON @@ -1302,6 +1305,7 @@ Shader "HDRP/LayeredLit" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ DYNAMICLIGHTMAP_ON @@ -1353,6 +1357,7 @@ Shader "HDRP/LayeredLit" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ DYNAMICLIGHTMAP_ON @@ -1429,6 +1434,7 @@ Shader "HDRP/LayeredLit" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ DYNAMICLIGHTMAP_ON @@ -1498,6 +1504,7 @@ Shader "HDRP/LayeredLit" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ SENSORSDK_OVERRIDE_REFLECTANCE diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitData.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitData.hlsl index a0c055f3..ccf39a8e 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitData.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitData.hlsl @@ -783,7 +783,8 @@ void GetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInputs p surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD; #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING - surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING; + if (surfaceData.subsurfaceMask > 0) + surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING; #endif #ifdef _MATERIAL_FEATURE_TRANSMISSION surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION; diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitTessellation.shader b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitTessellation.shader index ba8e5a93..18e59d72 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitTessellation.shader +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/LayeredLit/LayeredLitTessellation.shader @@ -721,6 +721,7 @@ Shader "HDRP/LayeredLitTessellation" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile_fragment _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ DYNAMICLIGHTMAP_ON #pragma multi_compile _ USE_LEGACY_LIGHTMAPS @@ -1116,6 +1117,7 @@ Shader "HDRP/LayeredLitTessellation" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile_fragment _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ DYNAMICLIGHTMAP_ON #pragma multi_compile _ USE_LEGACY_LIGHTMAPS @@ -1310,6 +1312,7 @@ Shader "HDRP/LayeredLitTessellation" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ DYNAMICLIGHTMAP_ON @@ -1367,6 +1370,7 @@ Shader "HDRP/LayeredLitTessellation" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ DYNAMICLIGHTMAP_ON @@ -1421,6 +1425,7 @@ Shader "HDRP/LayeredLitTessellation" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ DYNAMICLIGHTMAP_ON @@ -1503,6 +1508,7 @@ Shader "HDRP/LayeredLitTessellation" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ DYNAMICLIGHTMAP_ON @@ -1574,6 +1580,7 @@ Shader "HDRP/LayeredLitTessellation" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ SENSORSDK_OVERRIDE_REFLECTANCE diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl index 305b47e6..fb73c092 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.hlsl @@ -585,6 +585,10 @@ void EncodeIntoGBuffer( SurfaceData surfaceData float encodedSpecularOcclusion = surfaceData.specularOcclusion; #endif + // Remove SSS in case the mask is 0 + if (surfaceData.subsurfaceMask == 0) + surfaceData.materialFeatures &= ~(MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING); + // Ensure that surfaceData.coatMask is 0 if the feature is not enabled // Warning: overriden by Translucent if using a transmission tint float coatMask = HasFlag(surfaceData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT) ? surfaceData.coatMask : 0.0; @@ -909,13 +913,7 @@ uint DecodeFromGBuffer(uint2 positionSS, uint tileFeatureFlags, out BSDFData bsd SSSData sssData; float transmissionMask; - #ifdef DEBUG_DISPLAY - // Note that we don't use sssData.subsurfaceMask here. But it is still assign so we can have - // the information in the material debug view. UnpackFloatInt8bit(inGBuffer0.a, 16, sssData.subsurfaceMask, sssData.diffusionProfileIndex); - #else - sssData.subsurfaceMask = 0.0f; // Initialize to prevent compiler error, but value is never used - #endif // We read profile from G-Buffer 2 so the compiler can optimize away the read from the G-Buffer 0 to the very end (in PostEvaluateBSDF) // When using translucency, we exchange diffusion profile and coat mask diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.shader b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.shader index aad77af5..6ac37919 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.shader +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/Lit.shader @@ -459,6 +459,7 @@ Shader "HDRP/Lit" #pragma multi_compile _ DEBUG_DISPLAY // 'Optimize Mesh Data' strip away attribute uv1/uv2 without the keyword set on the vertex stage. #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile_fragment _ LIGHTMAP_BICUBIC_SAMPLING // Both DIRLIGHTMAP_COMBINED and DYNAMICLIGHTMAP_ON must have vertex frequency to be able to include UV2 in player // If DIRLIGHTMAP_COMBINED isn't define, then DYNAMICLIGHTMAP_ON will not. This is hardcoded in C++ // For ShaderGraph we don't have this issue as UV2 are always included. @@ -860,6 +861,7 @@ Shader "HDRP/Lit" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile_fragment _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ DYNAMICLIGHTMAP_ON #pragma multi_compile _ USE_LEGACY_LIGHTMAPS @@ -987,6 +989,7 @@ Shader "HDRP/Lit" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile_fragment _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ DYNAMICLIGHTMAP_ON #pragma multi_compile _ USE_LEGACY_LIGHTMAPS @@ -1195,6 +1198,7 @@ Shader "HDRP/Lit" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DYNAMICLIGHTMAP_ON #pragma multi_compile _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 #pragma multi_compile _ DIRLIGHTMAP_COMBINED @@ -1257,6 +1261,7 @@ Shader "HDRP/Lit" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DYNAMICLIGHTMAP_ON #pragma multi_compile _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 #pragma multi_compile _ DIRLIGHTMAP_COMBINED @@ -1315,6 +1320,7 @@ Shader "HDRP/Lit" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DYNAMICLIGHTMAP_ON #pragma multi_compile _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 #pragma multi_compile _ DIRLIGHTMAP_COMBINED @@ -1398,6 +1404,7 @@ Shader "HDRP/Lit" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DYNAMICLIGHTMAP_ON #pragma multi_compile _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 #pragma multi_compile _ DIRLIGHTMAP_COMBINED diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitBuiltinData.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitBuiltinData.hlsl index ead9f16f..ad1372d0 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitBuiltinData.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitBuiltinData.hlsl @@ -21,14 +21,14 @@ float3 GetEmissiveColor(SurfaceData surfaceData) return _EmissiveColor * lerp(float3(1.0, 1.0, 1.0), surfaceData.baseColor.rgb, _AlbedoAffectEmissive); } -#ifdef _EMISSIVE_COLOR_MAP float3 GetEmissiveColor(SurfaceData surfaceData, UVMapping emissiveMapMapping) { float3 emissiveColor = GetEmissiveColor(surfaceData); + #ifdef _EMISSIVE_COLOR_MAP emissiveColor *= SAMPLE_UVMAPPING_TEXTURE2D(_EmissiveColorMap, sampler_EmissiveColorMap, emissiveMapMapping).rgb; + #endif // _EMISSIVE_COLOR_MAP return emissiveColor; } -#endif // _EMISSIVE_COLOR_MAP void GetBuiltinData(FragInputs input, float3 V, inout PositionInputs posInput, SurfaceData surfaceData, float alpha, float3 bentNormalWS, float depthOffset, out BuiltinData builtinData) { diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDataIndividualLayer.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDataIndividualLayer.hlsl index 40d31a37..b5525553 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDataIndividualLayer.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitDataIndividualLayer.hlsl @@ -290,7 +290,8 @@ float ADD_IDX(GetSurfaceData)(FragInputs input, LayerTexCoord layerTexCoord, out surfaceData.materialFeatures = MATERIALFEATUREFLAGS_LIT_STANDARD; #ifdef _MATERIAL_FEATURE_SUBSURFACE_SCATTERING - surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING; + if (surfaceData.subsurfaceMask > 0) + surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING; #endif #ifdef _MATERIAL_FEATURE_TRANSMISSION surfaceData.materialFeatures |= MATERIALFEATUREFLAGS_LIT_TRANSMISSION; @@ -311,7 +312,7 @@ float ADD_IDX(GetSurfaceData)(FragInputs input, LayerTexCoord layerTexCoord, out #ifdef _TANGENTMAP #ifdef _NORMALMAP_TANGENT_SPACE_IDX // Normal and tangent use same space // Tangent space vectors always use only 2 channels. - float3 tangentTS = UnpackNormalmapRGorAG(SAMPLE_UVMAPPING_TEXTURE2D(_TangentMap, sampler_TangentMap, layerTexCoord.base), 1.0); + float3 tangentTS = UnpackNormalMapRGorAG(SAMPLE_UVMAPPING_TEXTURE2D(_TangentMap, sampler_TangentMap, layerTexCoord.base), 1.0); surfaceData.tangentWS = TransformTangentToWorld(tangentTS, input.tangentToWorld); #else // Object space // Note: There is no such a thing like triplanar with object space normal, so we call directly 2D function diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitTessellation.shader b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitTessellation.shader index 7b91d86d..e08af888 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitTessellation.shader +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/LitTessellation.shader @@ -480,6 +480,7 @@ Shader "HDRP/LitTessellation" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile_fragment _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ DYNAMICLIGHTMAP_ON #pragma multi_compile _ USE_LEGACY_LIGHTMAPS @@ -888,6 +889,7 @@ Shader "HDRP/LitTessellation" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile_fragment _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ DYNAMICLIGHTMAP_ON #pragma multi_compile _ USE_LEGACY_LIGHTMAPS @@ -1015,6 +1017,7 @@ Shader "HDRP/LitTessellation" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile_fragment _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ DYNAMICLIGHTMAP_ON #pragma multi_compile _ USE_LEGACY_LIGHTMAPS @@ -1230,6 +1233,7 @@ Shader "HDRP/LitTessellation" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DYNAMICLIGHTMAP_ON #pragma multi_compile _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 #pragma multi_compile _ DIRLIGHTMAP_COMBINED @@ -1289,6 +1293,7 @@ Shader "HDRP/LitTessellation" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DYNAMICLIGHTMAP_ON #pragma multi_compile _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 #pragma multi_compile _ DIRLIGHTMAP_COMBINED @@ -1344,6 +1349,7 @@ Shader "HDRP/LitTessellation" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DYNAMICLIGHTMAP_ON #pragma multi_compile _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 #pragma multi_compile _ DIRLIGHTMAP_COMBINED @@ -1431,6 +1437,7 @@ Shader "HDRP/LitTessellation" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DYNAMICLIGHTMAP_ON #pragma multi_compile _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 #pragma multi_compile _ DIRLIGHTMAP_COMBINED diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/ShaderPass/LitDepthPass.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/ShaderPass/LitDepthPass.hlsl index 1ce902b1..98eabca5 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/ShaderPass/LitDepthPass.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Lit/ShaderPass/LitDepthPass.hlsl @@ -7,7 +7,7 @@ #endif // Attributes -#define REQUIRE_TANGENT_TO_WORLD ((defined(_PIXEL_DISPLACEMENT) && defined(_HEIGHTMAP) && defined(_DEPTHOFFSET_ON)) || (defined(_ALPHATEST_ON) && defined(_MAPPING_TRIPLANAR))) +#define REQUIRE_TANGENT_TO_WORLD ((defined(_PIXEL_DISPLACEMENT) && defined(_DEPTHOFFSET_ON)) || (defined(_ALPHATEST_ON) && defined(_MAPPING_TRIPLANAR))) #define REQUIRE_NORMAL defined(TESSELLATION_ON) || REQUIRE_TANGENT_TO_WORLD || defined(_VERTEX_DISPLACEMENT) || defined(OUTPUT_DECAL_BUFER) #define REQUIRE_VERTEX_COLOR (defined(_VERTEX_DISPLACEMENT) || defined(_TESSELLATION_DISPLACEMENT) || (defined(LAYERED_LIT_SHADER) && (defined(_LAYER_MASK_VERTEX_COLOR_MUL) || defined(_LAYER_MASK_VERTEX_COLOR_ADD)))) diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/CombineLighting.shader b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/CombineLighting.shader index 795922a7..b2ae0f27 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/CombineLighting.shader +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/CombineLighting.shader @@ -64,7 +64,9 @@ Shader "Hidden/HDRP/CombineLighting" float4 Frag(Varyings input) : SV_Target { UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); - return LOAD_TEXTURE2D_X(_IrradianceSource, input.positionCS.xy); + float3 color = LOAD_TEXTURE2D_X(_IrradianceSource, input.positionCS.xy).rgb; + // avoid to additive blend the alpha which tends to make it above 1 and cause issues in later passes. + return float4(color, 0); } ENDHLSL } @@ -88,7 +90,9 @@ Shader "Hidden/HDRP/CombineLighting" float4 Frag(Varyings input) : SV_Target { UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); - return LOAD_TEXTURE2D_X(_IrradianceSource, input.positionCS.xy) * GetCurrentExposureMultiplier(); + float3 color = LOAD_TEXTURE2D_X(_IrradianceSource, input.positionCS.xy).rgb * GetCurrentExposureMultiplier(); + // avoid to additive blend the alpha which tends to make it above 1 and cause issues in later passes. + return float4(color, 0); } ENDHLSL } diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute index 54c7aaf7..c275b1cc 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.compute @@ -8,9 +8,11 @@ #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch #pragma kernel SubsurfaceScattering +#pragma kernel PackDiffusionProfile PACK_DIFFUSION_PROFILE #pragma multi_compile _ ENABLE_MSAA #pragma multi_compile _ USE_DOWNSAMPLE +#pragma multi_compile _ USE_SSS_OCCLUSION // TODO: use sharp load hoisting on PS4. @@ -71,6 +73,12 @@ StructuredBuffer _CoarseStencilBuffer; RW_TEXTURE2D_X(float4, _CameraColorTexture); // Target texture #endif +#ifdef PACK_DIFFUSION_PROFILE + RW_TEXTURE2D_X(uint, _DiffusionProfileIndexTexture); +#else + TYPED_TEXTURE2D_X(uint, _DiffusionProfileIndexTexture); +#endif + //-------------------------------------------------------------------------------------------------- // Implementation //-------------------------------------------------------------------------------------------------- @@ -187,9 +195,37 @@ struct DebugInfo #endif }; +bool SameProfiles(uint sampleProfileIndex, uint currentProfileIndex) +{ +#ifdef USE_SSS_OCCLUSION + return sampleProfileIndex == currentProfileIndex; +#endif + return true; +} + +int GetDiffusionProfileIndexAtPosition(int2 position) +{ +#if PACK_DIFFUSION_PROFILE + // Load from RW texture has only 3 parameter (no mips) and we don't have macro for this one + uint p = _DiffusionProfileIndexTexture[COORD_TEXTURE2D_X(uint2(position.x >> 1, position.y))]; +#else + uint p = LOAD_TEXTURE2D_X_LOD(_DiffusionProfileIndexTexture, uint2(position.x >> 1, position.y), 0); +#endif + + int sampleProfileIndex; + + if ((position.x & 1) == 0) + sampleProfileIndex = p & 0xF; + else + sampleProfileIndex = p >> 4; + + return sampleProfileIndex; +} + void EvaluateSample(uint i, uint n, int2 pixelCoord, int2 cacheOffset, float3 S, float d, float3 centerPosVS, float mmPerUnit, float pixelsPerMm, - float phase, float3 tangentX, float3 tangentY, float4x4 projMatrix, float linearDepth, inout DebugInfo debugInfo, + float phase, float3 tangentX, float3 tangentY, float4x4 projMatrix, float linearDepth, + int currentProfileIndex, float3 borderAttenuationColor, inout DebugInfo debugInfo, inout float3 totalIrradiance, inout float3 totalWeight) { // The sample count is loop-invariant. @@ -234,17 +270,33 @@ void EvaluateSample(uint i, uint n, int2 pixelCoord, int2 cacheOffset, float4 textureSample = LoadSample(position, cacheOffset); float3 irradiance = textureSample.rgb; + // Compute bilateral weighting. + float viewZ = textureSample.a; + float relZ = viewZ - linearDepth; + float3 weight = ComputeBilateralWeight(xy2, relZ, mmPerUnit, S, rcpPdf); + + // For the SSS Occlusion, we take in account all the samples as weight + // This is required if we want darkening on zones where less samples are available due to masking. + #if USE_SSS_OCCLUSION + totalWeight += weight; + #endif + // Check the results of the stencil test. if (TestLightingForSSS(irradiance)) { - // Apply bilateral weighting. - float viewZ = textureSample.a; - float relZ = viewZ - linearDepth; - float3 weight = ComputeBilateralWeight(xy2, relZ, mmPerUnit, S, rcpPdf); - - // Note: if the texture sample if off-screen, (z = 0) -> (viewZ = far) -> (weight ≈ 0). - totalIrradiance += weight * irradiance; - totalWeight += weight; + int sampleProfileIndex = GetDiffusionProfileIndexAtPosition(position); + if (SameProfiles(sampleProfileIndex, currentProfileIndex)) + { + // Note: if the texture sample if off-screen, (z = 0) -> (viewZ = far) -> (weight ≈ 0). + totalIrradiance += weight * irradiance; + #if !USE_SSS_OCCLUSION + totalWeight += weight; + #endif + } + else + { + totalIrradiance += weight * irradiance * borderAttenuationColor; + } } else { @@ -302,6 +354,7 @@ void EvaluateSss(uint2 pixelCoord, CacheInfo cacheInfo, CenterInfo centerInfo, i float distScale = sssData.subsurfaceMask; float3 S = _ShapeParamsAndMaxScatterDists[profileIndex].rgb; float d = _ShapeParamsAndMaxScatterDists[profileIndex].a; + float3 borderAttenuationColor = _BorderAttenuationColor[profileIndex].rgb; float metersPerUnit = _WorldScalesAndFilterRadiiAndThicknessRemaps[profileIndex].x; float filterRadius = _WorldScalesAndFilterRadiiAndThicknessRemaps[profileIndex].y; // In millimeters @@ -393,8 +446,8 @@ void EvaluateSss(uint2 pixelCoord, CacheInfo cacheInfo, CenterInfo centerInfo, i // Integrate over the image or tangent plane in the view space. EvaluateSample(i, n, pixelCoord, cacheInfo.cacheOffset, S, d, centerPosVS, mmPerUnit, pixelsPerMm, - phase, tangentX, tangentY, projMatrix, linearDepth, debugInfo, - totalIrradiance, totalWeight); + phase, tangentX, tangentY, projMatrix, linearDepth, profileIndex, + borderAttenuationColor, debugInfo, totalIrradiance, totalWeight); } // Total weight is 0 for color channels without scattering. @@ -459,7 +512,9 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, bool passedStencilTest = TestLightingForSSS(centerInfo.irradiance); // Save some bandwidth by only loading depth values for SSS pixels. +#if !USE_SSS_OCCLUSION // When Occlusion is enabled we need all the samples in the cache to be valid. if (passedStencilTest) +#endif { centerInfo.depth = LOAD_TEXTURE2D_X(_DepthTexture, pixelCoord).r; } @@ -559,3 +614,27 @@ void SubsurfaceScattering(uint3 groupId : SV_GroupID, StoreResult(pixelCoord, irradiance); } + +#ifdef PACK_DIFFUSION_PROFILE +[numthreads(8, 8, 1)] +void PackDiffusionProfile(uint3 groupId : SV_GroupID, + uint groupThreadId : SV_GroupThreadID, + uint3 dispatchThreadId : SV_DispatchThreadID) +{ + + UNITY_XR_ASSIGN_VIEW_INDEX(dispatchThreadId.z); + uint2 pixelCoord0 = uint2(dispatchThreadId.x * 2, dispatchThreadId.y); + uint2 pixelCoord1 = pixelCoord0 + uint2(1, 0); + uint packedProfiles = 0; + + // The result of the stencil test allows us to statically determine the material type (SSS). + SSSData sssData; + DECODE_FROM_SSSBUFFER(pixelCoord0, sssData); + packedProfiles |= sssData.diffusionProfileIndex & 0xF; + + DECODE_FROM_SSSBUFFER(pixelCoord1, sssData); + packedProfiles |= (sssData.diffusionProfileIndex & 0xF) << 4; + + _DiffusionProfileIndexTexture[COORD_TEXTURE2D_X(dispatchThreadId.xy)] = packedProfiles; +} +#endif diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.hlsl index 72f9b6ce..c40f147f 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/SubsurfaceScattering/SubsurfaceScattering.hlsl @@ -174,7 +174,8 @@ void FillMaterialSSS(uint diffusionProfileIndex, float subsurfaceMask, inout BSD bsdfData.diffusionProfileIndex = diffusionProfileIndex; bsdfData.fresnel0 = _TransmissionTintsAndFresnel0[diffusionProfileIndex].a; bsdfData.subsurfaceMask = subsurfaceMask; - bsdfData.materialFeatures |= MATERIALFEATUREFLAGS_SSS_OUTPUT_SPLIT_LIGHTING; + if (subsurfaceMask != 0) + bsdfData.materialFeatures |= MATERIALFEATUREFLAGS_SSS_OUTPUT_SPLIT_LIGHTING; bsdfData.materialFeatures |= GetSubsurfaceScatteringTexturingMode(diffusionProfileIndex) << MATERIALFEATUREFLAGS_SSS_TEXTURING_MODE_OFFSET; } @@ -186,8 +187,15 @@ bool ShouldOutputSplitLighting(BSDFData bsdfData) float3 GetModifiedDiffuseColorForSSS(BSDFData bsdfData) { // Subsurface scattering mode - uint texturingMode = (bsdfData.materialFeatures >> MATERIALFEATUREFLAGS_SSS_TEXTURING_MODE_OFFSET) & 3; - return ApplySubsurfaceScatteringTexturingMode(texturingMode, bsdfData.diffuseColor); + if (bsdfData.subsurfaceMask != 0) + { + uint texturingMode = (bsdfData.materialFeatures >> MATERIALFEATUREFLAGS_SSS_TEXTURING_MODE_OFFSET) & 3; + return ApplySubsurfaceScatteringTexturingMode(texturingMode, bsdfData.diffuseColor); + } + else + { + return bsdfData.diffuseColor; + } } bool GetDualLobeParameters(uint diffusionProfileIndex, out float multiplierA, out float multiplierB, out float lobeMix) diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit.shader b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit.shader index 57566098..dafe0c53 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit.shader +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit.shader @@ -133,6 +133,7 @@ Shader "HDRP/TerrainLit" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile_fragment _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ DYNAMICLIGHTMAP_ON #pragma multi_compile_fragment _ SHADOWS_SHADOWMASK @@ -288,6 +289,7 @@ Shader "HDRP/TerrainLit" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile_fragment _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ DYNAMICLIGHTMAP_ON #pragma multi_compile_fragment _ SHADOWS_SHADOWMASK @@ -369,6 +371,7 @@ Shader "HDRP/TerrainLit" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DYNAMICLIGHTMAP_ON #pragma multi_compile _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 #pragma multi_compile _ DIRLIGHTMAP_COMBINED @@ -403,6 +406,7 @@ Shader "HDRP/TerrainLit" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DYNAMICLIGHTMAP_ON #pragma multi_compile _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 #pragma multi_compile _ DIRLIGHTMAP_COMBINED @@ -438,6 +442,7 @@ Shader "HDRP/TerrainLit" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DYNAMICLIGHTMAP_ON #pragma multi_compile _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 #pragma multi_compile _ DIRLIGHTMAP_COMBINED diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit_Basemap.shader b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit_Basemap.shader index 221da9f4..3f54cecb 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit_Basemap.shader +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit_Basemap.shader @@ -89,6 +89,7 @@ Shader "Hidden/HDRP/TerrainLit_Basemap" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile_fragment _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ DYNAMICLIGHTMAP_ON #pragma multi_compile_fragment _ SHADOWS_SHADOWMASK @@ -227,6 +228,7 @@ Shader "Hidden/HDRP/TerrainLit_Basemap" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile_fragment _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DIRLIGHTMAP_COMBINED #pragma multi_compile _ DYNAMICLIGHTMAP_ON #pragma multi_compile_fragment _ SHADOWS_SHADOWMASK @@ -269,6 +271,7 @@ Shader "Hidden/HDRP/TerrainLit_Basemap" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DYNAMICLIGHTMAP_ON #pragma multi_compile _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 #pragma multi_compile _ DIRLIGHTMAP_COMBINED @@ -303,6 +306,7 @@ Shader "Hidden/HDRP/TerrainLit_Basemap" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DYNAMICLIGHTMAP_ON #pragma multi_compile _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 #pragma multi_compile _ DIRLIGHTMAP_COMBINED @@ -338,6 +342,7 @@ Shader "Hidden/HDRP/TerrainLit_Basemap" #pragma multi_compile _ DEBUG_DISPLAY #pragma multi_compile _ LIGHTMAP_ON + #pragma multi_compile _ LIGHTMAP_BICUBIC_SAMPLING #pragma multi_compile _ DYNAMICLIGHTMAP_ON #pragma multi_compile _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 #pragma multi_compile _ DIRLIGHTMAP_COMBINED diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit_Splatmap.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit_Splatmap.hlsl index 16c16de5..1ce8500b 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit_Splatmap.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/TerrainLit/TerrainLit_Splatmap.hlsl @@ -55,7 +55,7 @@ float3 SampleNormalGrad(TEXTURE2D_PARAM(textureName, samplerName), float2 uv, fl #ifdef UNITY_NO_DXT5nm return UnpackNormalRGB(nrm, scale); #else - return UnpackNormalmapRGorAG(nrm, scale); + return UnpackNormalMapRGorAG(nrm, scale); #endif #endif } diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs index d46d9f6c..60c75990 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs @@ -1868,6 +1868,10 @@ namespace UnityEngine.Rendering.HighDefinition return rtHandleSystem.Alloc(Vector2.one * scaleFactor, TextureXR.slices, filterMode: FilterMode.Point, colorFormat: format, dimension: TextureXR.dimension, useDynamicScale: true, enableRandomWrite: true, name: string.Format("{0}_{1}_{2}", id, name, frameIndex)); } } + + internal bool vrsEnabled => frameSettings.IsEnabled(FrameSettingsField.VariableRateShading) && + camera.cameraType == CameraType.Game && + !xr.enabled; #endregion @@ -2291,8 +2295,10 @@ namespace UnityEngine.Rendering.HighDefinition { // The variance between 0 and the actual halton sequence values reveals noticeable // instability in Unity's shadow maps, so we avoid index 0. - jitterX = HaltonSequence.Get(taaFrameIndex + 1, 2) - 0.5f; - jitterY = HaltonSequence.Get(taaFrameIndex + 1, 3) - 0.5f; + const float basePhaseCount = 8.0f; + int jitterPhaseCount = (int)(basePhaseCount * Mathf.Pow(screenSize.x / actualWidth, 2.0f)); + jitterX = HaltonSequence.Get((taaFrameIndex % jitterPhaseCount) + 1, 2) - 0.5f; + jitterY = HaltonSequence.Get((taaFrameIndex % jitterPhaseCount) + 1, 3) - 0.5f; } if (!(IsFSR2Enabled() || IsDLSSEnabled() || IsTAAUEnabled() || camera.cameraType == CameraType.SceneView)) diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCameraFrameHistoryType.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCameraFrameHistoryType.cs index d4bf472c..08ff02d8 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCameraFrameHistoryType.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCameraFrameHistoryType.cs @@ -67,6 +67,8 @@ namespace UnityEngine.Rendering.HighDefinition PathTracingDenoised, /// Denoised vpath-traced volumetrics scattering frame history. PathTracingVolumetricFogDenoised, + /// Variable rate shading. + Vrs, // WW1MOD Add temporal alpha upscaling AlphaUpscale, diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDProfileId.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDProfileId.cs index fbcbcb60..011ea2ec 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDProfileId.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDProfileId.cs @@ -265,7 +265,7 @@ namespace UnityEngine.Rendering.HighDefinition ApplyExposure, TemporalAntialiasing, UpscalerColorMask, - FSR2, + AdvancedUpscaling, DeepLearningSuperSampling, DepthOfField, DepthOfFieldKernel, diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.PostProcess.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.PostProcess.cs index 25bec214..8ae098fa 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.PostProcess.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.PostProcess.cs @@ -1001,7 +1001,7 @@ namespace UnityEngine.Rendering.HighDefinition RenderGraph renderGraph, HDCamera hdCamera, TextureHandle source, TextureHandle depthBuffer, TextureHandle motionVectors, TextureHandle biasColorMask) { - using (var builder = renderGraph.AddRenderPass("Fidelity FX 2 Super Resolution", out var passData, ProfilingSampler.Get(HDProfileId.FSR2))) + using (var builder = renderGraph.AddRenderPass("Advanced Temporal Upscaling", out var passData, ProfilingSampler.Get(HDProfileId.AdvancedUpscaling))) { passData.parameters = new FSR2Pass.Parameters(); passData.parameters.hdCamera = hdCamera; @@ -1009,7 +1009,7 @@ namespace UnityEngine.Rendering.HighDefinition var viewHandles = new UpscalerResources.ViewResourceHandles(); viewHandles.source = builder.ReadTexture(source); - viewHandles.output = builder.WriteTexture(GetPostprocessUpsampledOutputHandle(hdCamera, renderGraph, "FSR2 destination")); + viewHandles.output = builder.WriteTexture(GetPostprocessUpsampledOutputHandle(hdCamera, renderGraph, "Upscaling destination")); viewHandles.depth = builder.ReadTexture(depthBuffer); viewHandles.motionVectors = builder.ReadTexture(motionVectors); @@ -3662,7 +3662,6 @@ namespace UnityEngine.Rendering.HighDefinition nonJitteredViewProjMatrix0 = data.hdCamera.mainViewConstants.nonJitteredViewProjMatrix; xrId0 = data.hdCamera.xr.multipassId; #endif - Rect viewport = data.hdCamera.finalViewport; LensFlareCommonSRP.ComputeOcclusion( data.parameters.lensFlareShader, data.hdCamera.camera, data.hdCamera.xr, xrId0, @@ -3750,9 +3749,9 @@ namespace UnityEngine.Rendering.HighDefinition builder.SetRenderFunc( (LensFlareData data, RenderGraphContext ctx) => { - Rect viewport = data.hdCamera.finalViewport; float width = (float)data.viewport.x; float height = (float)data.viewport.y; + Rect viewport = new Rect(0, 0, width, height); #if ENABLE_VR && ENABLE_XR_MODULE // Single pass VR diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.Prepass.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.Prepass.cs index 16755bdc..a782b175 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.Prepass.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.Prepass.cs @@ -114,6 +114,8 @@ namespace UnityEngine.Rendering.HighDefinition // Output by the water system to mark underwater pixels (during transparent prepass) public BufferHandle waterLine; + + public TextureHandle shadingRateImage; } TextureHandle CreateDepthBuffer(RenderGraph renderGraph, bool clear, MSAASamples msaaSamples, string name = null, bool disableFallback = true) @@ -128,7 +130,7 @@ namespace UnityEngine.Rendering.HighDefinition TextureDesc depthDesc = new TextureDesc(Vector2.one, true, true) { - format = GraphicsFormat.D32_SFloat_S8_UInt, + format = CoreUtils.GetDefaultDepthStencilFormat(), bindTextureMS = msaa, msaaSamples = msaaSamples, clearBuffer = clear, @@ -303,6 +305,7 @@ namespace UnityEngine.Rendering.HighDefinition result.depthBuffer = CreateDepthBuffer(renderGraph, hdCamera.clearDepth, hdCamera.msaaSamples); result.stencilBuffer = result.depthBuffer; result.renderingLayersBuffer = renderingLayers ? CreateRenderingLayersBuffer(renderGraph, hdCamera.msaaSamples, decalLayers) : renderGraph.defaultResources.blackTextureXR; + result.shadingRateImage = hdCamera.vrsEnabled ? renderGraph.ImportShadingRateImageTexture(RequestVrsHistory(hdCamera, 1)) : TextureHandle.nullHandle; // Allocate VRS texture if needed RenderXROcclusionMeshes(renderGraph, hdCamera, colorBuffer, result.depthBuffer); @@ -1509,7 +1512,7 @@ namespace UnityEngine.Rendering.HighDefinition passData.depthTexture = builder.ReadTexture(output.depthPyramidTexture); passData.downsampledDepthBuffer = builder.UseDepthBuffer(renderGraph.CreateTexture( - new TextureDesc(Vector2.one * hdCamera.lowResScale, true, true) { format = GraphicsFormat.D32_SFloat_S8_UInt, name = "LowResDepthBuffer" }), DepthAccess.Write); + new TextureDesc(Vector2.one * hdCamera.lowResScale, true, true) { format = CoreUtils.GetDefaultDepthStencilFormat(), name = "LowResDepthBuffer" }), DepthAccess.Write); builder.SetRenderFunc( (DownsampleDepthForLowResPassData data, RenderGraphContext context) => diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.RenderGraph.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.RenderGraph.cs index 06c598e7..77ec146e 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.RenderGraph.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.RenderGraph.cs @@ -434,7 +434,8 @@ namespace UnityEngine.Rendering.HighDefinition // Stop XR single pass before rendering screenspace UI StopXRSinglePass(m_RenderGraph, hdCamera); - RenderScreenSpaceOverlayUI(m_RenderGraph, hdCamera, backBuffer); + if (renderRequest.isLast) + RenderScreenSpaceOverlayUI(m_RenderGraph, hdCamera, backBuffer); } } @@ -1002,7 +1003,7 @@ namespace UnityEngine.Rendering.HighDefinition TextureHandle CreateOffscreenUIDepthBuffer(RenderGraph renderGraph, MSAASamples msaaSamples, Rect viewport) { return renderGraph.CreateTexture(new TextureDesc((int)viewport.width, (int)viewport.height, false, true) - { format = GraphicsFormat.D32_SFloat_S8_UInt, clearBuffer = true, msaaSamples = msaaSamples, name = "UI Depth Buffer" }); + { format = CoreUtils.GetDefaultDepthStencilFormat(), clearBuffer = true, msaaSamples = msaaSamples, name = "UI Depth Buffer" }); } @@ -1165,7 +1166,7 @@ namespace UnityEngine.Rendering.HighDefinition { // if refraction is disabled, we did not create a copy of the depth buffer, so we need to create a dummy one here. passData.depthAndStencil = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) - { format = GraphicsFormat.D32_SFloat_S8_UInt, bindTextureMS = hdCamera.msaaSamples != MSAASamples.None, msaaSamples = hdCamera.msaaSamples, clearBuffer = false, name = "Dummy Depth", disableFallBackToImportedTexture = true, fallBackToBlackTexture = false}); + { format = CoreUtils.GetDefaultDepthStencilFormat(), bindTextureMS = hdCamera.msaaSamples != MSAASamples.None, msaaSamples = hdCamera.msaaSamples, clearBuffer = false, name = "Dummy Depth", disableFallBackToImportedTexture = true, fallBackToBlackTexture = false}); } else { @@ -2281,6 +2282,7 @@ namespace UnityEngine.Rendering.HighDefinition normalBufferRG = prepassOutput.resolvedNormalBuffer, motionVectorBufferRG = prepassOutput.resolvedMotionVectorsBuffer, renderingLayerMaskRG = renderingLayerMaskBuffer, + shadingRateImageRG = prepassOutput.shadingRateImage, waterLineRG = prepassOutput.waterLine, }; diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.SubsurfaceScattering.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.SubsurfaceScattering.cs index c23c8b10..81d881bd 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.SubsurfaceScattering.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.SubsurfaceScattering.cs @@ -9,6 +9,7 @@ namespace UnityEngine.Rendering.HighDefinition ComputeShader m_SubsurfaceScatteringCS; ComputeShader m_SubsurfaceScatteringDownsampleCS; int m_SubsurfaceScatteringKernel; + int m_PackDiffusionProfileKernel; int m_SubsurfaceScatteringKernelMSAA; int m_SubsurfaceScatteringDownsampleKernel; Material m_CombineLightingPass; @@ -23,6 +24,7 @@ namespace UnityEngine.Rendering.HighDefinition Vector4[] m_SSSDisabledTransmissionTintsAndFresnel0; Vector4[] m_SSSWorldScalesAndFilterRadiiAndThicknessRemaps; Vector4[] m_SSSDualLobeAndDiffusePower; + Vector4[] m_SSSBorderAttenuationColor; uint[] m_SSSDiffusionProfileHashes; int[] m_SSSDiffusionProfileUpdate; DiffusionProfileSettings[] m_SSSSetDiffusionProfiles; @@ -37,6 +39,7 @@ namespace UnityEngine.Rendering.HighDefinition string kernelName = "SubsurfaceScattering"; m_SubsurfaceScatteringCS = runtimeShaders.subsurfaceScatteringCS; m_SubsurfaceScatteringKernel = m_SubsurfaceScatteringCS.FindKernel(kernelName); + m_PackDiffusionProfileKernel = m_SubsurfaceScatteringCS.FindKernel("PackDiffusionProfile"); m_SubsurfaceScatteringDownsampleCS = runtimeShaders.subsurfaceScatteringDownsampleCS; m_SubsurfaceScatteringDownsampleKernel = m_SubsurfaceScatteringDownsampleCS.FindKernel("Downsample"); @@ -57,6 +60,7 @@ namespace UnityEngine.Rendering.HighDefinition m_SSSDisabledTransmissionTintsAndFresnel0 = new Vector4[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT]; m_SSSWorldScalesAndFilterRadiiAndThicknessRemaps = new Vector4[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT]; m_SSSDualLobeAndDiffusePower = new Vector4[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT]; + m_SSSBorderAttenuationColor = new Vector4[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT]; m_SSSDiffusionProfileHashes = new uint[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT]; m_SSSDiffusionProfileUpdate = new int[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT]; m_SSSSetDiffusionProfiles = new DiffusionProfileSettings[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT]; @@ -109,6 +113,7 @@ namespace UnityEngine.Rendering.HighDefinition m_SSSDisabledTransmissionTintsAndFresnel0[index] = settings.disabledTransmissionTintAndFresnel0; m_SSSWorldScalesAndFilterRadiiAndThicknessRemaps[index] = settings.worldScaleAndFilterRadiusAndThicknessRemap; m_SSSDualLobeAndDiffusePower[index] = settings.dualLobeAndDiffusePower; + m_SSSBorderAttenuationColor[index] = settings.borderAttenuationColor; m_SSSDiffusionProfileHashes[index] = settings.profile.hash; // Erase previous value (This need to be done here individually as in the SSS editor we edit individual component) @@ -141,6 +146,7 @@ namespace UnityEngine.Rendering.HighDefinition cb._TransmissionTintsAndFresnel0[i * 4 + c] = hdCamera.frameSettings.IsEnabled(FrameSettingsField.Transmission) ? m_SSSTransmissionTintsAndFresnel0[i][c] : m_SSSDisabledTransmissionTintsAndFresnel0[i][c]; cb._WorldScalesAndFilterRadiiAndThicknessRemaps[i * 4 + c] = m_SSSWorldScalesAndFilterRadiiAndThicknessRemaps[i][c]; cb._DualLobeAndDiffusePower[i * 4 + c] = m_SSSDualLobeAndDiffusePower[i][c]; + cb._BorderAttenuationColor[i * 4 + c] = m_SSSBorderAttenuationColor[i][c]; } cb._DiffusionProfileHashTable[i * 4] = m_SSSDiffusionProfileHashes[i]; @@ -194,6 +200,7 @@ namespace UnityEngine.Rendering.HighDefinition public ComputeShader subsurfaceScatteringCS; public ComputeShader subsurfaceScatteringDownsampleCS; public int subsurfaceScatteringCSKernel; + public int packDiffusionProfileKernel; public int subsurfaceScatteringDownsampleCSKernel; public int sampleBudget; public int downsampleSteps; @@ -203,6 +210,8 @@ namespace UnityEngine.Rendering.HighDefinition public int numTilesX; public int numTilesY; public int numTilesZ; + public bool useOcclusion; + public Vector2 viewportSize; public TextureHandle colorBuffer; public TextureHandle diffuseBuffer; @@ -211,6 +220,7 @@ namespace UnityEngine.Rendering.HighDefinition public TextureHandle cameraFilteringBuffer; public TextureHandle downsampleBuffer; public TextureHandle sssBuffer; + public TextureHandle diffusionProfileIndex; public BufferHandle coarseStencilBuffer; } @@ -223,10 +233,14 @@ namespace UnityEngine.Rendering.HighDefinition using (var builder = renderGraph.AddRenderPass("Subsurface Scattering", out var passData, ProfilingSampler.Get(HDProfileId.SubsurfaceScattering))) { + passData.useOcclusion = currentAsset.currentPlatformRenderPipelineSettings.subsurfaceScatteringAttenuation; + CoreUtils.SetKeyword(m_SubsurfaceScatteringCS, "ENABLE_MSAA", hdCamera.msaaEnabled); + CoreUtils.SetKeyword(m_SubsurfaceScatteringCS, "USE_SSS_OCCLUSION", passData.useOcclusion); passData.subsurfaceScatteringCS = m_SubsurfaceScatteringCS; passData.subsurfaceScatteringCSKernel = m_SubsurfaceScatteringKernel; + passData.packDiffusionProfileKernel = m_PackDiffusionProfileKernel; passData.subsurfaceScatteringDownsampleCS = m_SubsurfaceScatteringDownsampleCS; passData.subsurfaceScatteringDownsampleCSKernel = m_SubsurfaceScatteringDownsampleKernel; passData.needTemporaryBuffer = NeedTemporarySubsurfaceBuffer() || hdCamera.msaaEnabled; @@ -245,6 +259,18 @@ namespace UnityEngine.Rendering.HighDefinition passData.sssBuffer = builder.ReadTexture(lightingBuffers.sssBuffer); passData.coarseStencilBuffer = builder.ReadBuffer(prepassOutput.coarseStencilBuffer); + if (passData.useOcclusion) + { + passData.diffusionProfileIndex = builder.CreateTransientTexture(new TextureDesc(new Vector2(0.5f, 1f), true, true) + { + colorFormat = GraphicsFormat.R8_UInt, + enableRandomWrite = true, + clearBuffer = false, + name = "Packed Diffusion Profile Index", + }); + passData.viewportSize = hdCamera.screenSize; + } + if (passData.downsampleSteps > 0) { float scale = 1.0f / (1u << passData.downsampleSteps); @@ -253,7 +279,6 @@ namespace UnityEngine.Rendering.HighDefinition { format = GraphicsFormat.B10G11R11_UFloatPack32, enableRandomWrite = true, clearBuffer = true, clearColor = Color.clear, name = "SSSDownsampled" }); } - if (passData.needTemporaryBuffer) { passData.cameraFilteringBuffer = builder.CreateTransientTexture( @@ -298,6 +323,22 @@ namespace UnityEngine.Rendering.HighDefinition ctx.cmd.SetComputeBufferParam(data.subsurfaceScatteringCS, data.subsurfaceScatteringCSKernel, HDShaderIDs._CoarseStencilBuffer, data.coarseStencilBuffer); + // When occlusion is enabled, we pack the 2 diffusion profile indices into a single 8bit texel to improve the bandwidth when fetching the buffer. + // We couldn't pack this data into the lighting buffer because of the MSAA resolve and the precision loss. + if (data.useOcclusion) + { + ctx.cmd.SetComputeTextureParam(data.subsurfaceScatteringCS, data.packDiffusionProfileKernel, HDShaderIDs._DiffusionProfileIndexTexture, data.diffusionProfileIndex); + ctx.cmd.SetComputeTextureParam(data.subsurfaceScatteringCS, data.packDiffusionProfileKernel, HDShaderIDs._SSSBufferTexture, data.sssBuffer); + int xGroupCount = HDUtils.DivRoundUp(Mathf.CeilToInt(data.viewportSize.x / 2.0f), 8); + ctx.cmd.DispatchCompute(data.subsurfaceScatteringCS, data.packDiffusionProfileKernel, xGroupCount, HDUtils.DivRoundUp((int)data.viewportSize.y, 8), data.numTilesZ); + + ctx.cmd.SetComputeTextureParam(data.subsurfaceScatteringCS, data.subsurfaceScatteringCSKernel, HDShaderIDs._DiffusionProfileIndexTexture, data.diffusionProfileIndex); + } + else + { + ctx.cmd.SetComputeTextureParam(data.subsurfaceScatteringCS, data.subsurfaceScatteringCSKernel, HDShaderIDs._DiffusionProfileIndexTexture, TextureXR.GetBlackTexture()); + } + if (data.needTemporaryBuffer) { ctx.cmd.SetComputeTextureParam(data.subsurfaceScatteringCS, data.subsurfaceScatteringCSKernel, HDShaderIDs._CameraFilteringBuffer, data.cameraFilteringBuffer); diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.Vrs.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.Vrs.cs new file mode 100644 index 00000000..dbde84de --- /dev/null +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.Vrs.cs @@ -0,0 +1,73 @@ +using UnityEngine.Rendering.RenderGraphModule; + +namespace UnityEngine.Rendering.HighDefinition +{ + /// + /// Pipeline specifics for VRS + /// + public partial class HDRenderPipeline + { + /// + /// Preprocess VRS resources once at initialization + /// + void VrsInitializeResources() + { + if (!currentPlatformRenderPipelineSettings.supportVariableRateShading) + return; + + Vrs.InitializeResources(); + } + + /// + /// Dispose of preprocessed VRS resources + /// + void VrsDisposeResources() + { + Vrs.DisposeResources(); + } + + /// + /// Get or create VRS image. + /// + /// Camera to get shading rate image from. + /// Number of buffer in history. + /// The created shading rate image handle or null if not possible. + static RTHandle RequestVrsHistory(HDCamera hdCamera, int bufferCount) + { + if (bufferCount > 0) + return RequestVrsRTHandle(hdCamera, bufferCount, (int)HDCameraFrameHistoryType.Vrs); + + return null; + } + + /// + /// Helper function for RequestVrsHistory + /// + static RTHandle RequestVrsRTHandle(HDCamera hdCamera, int bufferCount, int id) + { + if (!ShadingRateInfo.supportsPerImageTile) + return null; // Tile size will be 0x0 and alloc fails. + + return hdCamera.GetCurrentFrameRT(id) ?? + hdCamera.AllocHistoryFrameRT(id, + VrsAllocatorFunction, + bufferCount); + } + + // Static allocator function to avoid allocations. + static RTHandle VrsAllocatorFunction(string viewName, int frameIndex, RTHandleSystem rtHandleSystem) + { + return rtHandleSystem.Alloc(Vector2.one, new RTHandleAllocInfo(name: string.Format("{0}_VrsHistoryBuffer{1}", viewName, frameIndex)) + { + slices = 1, + dimension = TextureDimension.Tex2D, + format = ShadingRateInfo.graphicsFormat, + enableRandomWrite = true, + useDynamicScale = true, + useMipMap = false, + autoGenerateMips = false, + enableShadingRate = true, + }); + } + } +} diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.Vrs.cs.meta b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.Vrs.cs.meta new file mode 100644 index 00000000..0a096393 --- /dev/null +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.Vrs.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 4c557ad7b7244a8ca665e526730e2e77 +timeCreated: 1731086223 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs index 6583da32..9968c8e4 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -681,7 +681,7 @@ namespace UnityEngine.Rendering.HighDefinition m_DepthPyramidMipLevelOffsetsBuffer = new ComputeBuffer(15, sizeof(int) * 2); m_CustomPassColorBuffer = new Lazy(() => RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GetCustomBufferFormat(), enableRandomWrite: true, useDynamicScale: true, name: "CustomPassColorBuffer")); - m_CustomPassDepthBuffer = new Lazy(() => RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.None, useDynamicScale: true, name: "CustomPassDepthBuffer", depthBufferBits: DepthBits.Depth32)); + m_CustomPassDepthBuffer = new Lazy(() => RTHandles.Alloc(Vector2.one, TextureXR.slices, dimension: TextureXR.dimension, colorFormat: GraphicsFormat.None, useDynamicScale: true, name: "CustomPassDepthBuffer", depthBufferBits: CoreUtils.GetDefaultDepthBufferBits())); // For debugging MousePositionDebug.instance.Build(); @@ -718,6 +718,8 @@ namespace UnityEngine.Rendering.HighDefinition LocalVolumetricFogManager.manager.InitializeGraphicsBuffers(asset.currentPlatformRenderPipelineSettings.lightLoopSettings.maxLocalVolumetricFogOnScreen); + VrsInitializeResources(); + #if UNITY_EDITOR GPUInlineDebugDrawer.Initialize(); #endif @@ -934,6 +936,8 @@ namespace UnityEngine.Rendering.HighDefinition /// Is disposing. protected override void Dispose(bool disposing) { + VrsDisposeResources(); + Graphics.ClearRandomWriteTargets(); Graphics.SetRenderTarget(null); DisposeProbeCameraPool(); @@ -1263,6 +1267,11 @@ namespace UnityEngine.Rendering.HighDefinition { cmd.ConfigureFoveatedRendering(hdCamera.xr.foveatedRenderingInfo); } + + if (GraphicsSettings.TryGetRenderPipelineSettings(out var lightmapSamplingSettings)) + CoreUtils.SetKeyword(cmd, "LIGHTMAP_BICUBIC_SAMPLING", lightmapSamplingSettings.useBicubicLightmapSampling); + else + CoreUtils.SetKeyword(cmd, "LIGHTMAP_BICUBIC_SAMPLING", false); } } @@ -1421,6 +1430,7 @@ namespace UnityEngine.Rendering.HighDefinition public List<(HDProbe.RenderData, HDProbe)> viewDependentProbesData; public bool cullingResultIsShared; public XRPass xrPass; + public bool isLast; } private void VisitRenderRequestRecursive(List requests, List visitStatus, int requestIndex, List renderIndices) @@ -2094,33 +2104,18 @@ namespace UnityEngine.Rendering.HighDefinition } } -#if UNITY_2021_1_OR_NEWER - protected override void Render(ScriptableRenderContext renderContext, Camera[] cameras) - { - Render(renderContext, new List(cameras)); - } - -#endif - -#if UNITY_2021_1_OR_NEWER // Only for internal use, outside of SRP people can call Camera.Render() internal void InternalRender(ScriptableRenderContext renderContext, List cameras) { Render(renderContext, cameras); } -#endif - /// /// RenderPipeline Render implementation. /// /// Current ScriptableRenderContext. /// List of cameras to render. -#if UNITY_2021_1_OR_NEWER protected override void Render(ScriptableRenderContext renderContext, List cameras) -#else - protected override void Render(ScriptableRenderContext renderContext, Camera[] cameras) -#endif { #if UNITY_EDITOR // Build target can change in editor so we need to check if the target is supported @@ -2148,11 +2143,7 @@ namespace UnityEngine.Rendering.HighDefinition // This function should be called once every render (once for all camera) LightLoopNewRender(); -#if UNITY_2021_1_OR_NEWER BeginContextRendering(renderContext, cameras); -#else - BeginFrameRendering(renderContext, cameras); -#endif // Check if we can speed up FrameSettings process by skipping history // or go in detail if debug is activated. Done once for all renderer. @@ -2363,6 +2354,7 @@ namespace UnityEngine.Rendering.HighDefinition bool isLast = i == renderRequestIndicesToRender.Count - 1; var renderRequestIndex = renderRequestIndicesToRender[i]; var renderRequest = renderRequests[renderRequestIndex]; + renderRequest.isLast = isLast; var cmd = CommandBufferPool.Get(""); @@ -2431,11 +2423,7 @@ namespace UnityEngine.Rendering.HighDefinition m_RenderGraph.EndFrame(); XRSystem.EndLayout(); -#if UNITY_2021_1_OR_NEWER EndContextRendering(renderContext, cameras); -#else - EndFrameRendering(renderContext, cameras); -#endif } /// @@ -3396,9 +3384,9 @@ namespace UnityEngine.Rendering.HighDefinition { SupportedRenderingFeatures.active.rendersUIOverlay = false; } - // When HDR is active and no XR we enforce UI overlay per camera as we want all UI to be calibrated to white paper inside a single pass - else if (HDROutputForAnyDisplayIsActive()) + else { + // Otherwise we enforce SS UI overlay rendering in HDRP SupportedRenderingFeatures.active.rendersUIOverlay = true; } } diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipelineAsset.Prefiltering.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipelineAsset.Prefiltering.cs index e78db0ae..20f82d26 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipelineAsset.Prefiltering.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipelineAsset.Prefiltering.cs @@ -12,14 +12,20 @@ namespace UnityEngine.Rendering.HighDefinition [ShaderKeywordFilter.SelectOrRemove(true, keywordNames: "USE_LEGACY_LIGHTMAPS")] [SerializeField] private bool m_PrefilterUseLegacyLightmaps = false; + [ShaderKeywordFilter.RemoveIf(false, keywordNames: "LIGHTMAP_BICUBIC_SAMPLING")] + [ShaderKeywordFilter.SelectIf(true, keywordNames: "LIGHTMAP_BICUBIC_SAMPLING")] + [SerializeField] private bool m_PrefilterUseLightmapBicubicSampling = false; + internal struct ShaderPrefilteringData { public bool useLegacyLightmaps; + public bool useBicubicLightmapSampling; } internal void UpdateShaderKeywordPrefiltering(ref ShaderPrefilteringData prefilteringData) { m_PrefilterUseLegacyLightmaps = prefilteringData.useLegacyLightmaps; + m_PrefilterUseLightmapBicubicSampling = prefilteringData.useBicubicLightmapSampling; } } } diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs index 8128ea63..ac83ddd3 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs @@ -443,6 +443,7 @@ namespace UnityEngine.Rendering.HighDefinition public static readonly int _VolumetricMaterialFalloffMode = Shader.PropertyToID("_VolumetricMaterialFalloffMode"); public static readonly int _SSSBufferTexture = Shader.PropertyToID("_SSSBufferTexture"); + public static readonly int _DiffusionProfileIndexTexture = Shader.PropertyToID("_DiffusionProfileIndexTexture"); public static readonly int _NormalBufferTexture = Shader.PropertyToID("_NormalBufferTexture"); public static readonly int _NormalBufferRW = Shader.PropertyToID("_NormalBufferRW"); public static readonly int _RaytracePrepassBufferTexture = Shader.PropertyToID("_RaytracePrepassBufferTexture"); diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs index 4772c8af..2d4a2e98 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/PathTracing/PathTracing.cs @@ -114,8 +114,21 @@ namespace UnityEngine.Rendering.HighDefinition } /// - /// A volume component that holds settings for the Path Tracing effect. + /// Manages the settings for the Path Tracing effect. /// + /// + /// Add a Path Tracing Volume Override to a Volume in your scene to enable and configure the path tracing effect. + /// + /// Enable path tracing in HDRP to interactively visualize highly accurate, physically-based lighting, + /// reflections and global illumination during the scene design process. It's especially useful for tasks like pre-visualization, + /// look development, or validating lighting setups in projects focused on high-quality visuals, such as architectural + /// visualization, automotive design, or cinematic production. This feature is best suited for powerful hardware setups + /// with GPUs that are compatible with DirectX Raytracing (DXR). Path tracing can be also used with the Unity Recorder to capture high fidelity animations. + /// + /// + /// The following example shows how to add or modify a Path Tracing Volume Override from a script. + /// + /// [Serializable, VolumeComponentMenu("Ray Tracing/Path Tracing")] [SupportedOnRenderPipeline(typeof(HDRenderPipelineAsset))] [HDRPHelpURL("Ray-Tracing-Path-Tracing")] @@ -218,6 +231,9 @@ namespace UnityEngine.Rendering.HighDefinition /// /// Default constructor for the path tracing volume component. /// + /// + /// Use the constructor with no arguments to create a new path tracing volume component with default values. + /// public PathTracing() { displayName = "Path Tracing"; diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/CustomPass/CustomPass.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/CustomPass/CustomPass.cs index 0c183738..ff9c62c3 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/CustomPass/CustomPass.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/CustomPass/CustomPass.cs @@ -91,6 +91,11 @@ namespace UnityEngine.Rendering.HighDefinition /// protected virtual bool executeInSceneView => true; + /// + /// True if you want your custom pass to enable and set variable rate shading (VRS) texture. False for regular passes. + /// + protected virtual bool enableVariableRateShading => false; + /// /// Used to select the target buffer when executing the custom pass /// @@ -146,6 +151,7 @@ namespace UnityEngine.Rendering.HighDefinition public TextureHandle normalBufferRG; public TextureHandle motionVectorBufferRG; public TextureHandle renderingLayerMaskRG; + public TextureHandle shadingRateImageRG; public BufferHandle waterLineRG; } @@ -182,7 +188,7 @@ namespace UnityEngine.Rendering.HighDefinition public ShaderVariablesGlobal shaderVariablesGlobal; } - RenderTargets ReadRenderTargets(in RenderGraphBuilder builder, in RenderTargets targets) + RenderTargets ReadRenderTargets(in RenderGraphBuilder builder, in RenderTargets targets, HDCamera hdCamera) { RenderTargets output = new RenderTargets(); @@ -210,6 +216,8 @@ namespace UnityEngine.Rendering.HighDefinition output.renderingLayerMaskRG = builder.ReadTexture(targets.renderingLayerMaskRG); if (targets.waterLineRG.IsValid()) output.waterLineRG = builder.ReadBuffer(targets.waterLineRG); + if (targets.shadingRateImageRG.IsValid() && hdCamera.vrsEnabled) + output.shadingRateImageRG = builder.ReadTexture(targets.shadingRateImageRG); return output; } @@ -228,10 +236,10 @@ namespace UnityEngine.Rendering.HighDefinition passData.hdCamera = hdCamera; passData.shaderVariablesGlobal = HDRenderPipeline.currentPipeline.GetShaderVariablesGlobalCB(); - this.currentRenderTarget = ReadRenderTargets(builder, targets); + this.currentRenderTarget = ReadRenderTargets(builder, targets, hdCamera); builder.SetRenderFunc( - (ExecutePassData data, RenderGraphContext ctx) => + static (ExecutePassData data, RenderGraphContext ctx) => { var customPass = data.customPass; @@ -256,6 +264,18 @@ namespace UnityEngine.Rendering.HighDefinition if (customPass.currentRenderTarget.customDepthBuffer.IsValueCreated) ctx.cmd.SetGlobalTexture(HDShaderIDs._CustomDepthTexture, customPass.currentRenderTarget.customDepthBuffer.Value); + // Imported and allocated in Prepass. + RTHandle sriHandle = data.hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.Vrs); + + bool applyVrs = false; + if (customPass.enableVariableRateShading && sriHandle != null) + { + // NOTE: VRS must be set before setting the target. Vulkan VRS is part of a sub-pass which is created on setting the target. + CoreUtils.SetShadingRateImage(ctx.cmd, sriHandle); + CoreUtils.SetShadingRateCombiner(ctx.cmd, ShadingRateCombinerStage.Fragment, ShadingRateCombiner.Override); + applyVrs = true; + } + if (!customPass.isSetup) { customPass.Setup(ctx.renderContext, ctx.cmd); @@ -277,6 +297,7 @@ namespace UnityEngine.Rendering.HighDefinition customPass.currentRenderTarget.customColorBuffer, customPass.currentRenderTarget.customDepthBuffer, ctx.renderGraphPool.GetTempMaterialPropertyBlock(), + sriHandle, customPass.injectionPoint, data.shaderVariablesGlobal ); @@ -284,6 +305,14 @@ namespace UnityEngine.Rendering.HighDefinition customPass.Execute(customPassCtx); customPass.isExecuting = false; + if (applyVrs) + { + // Set back default variable shading rate states + // NOTE: VRS must be set before setting the target. + CoreUtils.SetShadingRateImage(ctx.cmd, RenderTargetIdentifier.Invalid); + CoreUtils.SetShadingRateCombiner(ctx.cmd, ShadingRateCombinerStage.Fragment, ShadingRateCombiner.Keep); + } + // Set back the camera color buffer if we were using a custom buffer as target if (customPass.targetDepthBuffer != TargetBuffer.Camera) CoreUtils.SetRenderTarget(ctx.cmd, outputColorBuffer); diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/CustomPass/CustomPassContext.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/CustomPass/CustomPassContext.cs index 9199c662..3700ab21 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/CustomPass/CustomPassContext.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/CustomPass/CustomPassContext.cs @@ -67,6 +67,11 @@ namespace UnityEngine.Rendering.HighDefinition /// public readonly MaterialPropertyBlock propertyBlock; + /// + /// Shading rate image buffer for variable shading rate. + /// + public readonly RTHandle shadingRateBuffer; + internal readonly CustomPassInjectionPoint injectionPoint; // This represent the state of HDRP globals at the point of recording the custom passes. // Using GetShaderVariablesGlobals() from HDRP inside the execute of the custom pass would give invalid result @@ -81,6 +86,7 @@ namespace UnityEngine.Rendering.HighDefinition RTHandle cameraNormalBuffer, RTHandle cameraMotionVectorsBuffer, Lazy customColorBuffer, Lazy customDepthBuffer, MaterialPropertyBlock propertyBlock, + RTHandle shadingRateBuffer, CustomPassInjectionPoint injectionPoint, ShaderVariablesGlobal currentGlobalState) { this.renderContext = renderContext; @@ -95,6 +101,7 @@ namespace UnityEngine.Rendering.HighDefinition this.cameraMotionVectorsBuffer = cameraMotionVectorsBuffer; this.customDepthBuffer = customDepthBuffer; this.propertyBlock = propertyBlock; + this.shadingRateBuffer = shadingRateBuffer; this.injectionPoint = injectionPoint; this.currentGlobalState = currentGlobalState; } diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/DrawRenderersCustomPass.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/DrawRenderersCustomPass.cs index 5eb8baf9..749acf11 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/DrawRenderersCustomPass.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/DrawRenderersCustomPass.cs @@ -141,6 +141,16 @@ namespace UnityEngine.Rendering.HighDefinition /// public ShaderPass shaderPass = ShaderPass.Forward; + /// + /// Apply variable rate shading using the shading rate image. + /// + public bool variableRateShading = false; + + /// + /// True if you want your custom pass to enable and set variable rate shading (VRS) texture. False for regular passes. + /// + protected override bool enableVariableRateShading => variableRateShading; + int fadeValueId; static ShaderTagId[] forwardShaderTags; diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR/Runtime/FSR3/Fsr3Upscaler.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR/Runtime/FSR3/Fsr3Upscaler.cs index 56e2a9ab..928b6747 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR/Runtime/FSR3/Fsr3Upscaler.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR/Runtime/FSR3/Fsr3Upscaler.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2024 Nico de Poel +// Copyright (c) 2024 Nico de Poel // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -202,6 +202,10 @@ namespace FidelityFX.FSR3 public float CameraFovAngleVertical; public float ViewSpaceToMetersFactor; public float VelocityFactor = 1.0f; + public float ReactivenessScale = 1.0f; + public float ShadingChangeScale = 1.0f; + public float AccumulationAddedPerFrame = 1.0f / 3.0f; + public float MinDisocclusionAccumulation = -1.0f / 3.0f; public DispatchFlags Flags; public bool UseTextureArrays; // Enable texture array bindings, primarily used for HDRP and XR @@ -269,7 +273,12 @@ namespace FidelityFX.FSR3 public float frameIndex; public Vector2Int inputResourceSize; // WW1MOD + public float velocityFactor; + public float reactivenessScale; + public float shadingChangeScale; + public float accumulationAddedPerFrame; + public float minDisocclusionAccumulation; } [Serializable, StructLayout(LayoutKind.Sequential)] diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR/Runtime/FSR3/Fsr3UpscalerContext.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR/Runtime/FSR3/Fsr3UpscalerContext.cs index e8775667..a2a3ced3 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR/Runtime/FSR3/Fsr3UpscalerContext.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR/Runtime/FSR3/Fsr3UpscalerContext.cs @@ -97,6 +97,10 @@ namespace FidelityFX.FSR3 UpscalerConsts.maxUpscaleSize = _contextDescription.MaxUpscaleSize; UpscalerConsts.velocityFactor = 1.0f; + UpscalerConsts.reactivenessScale = 1.0f; + UpscalerConsts.shadingChangeScale = 1.0f; + UpscalerConsts.accumulationAddedPerFrame = 1.0f / 3.0f; + UpscalerConsts.minDisocclusionAccumulation = -1.0f / 3.0f; _resources.Create(_contextDescription); CreatePasses(); @@ -418,6 +422,10 @@ namespace FidelityFX.FSR3 constants.frameIndex += 1.0f; constants.velocityFactor = dispatchParams.VelocityFactor; + constants.reactivenessScale = dispatchParams.ReactivenessScale; + constants.shadingChangeScale = dispatchParams.ShadingChangeScale; + constants.accumulationAddedPerFrame = dispatchParams.AccumulationAddedPerFrame; + constants.minDisocclusionAccumulation = dispatchParams.MinDisocclusionAccumulation; } private Vector4 SetupDeviceDepthToViewSpaceDepthParams(Fsr3Upscaler.DispatchDescription dispatchParams) diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR/Shaders/shaders/fsr3upscaler/ffx_fsr3upscaler_accumulate.h b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR/Shaders/shaders/fsr3upscaler/ffx_fsr3upscaler_accumulate.h index 73b5ad69..3cb83332 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR/Shaders/shaders/fsr3upscaler/ffx_fsr3upscaler_accumulate.h +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR/Shaders/shaders/fsr3upscaler/ffx_fsr3upscaler_accumulate.h @@ -1,7 +1,7 @@ // This file is part of the FidelityFX SDK. // // Copyright (C) 2024 Advanced Micro Devices, Inc. -// +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files(the "Software"), to deal // in the Software without restriction, including without limitation the rights @@ -46,13 +46,13 @@ void RectifyHistory( FFX_PARAMETER_INOUT AccumulationPassData data ) { - const FfxFloat32 fVecolityFactor = ffxSaturate(params.f4KVelocity / 20.0f); + const FfxFloat32 f4kVelocityFactor = ffxSaturate(params.f4KVelocity / 20.0f); const FfxFloat32 fDistanceFactor = ffxSaturate(0.75f - params.fFarthestDepthInMeters / 20.0f); const FfxFloat32 fAccumulationFactor = 1.0f - params.fAccumulation; const FfxFloat32 fReactiveFactor = ffxPow(params.fReactiveMask, 1.0f / 2.0f); const FfxFloat32 fShadingChangeFactor = params.fShadingChange; - const FfxFloat32 fBoxScaleT = ffxMax(fVecolityFactor, ffxMax(fDistanceFactor, ffxMax(fAccumulationFactor, ffxMax(fReactiveFactor, fShadingChangeFactor)))); - + const FfxFloat32 fBoxScaleT = ffxMax(f4kVelocityFactor, ffxMax(fDistanceFactor, ffxMax(fAccumulationFactor, ffxMax(fReactiveFactor, fShadingChangeFactor)))); + const FfxFloat32 fBoxScale = ffxLerp(3.0f, 1.0f, fBoxScaleT); const FfxFloat32x3 fScaledBoxVec = data.clippingBox.boxVec * FfxFloat32x3(1.7f, 1.0f, 1.0f) * fBoxScale; @@ -148,7 +148,7 @@ void Accumulate(FfxInt32x2 iPxHrPos) if (params.bIsExistingSample && !params.bIsNewSample) { ReprojectHistoryColor(params, data); } - + UpdateLockStatus(params, data); ComputeBaseAccumulationWeight(params, data); diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR/Shaders/shaders/fsr3upscaler/ffx_fsr3upscaler_callbacks_hlsl.h b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR/Shaders/shaders/fsr3upscaler/ffx_fsr3upscaler_callbacks_hlsl.h index 986209e9..ffe3e63f 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR/Shaders/shaders/fsr3upscaler/ffx_fsr3upscaler_callbacks_hlsl.h +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR/Shaders/shaders/fsr3upscaler/ffx_fsr3upscaler_callbacks_hlsl.h @@ -1,7 +1,7 @@ -// This file is part of the FidelityFX SDK. +// This file is part of the FidelityFX SDK. // // Copyright (C) 2024 Advanced Micro Devices, Inc. -// +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files(the "Software"), to deal // in the Software without restriction, including without limitation the rights @@ -77,7 +77,12 @@ cbuffer cbFSR3Upscaler : FFX_FSR3UPSCALER_DECLARE_CB(FSR3UPSCALER_BIND_CB_FSR3UP FfxFloat32 fFrameIndex; FfxInt32x2 iInputResourceSize; // WW1MOD + FfxFloat32 fVelocityFactor; + FfxFloat32 fReactivenessScale; + FfxFloat32 fShadingChangeScale; + FfxFloat32 fAccumulationAddedPerFrame; + FfxFloat32 fMinDisocclusionAccumulation; }; #define FFX_FSR3UPSCALER_CONSTANT_BUFFER_1_SIZE (sizeof(cbFSR3Upscaler) / 4) // Number of 32-bit values. This must be kept in sync with the cbFSR3Upscaler size. @@ -185,6 +190,16 @@ FfxFloat32 VelocityFactor() return fVelocityFactor; } +FfxFloat32 AccumulationAddedPerFrame() +{ + return fAccumulationAddedPerFrame; +} + +FfxFloat32 MinDisocclusionAccumulation() +{ + return fMinDisocclusionAccumulation; +} + #endif // #if defined(FSR3UPSCALER_BIND_CB_FSR3UPSCALER) #define FFX_FSR3UPSCALER_ROOTSIG_STRINGIFY(p) FFX_FSR3UPSCALER_ROOTSIG_STR(p) @@ -392,7 +407,7 @@ UNITY_FSR_TEX2D(FfxFloat32) r_reactive_mask : FFX_FSR3UPSCALER_DECLARE_SRV(FSR3U FfxFloat32 LoadReactiveMask(FfxUInt32x2 iPxPos) { - return r_reactive_mask[UNITY_FSR_POS(iPxPos)]; + return r_reactive_mask[UNITY_FSR_POS(iPxPos)] * fReactivenessScale; } FfxInt32x2 GetReactiveMaskResourceDimensions() @@ -406,7 +421,7 @@ FfxInt32x2 GetReactiveMaskResourceDimensions() FfxFloat32 SampleReactiveMask(FfxFloat32x2 fUV) { - return r_reactive_mask.SampleLevel(s_LinearClamp, UNITY_FSR_UV(fUV), 0).x; + return r_reactive_mask.SampleLevel(s_LinearClamp, UNITY_FSR_UV(fUV), 0).x * fReactivenessScale; } #endif @@ -501,7 +516,7 @@ FfxFloat32x4 SampleLumaHistory(FfxFloat32x2 fUV) } #endif -#if defined(FSR3UPSCALER_BIND_SRV_RCAS_INPUT) +#if defined(FSR3UPSCALER_BIND_SRV_RCAS_INPUT) Texture2D r_rcas_input : FFX_FSR3UPSCALER_DECLARE_SRV(FSR3UPSCALER_BIND_SRV_RCAS_INPUT); FfxFloat32x4 LoadRCAS_Input(FfxInt32x2 iPxPos) @@ -562,12 +577,12 @@ Texture2D r_shading_change : FFX_FSR3UPSCALER_DECLARE_SRV(FSR3UPSCAL FfxFloat32 LoadShadingChange(FfxUInt32x2 iPxPos) { - return r_shading_change[iPxPos]; + return r_shading_change[iPxPos] * fShadingChangeScale; } FfxFloat32 SampleShadingChange(FfxFloat32x2 fUV) { - return r_shading_change.SampleLevel(s_LinearClamp, fUV, 0); + return r_shading_change.SampleLevel(s_LinearClamp, fUV, 0) * fShadingChangeScale; } #endif diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR/Shaders/shaders/fsr3upscaler/ffx_fsr3upscaler_prepare_reactivity.h b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR/Shaders/shaders/fsr3upscaler/ffx_fsr3upscaler_prepare_reactivity.h index fa9571d6..ae24545c 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR/Shaders/shaders/fsr3upscaler/ffx_fsr3upscaler_prepare_reactivity.h +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR/Shaders/shaders/fsr3upscaler/ffx_fsr3upscaler_prepare_reactivity.h @@ -210,15 +210,28 @@ FfxFloat32 UpdateAccumulation(FfxInt32x2 iPxPos, FfxFloat32x2 fUv, FfxFloat32x2 const FfxFloat32x2 fReprojectedUv_HW = ClampUv(fReprojectedUv, PreviousFrameRenderSize(), MaxRenderSize()); fAccumulation = ffxSaturate(SampleAccumulation(fReprojectedUv_HW)); } + const FfxFloat32 fAccumulationAddedPerFrame= AccumulationAddedPerFrame(); //default is 0.333 + // Assume at frame N+0 fShadingChange is 1.0, and all subsequent frames fShadingChange is 0.0 and fDisocclusion is 0.0. Then, + // frame N+0 fAccumulation will be 0.000 + // frame N+2 fAccumulation will be 0.000 + 0.333 * 1 == 0.333 + // frame N+3 fAccumulation will be 0.000 + 0.333 * 2 == 0.666 + // frame N+4 fAccumulation will be 0.000 + 0.333 * 3 == 0.999 fAccumulation = ffxLerp(fAccumulation, 0.0f, fShadingChange); - fAccumulation = ffxLerp(fAccumulation, ffxMin(fAccumulation, 0.25f), fDisocclusion); + + const FfxFloat32 fMinDisocclusionAccumulation = MinDisocclusionAccumulation(); //default is -0.333 + // Assume at frame N+0 fDisocclusion is 1.0, and all subsequent frames fShadingChange is 0.0 and fDisocclusion is 0.0. Then, + // frame N+0 fAccumulation will be -0.333f (but normalized to store in unorm) + // frame N+1 fAccumulation will be -0.333f + 0.333 * 1 == 0.000 + // frame N+2 fAccumulation will be -0.333f + 0.333 * 2 == 0.333 + // frame N+3 fAccumulation will be -0.333f + 0.333 * 3 == 0.666 + // frame N+4 fAccumulation will be -0.333f + 0.333 * 4 == 0.999 + fAccumulation = ffxLerp(fAccumulation, ffxMin(fMinDisocclusionAccumulation, fAccumulation), fDisocclusion); fAccumulation *= FfxFloat32(round(fAccumulation * 100.0f) > 1.0f); // Update for next frame, normalize to store in unorm - const FfxFloat32 fAccumulatedFramesMax = 3.0f; - const FfxFloat32 fAccumulatedFramesToStore = ffxSaturate(fAccumulation + (1.0f / fAccumulatedFramesMax)); + const FfxFloat32 fAccumulatedFramesToStore = ffxSaturate(fAccumulation + fAccumulationAddedPerFrame); StoreAccumulation(iPxPos, fAccumulatedFramesToStore); return fAccumulation; diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/VrsCustomPass.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/VrsCustomPass.cs new file mode 100644 index 00000000..321c96d6 --- /dev/null +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/VrsCustomPass.cs @@ -0,0 +1,110 @@ +using System.Collections.Generic; +using UnityEngine.Rendering; +using UnityEngine.Experimental.Rendering; +using System; + +namespace UnityEngine.Rendering.HighDefinition +{ + /// + /// Variable Rate Shading (VRS) Custom Pass + /// + [System.Serializable] + public class VrsCustomPass : CustomPass + { + /// + /// Color texture to convert into shading rate. + /// + /// Valid colors are defined by the variable rate shading (VRS) look up table (LUT). + /// + /// + public Texture vrsColorMask; + + private Texture m_prevVrsColorMask; + private int m_prevVrsColorMaskHash; + + private Texture2D m_VrsClearMask; + private int m_VrsClearMaskHash; + + /// + /// Called before the first execution of the pass occurs. + /// Allow you to allocate custom buffers. + /// + /// The render context + /// Current command buffer of the frame + protected override void Setup(ScriptableRenderContext renderContext, CommandBuffer cmd) + { + m_VrsClearMask = new Texture2D(1, 1, GraphicsFormat.R8G8B8A8_UNorm, + TextureCreationFlags.DontInitializePixels | TextureCreationFlags.DontUploadUponCreate); + + var lut = VrsLut.CreateDefault(); + m_VrsClearMask.SetPixel(0,0, lut[ShadingRateFragmentSize.FragmentSize1x1]); + m_VrsClearMask.Apply(false, true); + + m_VrsClearMaskHash = CoreUtils.GetTextureHash(m_VrsClearMask); + } + + /// + /// Called when HDRP is destroyed. + /// Allow you to free custom buffers. + /// + protected override void Cleanup() + { + CoreUtils.Destroy(m_VrsClearMask); + } + + /// + /// Generate VRS texture from a color texture. + /// + /// Texture to convert to a shading rate image. + /// CommandBuffer to record conversion operations. + /// Camnera to get settings from. + /// Shading rate image handle, null if conversion is not possible. + RTHandle GenerateVrsFromTexture(Texture colorMaskTexture, CommandBuffer cmd, HDCamera hdCamera) + { + if (colorMaskTexture == null || + (colorMaskTexture.dimension != TextureDimension.Tex2D && colorMaskTexture.dimension != TextureDimension.Tex2DArray)) + { + return null; + } + + var sriRtHandle = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.Vrs); + if (sriRtHandle == null) + return null; + + Vrs.ColorMaskTextureToShadingRateImageDispatch(cmd, sriRtHandle, colorMaskTexture, true); + sriRtHandle.rt.IncrementUpdateCount(); + + return sriRtHandle; + } + + /// + /// Execute the pass with the fullscreen setup + /// + /// The context of the custom pass. Contains command buffer, render context, buffer, etc. + protected override void Execute(CustomPassContext ctx) + { + if (!Vrs.IsColorMaskTextureConversionSupported()) + return; + + bool textureChanged = m_prevVrsColorMask != vrsColorMask; + if(vrsColorMask != null) + textureChanged |= m_prevVrsColorMaskHash != CoreUtils.GetTextureHash(vrsColorMask); + + if (textureChanged) + { + if(vrsColorMask != null) // Generate VRS image from color texture + { + var result = GenerateVrsFromTexture(vrsColorMask, ctx.cmd, ctx.hdCamera); + m_prevVrsColorMaskHash = CoreUtils.GetTextureHash(vrsColorMask); + } + else // Clear VRS image + { + var result = GenerateVrsFromTexture(m_VrsClearMask, ctx.cmd, ctx.hdCamera); + m_prevVrsColorMaskHash = m_VrsClearMaskHash; + } + + m_prevVrsColorMask = vrsColorMask; + } + } + } +} diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/VrsCustomPass.cs.meta b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/VrsCustomPass.cs.meta new file mode 100644 index 00000000..0df11a65 --- /dev/null +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/VrsCustomPass.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c0bc877ec2e444b588114c7a816c1ce5 +timeCreated: 1731004548 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/FrameSettings.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/FrameSettings.cs index 1554e621..90bda813 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/FrameSettings.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/FrameSettings.cs @@ -183,6 +183,9 @@ namespace UnityEngine.Rendering.HighDefinition /// When enabled, HDRP renders custom passes contained in CustomPassVolume components. [FrameSettingsField(0, autoName: CustomPass, customOrderInGroup: 11, tooltip: "When enabled, HDRP renders custom passes contained in CustomPassVolume components.")] CustomPass = 6, + /// When enabled, HDRP renders custom passes contained in CustomPassVolume components. + [FrameSettingsField(0, autoName: VariableRateShading, positiveDependencies: new[] { CustomPass }, customOrderInGroup: 12, tooltip: "When enabled, HDRP updates variable rate shading for Cameras using these Frame Settings.")] + VariableRateShading = 7, /// When enabled, HDRP can use virtual texturing. [FrameSettingsField(0, autoName: VirtualTexturing, customOrderInGroup: 105, tooltip: "Virtual Texturing needs to be enabled first in Project Settings > Player > Other Settings > Virtual Texturing.")] VirtualTexturing = 68, @@ -757,6 +760,10 @@ namespace UnityEngine.Rendering.HighDefinition sanitizedFrameSettings.bitDatas[(uint)FrameSettingsField.CustomPass] &= renderPipelineSettings.supportCustomPass; sanitizedFrameSettings.bitDatas[(uint)FrameSettingsField.CustomPass] &= camera.cameraType != CameraType.Preview; + sanitizedFrameSettings.bitDatas[(uint)FrameSettingsField.VariableRateShading] &= renderPipelineSettings.supportCustomPass; + sanitizedFrameSettings.bitDatas[(uint)FrameSettingsField.VariableRateShading] &= renderPipelineSettings.supportVariableRateShading; + sanitizedFrameSettings.bitDatas[(uint)FrameSettingsField.VariableRateShading] &= camera.cameraType == CameraType.Game; + sanitizedFrameSettings.bitDatas[(uint)FrameSettingsField.CustomPostProcess] &= camera.cameraType != CameraType.Preview; // Deferred opaque are always using Fptl. Forward opaque can use Fptl or Cluster, transparent use cluster. diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/FrameSettingsDefaults.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/FrameSettingsDefaults.cs index 1120ad50..426b56a8 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/FrameSettingsDefaults.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/FrameSettingsDefaults.cs @@ -26,6 +26,7 @@ namespace UnityEngine.Rendering.HighDefinition (uint)FrameSettingsField.TransparentPrepass, (uint)FrameSettingsField.TransparentPostpass, (uint)FrameSettingsField.CustomPass, + (uint)FrameSettingsField.VariableRateShading, (uint)FrameSettingsField.VirtualTexturing, (uint)FrameSettingsField.MotionVectors, // Enable/disable whole motion vectors pass (Camera + Object). (uint)FrameSettingsField.ObjectMotionVectors, diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/RenderPipelineSettings.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/RenderPipelineSettings.cs index 53ced468..24fd5afd 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/RenderPipelineSettings.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Settings/RenderPipelineSettings.cs @@ -103,6 +103,7 @@ namespace UnityEngine.Rendering.HighDefinition supportShadowMask = true, supportSSAO = true, supportSubsurfaceScattering = true, + subsurfaceScatteringAttenuation = true, sssSampleBudget = new IntScalableSetting(new[] { (int)DefaultSssSampleBudgetForQualityLevel.Low, (int)DefaultSssSampleBudgetForQualityLevel.Medium, (int)DefaultSssSampleBudgetForQualityLevel.High }, ScalableSettingSchemaId.With3Levels), @@ -116,6 +117,7 @@ namespace UnityEngine.Rendering.HighDefinition supportTransparentDepthPostpass = true, colorBufferFormat = ColorBufferFormat.R11G11B10, supportCustomPass = true, + supportVariableRateShading = true, customBufferFormat = CustomBufferFormat.R8G8B8A8, supportedLitShaderMode = SupportedLitShaderMode.DeferredOnly, supportDecals = true, @@ -152,6 +154,7 @@ namespace UnityEngine.Rendering.HighDefinition supportWater = false, waterSimulationResolution = WaterSimulationResolution.Medium128, supportWaterExclusion = true, + supportWaterHorizontalDeformation = false, supportWaterDecals = true, waterDecalAtlasSize = WaterAtlasSize.AtlasSize1024, @@ -248,6 +251,8 @@ namespace UnityEngine.Rendering.HighDefinition // [ShaderKeywordFilter.RemoveIf(true, keywordNames: "OUTPUT_SPLIT_LIGHTING")] #endif public bool supportSubsurfaceScattering; + /// Enable SubSurface-Scattering occlusion computation. Enabling this makes the SSS slightly more expensive but add great details to occluded zones with SSS materials. + public bool subsurfaceScatteringAttenuation; /// Sample budget for the Subsurface Scattering algorithm. public IntScalableSetting sssSampleBudget; /// Downsample input texture for the Subsurface Scattering algorithm. @@ -268,6 +273,8 @@ namespace UnityEngine.Rendering.HighDefinition public WaterSimulationResolution waterSimulationResolution; /// Support Water Surfaces exclusion. public bool supportWaterExclusion; + /// Support Water Surfaces Horizontal Deformation. + public bool supportWaterHorizontalDeformation; /// Support Water Surfaces deformation. public bool supportWaterDecals; @@ -310,6 +317,8 @@ namespace UnityEngine.Rendering.HighDefinition public ColorBufferFormat colorBufferFormat; /// Support custom passes. public bool supportCustomPass; + /// Support variable rate shading. + public bool supportVariableRateShading; /// Custom passes buffer format. public CustomBufferFormat customBufferFormat; /// Supported Lit shader modes. diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl index e9fe4012..61823771 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/VertMesh.hlsl @@ -126,6 +126,12 @@ VaryingsToDS InterpolateWithBaryCoordsToDS(VaryingsToDS input0, VaryingsToDS inp #define PackVaryingsType PackVaryingsToPS #endif +#if defined(HAVE_VFX_MODIFICATION) +//compiler shows warning when using intermediate returns (see vfx culling), disable this. +#pragma warning(push) +#pragma warning(disable : 4000) +#endif + // TODO: Here we will also have all the vertex deformation (GPU skinning, vertex animation, morph target...) or we will need to generate a compute shaders instead (better! but require work to deal with unpacking like fp16) VaryingsMeshType VertMesh(AttributesMesh input, float3 worldSpaceOffset #ifdef HAVE_VFX_MODIFICATION @@ -245,6 +251,10 @@ VaryingsMeshType VertMesh(AttributesMesh input, float3 worldSpaceOffset return output; } +#if defined(HAVE_VFX_MODIFICATION) +#pragma warning(pop) +#endif + VaryingsMeshType VertMesh(AttributesMesh input) { #ifdef HAVE_VFX_MODIFICATION diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Settings/HDRPDefaultVolumeProfileSetting.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Settings/HDRPDefaultVolumeProfileSetting.cs index 981ae4c5..ff47063e 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Settings/HDRPDefaultVolumeProfileSetting.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Settings/HDRPDefaultVolumeProfileSetting.cs @@ -7,8 +7,34 @@ using UnityEditor.Rendering; namespace UnityEngine.Rendering.HighDefinition { /// - /// Settings class that stores the default volume profile for Volume Framework. + /// Graphics Settings container for the default used by the . /// + /// + /// To change those settings, go to Editor > Project Settings in the Graphics tab (HDRP). + /// Changing this through API is only allowed in the Editor. In the Player, this raises an error. + /// + /// + /// + /// Here is an example of how to get the default volume profile used by HDRP. + /// + /// using UnityEngine.Rendering; + /// using UnityEngine.Rendering.HighDefinition; + /// + /// public static class URPDefaultVolumeProfileHelper + /// { + /// public static VolumeProfile volumeProfile + /// { + /// get + /// { + /// var gs = GraphicsSettings.GetRenderPipelineSettings<URPDefaultVolumeProfileSettings>(); + /// if (gs == null) //not in HDRP + /// return null; + /// return gs.volumeProfile; + /// } + /// } + /// } + /// + /// [Serializable] [SupportedOnRenderPipeline(typeof(HDRenderPipelineAsset))] [Categorization.CategoryInfo(Name = "Volume", Order = 0)] @@ -24,7 +50,7 @@ namespace UnityEngine.Rendering.HighDefinition [SerializeField][HideInInspector] Version m_Version; - /// Current version. + /// Current version of this settings container. Used only for upgrading the project. public int version => (int)m_Version; #endregion diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Settings/LookDevVolumeProfileSettings.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Settings/LookDevVolumeProfileSettings.cs index 85e66855..cd3226f8 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Settings/LookDevVolumeProfileSettings.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Settings/LookDevVolumeProfileSettings.cs @@ -3,8 +3,36 @@ using System; namespace UnityEngine.Rendering.HighDefinition { /// - /// Settings class that stores the volume profile for HDRP LookDev. + /// A graphics settings container for the used by LookDev with . /// + /// + /// To change those settings, go to Editor > Project Settings in the Graphics tab (HDRP). + /// Changing this through the API is only allowed in the Editor. In the Player, this raises an error. + /// + /// This container is removed from all build Players. + /// + /// + /// + /// Here is an example of how to get the default volume profile used by the LookDev in HDRP. + /// + /// using UnityEngine.Rendering; + /// using UnityEngine.Rendering.HighDefinition; + /// + /// public static class HDRPLookDevVolumeProfileHelper + /// { + /// public static VolumeProfile volumeProfile + /// { + /// get + /// { + /// var gs = GraphicsSettings.GetRenderPipelineSettings<LookDevVolumeProfileSettings>(); + /// if (gs == null) //not in HDRP or in a Player + /// return null; + /// return gs.volumeProfile; + /// } + /// } + /// } + /// + /// [Serializable] [SupportedOnRenderPipeline(typeof(HDRenderPipelineAsset))] [Categorization.CategoryInfo(Name = "Volume", Order = 0)] @@ -20,7 +48,7 @@ namespace UnityEngine.Rendering.HighDefinition [SerializeField][HideInInspector] Version m_Version; - /// Current version. + /// Current version of these settings container. Used only for upgrading a project. public int version => (int)m_Version; #endregion diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesGlobal.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesGlobal.cs index 4477ece5..0efb213d 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesGlobal.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesGlobal.cs @@ -258,6 +258,8 @@ namespace UnityEngine.Rendering.HighDefinition public fixed float _WorldScalesAndFilterRadiiAndThicknessRemaps[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT * 4]; // X = meters per world unit, Y = filter radius (in mm), Z = remap start, W = end - start [HLSLArray(DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT, typeof(Vector4))] public fixed float _DualLobeAndDiffusePower[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT * 4]; // RGB = dual lobe, A = diffuse power + [HLSLArray(DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT, typeof(Vector4))] + public fixed float _BorderAttenuationColor[DiffusionProfileConstants.DIFFUSION_PROFILE_COUNT * 4]; // RGB = dual lobe, A = diffuse power // Because of constant buffer limitation, arrays can only hold 4 components elements (otherwise we get alignment issues) // We could pack the 16 values inside 4 uint4 but then the generated code is inefficient and generates a lots of swizzle operations instead of a single load. // That's why we have 16 uint and only use the first component of each element. diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesGlobal.cs.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesGlobal.cs.hlsl index e598df55..dad5dfaa 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesGlobal.cs.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariablesGlobal.cs.hlsl @@ -152,6 +152,7 @@ GLOBAL_CBUFFER_START(ShaderVariablesGlobal, b0) float4 _TransmissionTintsAndFresnel0[16]; float4 _WorldScalesAndFilterRadiiAndThicknessRemaps[16]; float4 _DualLobeAndDiffusePower[16]; + float4 _BorderAttenuationColor[16]; uint4 _DiffusionProfileHashTable[16]; uint _EnableSubsurfaceScattering; uint _TexturingModeFlags; diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/PhysicallyBasedSky/PhysicallyBasedSkyRenderer.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/PhysicallyBasedSky/PhysicallyBasedSkyRenderer.cs index 1b00ab03..7bd3fae1 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/PhysicallyBasedSky/PhysicallyBasedSkyRenderer.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/PhysicallyBasedSky/PhysicallyBasedSkyRenderer.cs @@ -68,6 +68,9 @@ namespace UnityEngine.Rendering.HighDefinition RTHandle m_AtmosphericScatteringLut; + // BUG: https://jira.unity3d.com/browse/UUM-86915 RwTex3D outputs red. Disable on some devices as a workaround. + bool m_EnableAtmosphericScatteringBlur; + bool IsWorldSpace() => m_InScatteredRadianceTables != null; RTHandle AllocateGroundIrradianceTable() @@ -150,6 +153,13 @@ namespace UnityEngine.Rendering.HighDefinition colorFormat: s_ColorFormat, enableRandomWrite: true, name: "AtmosphericScatteringLUT"); + + // BUG: https://jira.unity3d.com/browse/UUM-86915 + m_EnableAtmosphericScatteringBlur = !(s_ColorFormat == GraphicsFormat.B10G11R11_UFloatPack32 && + SystemInfo.graphicsDeviceName.Contains("Graphics") && + (SystemInfo.graphicsDeviceName.Contains("HD") || // and UHD + SystemInfo.graphicsDeviceName.Contains("Iris") || + SystemInfo.graphicsDeviceName.Contains("Xe"))); } } @@ -269,10 +279,14 @@ namespace UnityEngine.Rendering.HighDefinition // Perform a blur pass on the buffer to reduce resolution artefacts cmd.SetComputeTextureParam(s_SkyLUTGenerator, s_AtmosphericScatteringBlurKernel, HDShaderIDs._AtmosphericScatteringLUT_RW, m_AtmosphericScatteringLut); - cmd.DispatchCompute(s_SkyLUTGenerator, s_AtmosphericScatteringBlurKernel, - 1, - 1, - (int)PbrSkyConfig.AtmosphericScatteringLutDepth); + if(m_EnableAtmosphericScatteringBlur) + { + cmd.DispatchCompute(s_SkyLUTGenerator, s_AtmosphericScatteringBlurKernel, + 1, + 1, + (int)PbrSkyConfig.AtmosphericScatteringLutDepth); + } + } public void BindGlobalBuffers(CommandBuffer cmd) @@ -384,6 +398,8 @@ namespace UnityEngine.Rendering.HighDefinition public override void Cleanup() { + s_DataFrameUpdate = -1; + if (m_PrecomputedData != null) { s_PrecomputationCache.Release(m_LastPrecomputationParamHash); diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyManager.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyManager.cs index 81a7a6a9..0ca9f691 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyManager.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyManager.cs @@ -663,6 +663,12 @@ namespace UnityEngine.Rendering.HighDefinition return m_BlackAmbientProbeBuffer; } + // If a camera is a material preview camera, don't use the scene's ambient spherical harmonics to render it. + if (hdCamera.camera.cameraType == CameraType.Preview) + { + return m_BlackAmbientProbeBuffer; + } + return GetDiffuseAmbientProbeBuffer(GetLightingSky(hdCamera)); } diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Utilities/CameraSettings.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Utilities/CameraSettings.cs index f2e7fa11..287be431 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Utilities/CameraSettings.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Utilities/CameraSettings.cs @@ -91,24 +91,69 @@ namespace UnityEngine.Rendering.HighDefinition public bool clearDepth; } - /// Defines how the volume framework is queried. + /// + /// Defines the settings for querying and evaluating volumes within the framework. + /// This structure contains options for filtering volumes by and customizing the location + /// of volume evaluations through an optional anchor override. + /// These settings control how volumes are processed and how they interact with the scene's camera or other objects. + /// + /// + /// The struct is used for controlling volume behavior, including selecting which volumes + /// to query using the and overriding the default evaluation anchor. It is useful when + /// customizing volume queries and evaluation locations within a scene. + /// [Serializable] public struct Volumes { - /// Default value. - [Obsolete("Since 2019.3, use Volumes.NewDefault() instead.")] + /// + /// Default value for volume settings. This is the default configuration used before any customizations are applied. + /// + /// + /// The default value uses a of -1 (which includes all layers) and a null override + /// for the anchor (indicating no anchor override). + /// + [Obsolete("This field is obsolete use Volumes.NewDefault() instead. #from(2019.3)", true)] public static readonly Volumes @default = default; - /// Default value. - /// The default value. + + /// + /// Creates a new default instance with predefined settings. + /// The default configuration includes a that includes all layers and a null anchor override. + /// + /// The default configuration. + /// + /// + /// Volumes defaultVolumes = Volumes.NewDefault(); + /// + /// + /// + /// This method returns a fresh instance of with default values. It can be used to initialize + /// the volume settings before applying specific customizations like setting the or overriding + /// the evaluation anchor. + /// public static Volumes NewDefault() => new Volumes { layerMask = -1, anchorOverride = null }; - /// The to use for the volumes. + /// + /// The used to filter which volumes should be evaluated. + /// This setting allows you to control which layers are considered during volume evaluation. + /// + /// + /// A of -1 includes all layers, while setting specific values allows you to limit evaluation + /// to certain layers. + /// public LayerMask layerMask; - /// If not null, define the location of the evaluation of the volume framework. + + /// + /// If not null, specifies a custom location for evaluating the volumes. + /// This allows for overriding the default anchor point for volume processing. + /// + /// + /// If is set to null, the default evaluation location is used. This property provides + /// additional flexibility in controlling where volumes are processed within the scene. + /// public Transform anchorOverride; } diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Utilities/VolumeComponentWithQuality.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Utilities/VolumeComponentWithQuality.cs index b1ef8092..5d33352a 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Utilities/VolumeComponentWithQuality.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Utilities/VolumeComponentWithQuality.cs @@ -1,17 +1,35 @@ -using System; - namespace UnityEngine.Rendering.HighDefinition { /// - /// Volume Component that uses Quality Settings. + /// A base class for volume components that use quality settings and HDRP scalable settings to adjust their behavior based on performance tiers. /// + /// + /// This class is designed for volume components that need to change their parameters based on the selected quality level and scalable settings + /// public abstract class VolumeComponentWithQuality : VolumeComponent { - /// Quality level used by this component. + /// + /// Specifies the quality level to be used for performance-relevant parameters. The quality level will adjust + /// the component's behavior based on the selected setting, which helps to optimize performance across different + /// hardware configurations. + /// + /// + /// This parameter allows the user to specify the quality tier (e.g., Low, Medium, High) for specific components + /// that are performance-sensitive. By modifying this parameter, you can tailor the visual fidelity of the component + /// to meet performance requirements. + /// [Tooltip("Specifies the quality level to be used for performance relevant parameters.")] [InspectorName("Tier")] public ScalableSettingLevelParameter quality = new ScalableSettingLevelParameter((int)ScalableSettingLevelParameter.Level.Medium, false); + /// + /// Retrieves the post-processing quality settings from the current pipeline, if available. + /// + /// + /// This method checks the active render pipeline and returns the post-processing quality settings, which determine + /// how post-processing effects are applied depending on the selected quality level. + /// + /// The object, or null if unavailable. static internal GlobalPostProcessingQualitySettings GetPostProcessingQualitySettings() { var pipeline = (HDRenderPipeline)RenderPipelineManager.currentPipeline; @@ -23,6 +41,14 @@ namespace UnityEngine.Rendering.HighDefinition return null; } + /// + /// Retrieves the lighting quality settings from the current pipeline, if available. + /// + /// + /// This method retrieves the lighting quality settings from the active render pipeline. These settings control + /// how lighting is processed and rendered depending on the quality level. + /// + /// The object, or null if unavailable. static internal GlobalLightingQualitySettings GetLightingQualitySettings() { var pipeline = (HDRenderPipeline)RenderPipelineManager.currentPipeline; @@ -35,12 +61,24 @@ namespace UnityEngine.Rendering.HighDefinition } /// - /// Returns true if the component uses parameters from the quality settings. + /// Determines if the component is using parameters from the quality settings. /// - /// True if the component uses parameters from the quality settings. + /// + /// This method checks whether the component uses the current quality settings or whether it is overridden by + /// a custom setting. If the component uses the default quality settings, it will return true. + /// + /// True if the component uses the quality settings; otherwise, false. + /// + /// // Example of usage: + /// if (UsesQualitySettings()) + /// { + /// // Adjust parameters based on quality settings + /// } + /// protected bool UsesQualitySettings() { return !quality.levelAndOverride.useOverride && (HDRenderPipeline)RenderPipelineManager.currentPipeline != null; } } + } diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/VFXGraph/Shaders/VFXDefines.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/VFXGraph/Shaders/VFXDefines.hlsl index 1a1a4e66..d579c93a 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/VFXGraph/Shaders/VFXDefines.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/VFXGraph/Shaders/VFXDefines.hlsl @@ -17,7 +17,6 @@ #if HDRP_LIT #define VFX_NEEDS_POSWS_INTERPOLATOR 1 // Needed for LPPV #elif IS_TRANSPARENT_PARTICLE // Fog for opaque is handled in a dedicated pass -#define USE_FOG 1 #define VFX_NEEDS_POSWS_INTERPOLATOR 1 #endif diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/VFXGraph/Shaders/VFXLit.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/VFXGraph/Shaders/VFXLit.hlsl index 899d9b45..6a0b8b93 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/VFXGraph/Shaders/VFXLit.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/VFXGraph/Shaders/VFXLit.hlsl @@ -12,7 +12,7 @@ #endif #if defined(VFX_MATERIAL_TYPE_SIX_WAY_SMOKE) && (SHADERPASS == SHADERPASS_FORWARD) -//Do nothing. In Six-way lighting forward pass, these includes are required earlier, defined in VFXVertexProbeSampling.template +//Do nothing. In Six-way lighting forward pass, these includes are required earlier, defined in VFXSixWayIncludes.template #else #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Material.hlsl" diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/HDRenderPipeline.WaterSystem.Decals.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/HDRenderPipeline.WaterSystem.Decals.cs index 1d9f9b81..6fbcf34b 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/HDRenderPipeline.WaterSystem.Decals.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/HDRenderPipeline.WaterSystem.Decals.cs @@ -8,7 +8,8 @@ namespace UnityEngine.Rendering.HighDefinition { const float k_FoamIntensityThreshold = 0.015f; - const string k_DeformFoamPassName = nameof(WaterDecal.PassType.DeformationAndFoam); + const string k_DeformPassName = nameof(WaterDecal.PassType.Deformation); + const string k_FoamPassName = nameof(WaterDecal.PassType.Foam); const string k_SimulationMaskPassName = nameof(WaterDecal.PassType.SimulationMask); const string k_LargeCurrentPassName = nameof(WaterDecal.PassType.LargeCurrent); const string k_RipplesCurrentPassName = nameof(WaterDecal.PassType.RipplesCurrent); @@ -17,6 +18,8 @@ namespace UnityEngine.Rendering.HighDefinition int m_DecalAtlasSize; int m_MaxDecalCount; + GlobalKeyword horizontalDeformationKeyword; + // Buffers used to hold all the water foam generators WaterDecalData[] m_WaterDecalDataCPU; ComputeBuffer m_WaterDecalData; @@ -68,6 +71,8 @@ namespace UnityEngine.Rendering.HighDefinition if (!m_ActiveWaterDecals) return; + horizontalDeformationKeyword = GlobalKeyword.Create("HORIZONTAL_DEFORMATION"); + m_DecalAtlasSize = (int)m_RenderPipeline.asset.currentPlatformRenderPipelineSettings.waterDecalAtlasSize; m_MaxDecalCount = m_RenderPipeline.asset.currentPlatformRenderPipelineSettings.maximumWaterDecalCount; @@ -248,7 +253,9 @@ namespace UnityEngine.Rendering.HighDefinition bool ReserveAtlasSpace(WaterDecal.PassType passType, in VisibleDecalData cpuData) => m_DecalAtlas.ReserveSpace(cpuData.MaterialId(passType), cpuData.resX, cpuData.resY); - if ((affectDeformation || affectFoam) && !ReserveAtlasSpace(WaterDecal.PassType.DeformationAndFoam, in cpuData)) + if (affectDeformation && !ReserveAtlasSpace(WaterDecal.PassType.Deformation, in cpuData)) + needRelayout = true; + if (affectFoam && !ReserveAtlasSpace(WaterDecal.PassType.Foam, in cpuData)) needRelayout = true; if (affectMask && !ReserveAtlasSpace(WaterDecal.PassType.SimulationMask, in cpuData)) needRelayout = true; @@ -308,7 +315,8 @@ namespace UnityEngine.Rendering.HighDefinition ref var gpuData = ref m_WaterDecalDataCPU[i]; // Note: we could have all of these in the same pass like for regular SG decals since they render to the same atlas - FetchCoords(in cpuData, WaterDecal.PassType.DeformationAndFoam, k_DeformFoamPassName, ref gpuData.deformFoamScaleOffset); + FetchCoords(in cpuData, WaterDecal.PassType.Deformation, k_DeformPassName, ref gpuData.deformScaleOffset); + FetchCoords(in cpuData, WaterDecal.PassType.Foam, k_FoamPassName, ref gpuData.foamScaleOffset); FetchCoords(in cpuData, WaterDecal.PassType.SimulationMask, k_SimulationMaskPassName, ref gpuData.maskScaleOffset); FetchCoords(in cpuData, WaterDecal.PassType.LargeCurrent, k_LargeCurrentPassName, ref gpuData.largeCurrentScaleOffset); FetchCoords(in cpuData, WaterDecal.PassType.RipplesCurrent, k_RipplesCurrentPassName, ref gpuData.ripplesCurrentScaleOffset); @@ -336,8 +344,7 @@ namespace UnityEngine.Rendering.HighDefinition var perSurfaceCB = m_ShaderVariablesWaterPerSurface[currentWater.surfaceIndex]; currentWater.mpb.SetConstantBuffer(HDShaderIDs._ShaderVariablesWaterPerSurface, perSurfaceCB, 0, perSurfaceCB.stride); - - currentWater.CheckDeformationResources(); + currentWater.CheckDeformationResources(HDRenderPipeline.currentAsset.currentPlatformRenderPipelineSettings.supportWaterHorizontalDeformation); currentWater.CheckFoamResources(cmd); currentWater.CheckMaskResources(); currentWater.CheckCurrentResources(); @@ -412,13 +419,15 @@ namespace UnityEngine.Rendering.HighDefinition // Clear the render target to black and draw all the deformers to the texture // We render in the SG buffer, blur pass will then output to deformation buffer - CoreUtils.SetRenderTarget(cmd, currentWater.deformationSGBuffer, clearFlag: ClearFlag.Color, Color.black); + CoreUtils.SetRenderTarget(cmd, currentWater.deformationSGBuffer, clearFlag: ClearFlag.Color, Color.clear); cmd.DrawProcedural(Matrix4x4.identity, m_DecalMaterial, m_DeformationDecalPass, MeshTopology.Quads, 4, m_NumActiveWaterDecals, currentWater.mpb); currentWater.deformationBuffer.rt.IncrementUpdateCount(); // For the CPU Simulation // Evaluate the normals int numTiles = HDUtils.DivRoundUp((int)currentWater.deformationRes, 8); + cmd.SetKeyword(horizontalDeformationKeyword, HDRenderPipeline.currentAsset.currentPlatformRenderPipelineSettings.supportWaterHorizontalDeformation); + // First we need to clear the edge pixel and blur the deformation a bit cmd.SetComputeTextureParam(m_WaterDeformationCS, m_FilterDeformationKernel, HDShaderIDs._WaterDeformationBuffer, currentWater.deformationSGBuffer); cmd.SetComputeTextureParam(m_WaterDeformationCS, m_FilterDeformationKernel, HDShaderIDs._WaterDeformationBufferRW, currentWater.deformationBuffer); @@ -430,34 +439,37 @@ namespace UnityEngine.Rendering.HighDefinition } } - if ((currentWater.simulationMask || currentWater.supportSimulationFoamMask) && m_ActiveMask) + if (m_EnableDecalWorkflow) { - using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.WaterDecalMask))) + if ((currentWater.simulationMask || currentWater.supportSimulationFoamMask) && m_ActiveMask) { - CoreUtils.SetRenderTarget(cmd, currentWater.maskBuffer, clearFlag: ClearFlag.Color, Color.white); + using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.WaterDecalMask))) + { + CoreUtils.SetRenderTarget(cmd, currentWater.maskBuffer, clearFlag: ClearFlag.Color, Color.white); - cmd.DrawProcedural(Matrix4x4.identity, m_DecalMaterial, m_MaskDecalPass, MeshTopology.Quads, 4, m_NumActiveWaterDecals, currentWater.mpb); - currentWater.maskBuffer.rt.IncrementUpdateCount(); // For the CPU Simulation + cmd.DrawProcedural(Matrix4x4.identity, m_DecalMaterial, m_MaskDecalPass, MeshTopology.Quads, 4, m_NumActiveWaterDecals, currentWater.mpb); + currentWater.maskBuffer.rt.IncrementUpdateCount(); // For the CPU Simulation + } } - } - if (m_ActiveLargeCurrent || m_ActiveRipplesCurrent) - { - using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.WaterDecalCurrent))) + if (m_ActiveLargeCurrent || m_ActiveRipplesCurrent) { - if (currentWater.supportLargeCurrent && m_ActiveLargeCurrent) + using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.WaterDecalCurrent))) { - CoreUtils.SetRenderTarget(cmd, currentWater.largeCurrentBuffer, clearFlag: ClearFlag.Color, Color.black); + if (currentWater.supportLargeCurrent && m_ActiveLargeCurrent) + { + CoreUtils.SetRenderTarget(cmd, currentWater.largeCurrentBuffer, clearFlag: ClearFlag.Color, Color.black); - cmd.DrawProcedural(Matrix4x4.identity, m_DecalMaterial, m_LargeCurrentDecalPass, MeshTopology.Quads, 4, m_NumActiveWaterDecals, currentWater.mpb); - currentWater.largeCurrentBuffer.rt.IncrementUpdateCount(); // For the CPU Simulation - } - if (currentWater.supportRipplesCurrent && m_ActiveRipplesCurrent) - { - CoreUtils.SetRenderTarget(cmd, currentWater.ripplesCurrentBuffer, clearFlag: ClearFlag.Color, Color.black); + cmd.DrawProcedural(Matrix4x4.identity, m_DecalMaterial, m_LargeCurrentDecalPass, MeshTopology.Quads, 4, m_NumActiveWaterDecals, currentWater.mpb); + currentWater.largeCurrentBuffer.rt.IncrementUpdateCount(); // For the CPU Simulation + } + if (currentWater.supportRipplesCurrent && m_ActiveRipplesCurrent) + { + CoreUtils.SetRenderTarget(cmd, currentWater.ripplesCurrentBuffer, clearFlag: ClearFlag.Color, Color.black); - cmd.DrawProcedural(Matrix4x4.identity, m_DecalMaterial, m_RipplesCurrentDecalPass, MeshTopology.Quads, 4, m_NumActiveWaterDecals, currentWater.mpb); - currentWater.ripplesCurrentBuffer.rt.IncrementUpdateCount(); // For the CPU Simulation + cmd.DrawProcedural(Matrix4x4.identity, m_DecalMaterial, m_RipplesCurrentDecalPass, MeshTopology.Quads, 4, m_NumActiveWaterDecals, currentWater.mpb); + currentWater.ripplesCurrentBuffer.rt.IncrementUpdateCount(); // For the CPU Simulation + } } } } diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/HDRenderPipeline.WaterSystem.Underwater.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/HDRenderPipeline.WaterSystem.Underwater.cs index 051de4e5..6be6432b 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/HDRenderPipeline.WaterSystem.Underwater.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/HDRenderPipeline.WaterSystem.Underwater.cs @@ -84,8 +84,11 @@ namespace UnityEngine.Rendering.HighDefinition { if (currentWater.volumeBounds != null) { + var closestPointInVolumeBounds = currentWater.volumeBounds.ClosestPoint(cameraWSPos); + bool isInBounds = (closestPointInVolumeBounds - cameraWSPos).sqrMagnitude < float.Epsilon; + // If the specified bounds contains the camera, we found a match - if (currentWater.volumeBounds.bounds.Contains(cameraWSPos) && currentPriority < currentWater.volumePrority) + if (isInBounds && currentPriority < currentWater.volumePrority) { m_UnderWaterUpHeight = new Vector4(upDirection.x, upDirection.y, upDirection.z, float.MinValue); m_UnderWaterSurfaceIndex = surfaceIdx; diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/HDRenderPipeline.WaterSystem.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/HDRenderPipeline.WaterSystem.cs index be472120..bbfb4bbb 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/HDRenderPipeline.WaterSystem.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/HDRenderPipeline.WaterSystem.cs @@ -46,7 +46,7 @@ namespace UnityEngine.Rendering.HighDefinition internal const string k_TessellationPass = "Tessellation"; readonly static string[] k_PassesGBuffer = new string[] { k_WaterGBufferPass, k_LowResGBufferPass }; readonly static string[] k_PassesGBufferTessellation = new string[] { k_WaterGBufferPass + k_TessellationPass, k_LowResGBufferPass }; - readonly static string[] k_PassesWaterDebug = new string[] { k_WaterDebugPass + k_TessellationPass, k_WaterDebugPass + k_LowResGBufferPass }; + readonly static string[] k_PassesWaterDebug = new string[] { k_WaterDebugPass, k_WaterDebugPass + k_LowResGBufferPass }; // Other internal rendering data MaterialPropertyBlock m_WaterMaterialPropertyBlock; @@ -177,9 +177,9 @@ namespace UnityEngine.Rendering.HighDefinition internal void Cleanup() { - // Grab all the water surfaces in the scene - var waterSurfaces = WaterSurface.instancesAsArray; - int numWaterSurfaces = WaterSurface.instanceCount; + // Grab all the water surfaces in the scene. Including disabled ones (i.e. not in WaterSurface.instances). + var waterSurfaces = Object.FindObjectsByType(FindObjectsSortMode.None); + int numWaterSurfaces = waterSurfaces.Length; // Loop through them and display them for (int surfaceIdx = 0; surfaceIdx < numWaterSurfaces; ++surfaceIdx) diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/Shaders/SampleWaterSurface.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/Shaders/SampleWaterSurface.hlsl index 0ad80ea9..6321f779 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/Shaders/SampleWaterSurface.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/Shaders/SampleWaterSurface.hlsl @@ -75,10 +75,10 @@ float4 EvaluateWaterMask(float3 positionAWS) } // Deformation region -Texture2D _WaterDeformationBuffer; +Texture2D _WaterDeformationBuffer; Texture2D _WaterDeformationSGBuffer; -float EvaluateWaterDeformation(float3 positionAWS) +float4 EvaluateWaterDeformation(float3 positionAWS) { float2 deformationUV = EvaluateDecalUV(positionAWS); return SAMPLE_TEXTURE2D_LOD(_WaterDeformationBuffer, s_linear_clamp_sampler, deformationUV, 0); @@ -286,7 +286,7 @@ void EvaluateSimulationDisplacement(float3 positionOS, out float2 horizontalDisp horizontalDisplacement *= -WATER_SYSTEM_CHOPPINESS; } -void EvaluateVerticalDisplacement(float3 positionOS, float3 verticalDisplacements, out float verticalDisplacement, out float lowFrequencyHeight) +void EvaluateDisplacement(float3 positionOS, float3 verticalDisplacements, out float verticalDisplacement, out float2 horizontalDisplacement, out float lowFrequencyHeight) { // Compute the position that will be used to sample decals float3 positionAWS = GetAbsolutePositionWS(TransformObjectToWorld_Water(positionOS)); @@ -298,11 +298,14 @@ void EvaluateVerticalDisplacement(float3 positionOS, float3 verticalDisplacement verticalDisplacement = dot(verticalDisplacements, waterMask); lowFrequencyHeight = dot(verticalDisplacements.xy, waterMask.xy); + horizontalDisplacement = float2(0, 0); + #if defined(SUPPORT_WATER_DEFORMATION) // Apply the deformation data - float verticalDeformation = EvaluateWaterDeformation(positionAWS); - verticalDisplacement += verticalDeformation; - lowFrequencyHeight += verticalDeformation; + float4 deformation = EvaluateWaterDeformation(positionAWS + verticalDisplacements); + horizontalDisplacement = deformation.yz; + verticalDisplacement += deformation.x; + lowFrequencyHeight += deformation.x; #endif } @@ -314,14 +317,17 @@ struct WaterDisplacementData void EvaluateWaterDisplacement(float3 positionOS, out WaterDisplacementData displacementData) { - float2 horizontalDisplacement; + float2 simulationHorizontalDisplacement; + float2 deformationHorizontalDisplacement; float3 verticalDisplacements; - EvaluateSimulationDisplacement(positionOS, horizontalDisplacement, verticalDisplacements); + EvaluateSimulationDisplacement(positionOS, simulationHorizontalDisplacement, verticalDisplacements); float lowFrequencyHeight; - float3 displacement = float3(horizontalDisplacement.x, 0, horizontalDisplacement.y); - EvaluateVerticalDisplacement(positionOS + displacement, verticalDisplacements, displacement.y, lowFrequencyHeight); + float3 displacement = float3(simulationHorizontalDisplacement.x, 0, simulationHorizontalDisplacement.y); + EvaluateDisplacement(positionOS + displacement, verticalDisplacements, displacement.y, deformationHorizontalDisplacement, lowFrequencyHeight); + displacement.xz += deformationHorizontalDisplacement.xy; + displacementData.displacement = displacement; displacementData.lowFrequencyHeight = lowFrequencyHeight; @@ -429,7 +435,7 @@ void SampleSimulation_PS(WaterSimCoord waterCoord, float3 waterMask, float dista } } -void EvaluateWaterAdditionalData(float3 positionOS, float3 transformedPosition, float3 meshNormalOS, out WaterAdditionalData waterAdditionalData) +void EvaluateWaterAdditionalData(float3 positionOS, float3 transformedPosition, float3 meshNormalOS, float2 horizontalDisplacement, out WaterAdditionalData waterAdditionalData) { ZERO_INITIALIZE(WaterAdditionalData, waterAdditionalData); if (_GridSize.x < 0) @@ -441,7 +447,7 @@ void EvaluateWaterAdditionalData(float3 positionOS, float3 transformedPosition, float distanceToCamera = length(positionRWS); // Get the world space transformed postion float3 transformedAWS = GetAbsolutePositionWS(transformedPosition); - float2 decalUV = EvaluateDecalUV(transformedAWS); + float2 decalUV = EvaluateDecalUV(transformedAWS - float3(horizontalDisplacement.x, 0.0f, horizontalDisplacement.y)); // Compute the texture size param for the filtering float4 texSize = 0.0; @@ -621,12 +627,13 @@ float FindVerticalDisplacement(float3 positionWS, int iterationCount, float dist } float currentHeight; + float2 horizontalDisplacement; float lowFrequencyHeight; - EvaluateVerticalDisplacement(currentLocation, currentVertical, currentHeight, lowFrequencyHeight); + EvaluateDisplacement(currentLocation, currentVertical, currentHeight, horizontalDisplacement, lowFrequencyHeight); #if !defined(WATER_SIMULATION) WaterAdditionalData waterAdditionalData; - EvaluateWaterAdditionalData(currentLocation, GetCameraRelativePositionWS(positionWS), float3(0, 1, 0), waterAdditionalData); + EvaluateWaterAdditionalData(currentLocation, GetCameraRelativePositionWS(positionWS), float3(0, 1, 0), float2(0,0), waterAdditionalData); normal = waterAdditionalData.normalWS; current = OrientationToDirection(_PatchOrientation.x); diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/Shaders/ShaderPassWaterMask.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/Shaders/ShaderPassWaterMask.hlsl index 7592befe..8faed6c7 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/Shaders/ShaderPassWaterMask.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/Shaders/ShaderPassWaterMask.hlsl @@ -115,7 +115,7 @@ void Frag(PackedVaryingsToPS packedInput, else if (_WaterDebugMode == WATERDEBUGMODE_FOAM) { WaterAdditionalData waterAdditionalData; - EvaluateWaterAdditionalData(input.texCoord0.xyy, input.positionRWS, float3(0, 1, 0), waterAdditionalData); + EvaluateWaterAdditionalData(input.texCoord0.xyy, input.positionRWS, float3(0, 1, 0), float2(0, 0), waterAdditionalData); // Checkerboard pattern to visualize resolution float scale = _WaterFoamRegionResolution; diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/Shaders/WaterDecal.shader b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/Shaders/WaterDecal.shader index 2a004f96..685fe085 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/Shaders/WaterDecal.shader +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/Shaders/WaterDecal.shader @@ -97,13 +97,13 @@ Shader "Hidden/HDRP/WaterDecal" Varyings Vert(Attributes input) { WaterDecalData decal = _WaterDecalData[input.instanceID]; - return GetDecalVaryings(input, decal.deformFoamScaleOffset, decal.amplitude); + return GetDecalVaryings(input, decal.deformScaleOffset, decal.amplitude); } - float Frag(Varyings input) : SV_Target + float4 Frag(Varyings input) : SV_Target { float2 uv = RemapUV(input.uv, input.scaleOffset); - return SAMPLE_TEXTURE2D_LOD(_WaterDecalAtlas, s_linear_clamp_sampler, uv, 0).x * input.data.x; + return SAMPLE_TEXTURE2D_LOD(_WaterDecalAtlas, s_linear_clamp_sampler, uv, 0) * input.data.x; } ENDHLSL } @@ -121,7 +121,7 @@ Shader "Hidden/HDRP/WaterDecal" Varyings Vert(Attributes input) { WaterDecalData decal = _WaterDecalData[input.instanceID]; - return GetDecalVaryings(input, decal.deformFoamScaleOffset, float2(decal.surfaceFoamDimmer, decal.deepFoamDimmer)); + return GetDecalVaryings(input, decal.foamScaleOffset, float2(decal.surfaceFoamDimmer, decal.deepFoamDimmer)); } float2 Frag(Varyings input) : SV_Target diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/Shaders/WaterDeformation.compute b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/Shaders/WaterDeformation.compute index a5ce48f8..50aef467 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/Shaders/WaterDeformation.compute +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/Shaders/WaterDeformation.compute @@ -3,6 +3,7 @@ #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch +#pragma multi_compile _ HORIZONTAL_DEFORMATION // #pragma enable_d3d11_debug_symbols // Required to be defined for some includes @@ -16,13 +17,20 @@ #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Water/Shaders/WaterUtilities.hlsl" // FilterDeformation UAV -RWTexture2D _WaterDeformationBufferRW; +#if defined(HORIZONTAL_DEFORMATION) + #define DEFORM_TYPE float4 +#else + #define DEFORM_TYPE float +#endif + +RWTexture2D _WaterDeformationBufferRW; // LDS to load the data #define DISPATCH_SIZE 8 #define FILTER_SIZE_1D (DISPATCH_SIZE + 2) // With a 8x8 group, we have a 10x10 working area #define LDS_SIZE FILTER_SIZE_1D * FILTER_SIZE_1D -groupshared float gs_cacheHeight[LDS_SIZE]; + +groupshared DEFORM_TYPE gs_cacheHeight[LDS_SIZE]; bool IsValidCoord(int2 tapCoord) { @@ -44,7 +52,12 @@ void LoadDeformationIntoLDS(uint groupIndex, uint2 groupOrigin) // Clamp the tap coordinate to the texture space int2 sampleCoord = clamp(tapCoord, 0, _DeformationRegionResolution - 1); - float tapHeight = LOAD_TEXTURE2D(_WaterDeformationBuffer, sampleCoord); + +#if defined(HORIZONTAL_DEFORMATION) + DEFORM_TYPE tapHeight = LOAD_TEXTURE2D(_WaterDeformationBuffer, sampleCoord); +#else + DEFORM_TYPE tapHeight = LOAD_TEXTURE2D(_WaterDeformationBuffer, sampleCoord).x; +#endif // Write the result to the LDS int LDSIndex = offsetX + offsetY * FILTER_SIZE_1D; @@ -74,7 +87,9 @@ void FilterDeformation(uint3 currentThread : SV_DispatchThreadID, // Make sure all values are loaded in LDS by now. GroupMemoryBarrierWithGroupSync(); - float totalDeformation = 0.0; + + DEFORM_TYPE totalDeformation = 0.0; + float sumW = 0.0; for (int y = -1; y <= 1; ++y) { @@ -87,7 +102,7 @@ void FilterDeformation(uint3 currentThread : SV_DispatchThreadID, // Tap from LDS int2 tapAddress = (groupThreadId + 1) + int2(x, y); uint ldsTapAddress = uint(tapAddress.x) % FILTER_SIZE_1D + tapAddress.y * FILTER_SIZE_1D; - float tapHeight = gs_cacheHeight[ldsTapAddress]; + DEFORM_TYPE tapHeight = gs_cacheHeight[ldsTapAddress]; // Accumulate totalDeformation += tapHeight * weight; @@ -114,18 +129,31 @@ void EvaluateDeformationSurfaceGradient(uint3 currentThread : SV_DispatchThreadI uint2 rightCoord = clamp(uint2(centerCoord + uint2(1, 0)), uint2(0, 0), uint2(bound, bound)); uint2 upCoord = clamp(uint2(centerCoord + uint2(0, 1)), uint2(0, 0), uint2(bound, bound)); - // Get the displacement we need for the evaluate (and re-order them) - float displacementCenter = LOAD_TEXTURE2D(_WaterDeformationBuffer, centerCoord); - float displacementRight = LOAD_TEXTURE2D(_WaterDeformationBuffer, rightCoord); - float displacementUp = LOAD_TEXTURE2D(_WaterDeformationBuffer, upCoord); - // Evaluate the displacement normalization factor and pixel size float2 pixelSize = 1.0f / (_DeformationRegionResolution * _DecalRegionScale); + +#if defined(HORIZONTAL_DEFORMATION) + // Get the displacement we need for the evaluate (and re-order them) + float3 displacementCenter = ShuffleDisplacement(LOAD_TEXTURE2D(_WaterDeformationBuffer, centerCoord).xyz); + float3 displacementRight = ShuffleDisplacement(LOAD_TEXTURE2D(_WaterDeformationBuffer, rightCoord).xyz); + float3 displacementUp = ShuffleDisplacement(LOAD_TEXTURE2D(_WaterDeformationBuffer, upCoord).xyz); + + // We evaluate the displacement without the choppiness as it doesn't behave properly for distance surfaces + float3 p0 = displacementCenter; + float3 p1 = displacementRight + float3(pixelSize.x, 0, 0); + float3 p2 = displacementUp + float3(0, 0, pixelSize.y); +#else + // Get the displacement we need for the evaluate (and re-order them) + float displacementCenter = LOAD_TEXTURE2D(_WaterDeformationBuffer, centerCoord).x; + float displacementRight = LOAD_TEXTURE2D(_WaterDeformationBuffer, rightCoord).x; + float displacementUp = LOAD_TEXTURE2D(_WaterDeformationBuffer, upCoord).x; // We evaluate the displacement without the choppiness as it doesn't behave properly for distance surfaces float3 p0 = float3(0, displacementCenter, 0); float3 p1 = float3(pixelSize.x, displacementRight, 0); float3 p2 = float3(0, displacementUp, pixelSize.y); +#endif + float2 surfaceGradient = EvaluateSurfaceGradients(p0, p1, p2); // Make sure the surface gradient is null at the edges diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/Shaders/WaterSimulation.compute b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/Shaders/WaterSimulation.compute index 36987691..2ccf4f83 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/Shaders/WaterSimulation.compute +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/Shaders/WaterSimulation.compute @@ -72,11 +72,6 @@ float2 ComplexMult(float2 a, float2 b) return float2(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x); } -float3 ShuffleDisplacement(float3 displacement) -{ - return float3(-displacement.y, displacement.x, -displacement.z); -} - // InitializePhillipsSpectrum UAVS RWTexture2DArray _H0BufferRW; diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/Shaders/WaterUtilities.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/Shaders/WaterUtilities.hlsl index 235a60aa..949f26fe 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/Shaders/WaterUtilities.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/Shaders/WaterUtilities.hlsl @@ -14,11 +14,27 @@ #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Water/Shaders/SampleWaterSurface.hlsl" #include "Packages/com.unity.render-pipelines.high-definition/Runtime/Water/Shaders/UnderWaterUtilities.hlsl" +// We need this function here because we cannot pass lowFrequencyHeight anymore. +// Instead we pass displacement.y and remap it, it's the same but it contains all frequencies, the look changes slightly but not even to make tests fail so it's more than acceptable. +// We keep the function as is for backwards compatibility. +float RemapLowFrequencyHeight(float lowFrequencyHeight) +{ + lowFrequencyHeight /= _ScatteringWaveHeight; + lowFrequencyHeight = saturate(lowFrequencyHeight * 0.5 + 0.5); + return lowFrequencyHeight; +} + +float3 ShuffleDisplacement(float3 displacement) +{ + return float3(-displacement.y, displacement.x, -displacement.z); +} + float2 EvaluateSurfaceGradients(float3 p0, float3 p1, float3 p2) { float3 v0 = normalize(p1 - p0); float3 v1 = normalize(p2 - p0); float3 geometryNormal = normalize(cross(v1, v0)); + geometryNormal.y = max(abs(geometryNormal.y), 0.01f); return SurfaceGradientFromPerturbedNormal(float3(0, 1, 0), geometryNormal).xz; } @@ -204,7 +220,7 @@ void ComputeWaterRefractionParams(float3 waterPosRWS, float2 positionNDC, float3 float EvaluateTipThickness(float3 viewWS, float3 lowFrequencyNormals, float lowFrequencyHeight) { // Compute the tip thickness - float tipHeight = saturate(lowFrequencyHeight * 2.0 - 1.0); // ignore negative displacement + float tipHeight = saturate(RemapLowFrequencyHeight(lowFrequencyHeight) * 2.0 - 1.0); // ignore negative displacement float3 lowFrequencyRefractedRay = refract(-viewWS, lowFrequencyNormals, WATER_INV_IOR); return GetWaveTipThickness(max(0.01, tipHeight), viewWS, lowFrequencyRefractedRay); } @@ -215,15 +231,14 @@ float3 EvaluateRefractionColor(float3 absorptionTint, float3 caustics) return absorptionTint * caustics * absorptionTint; } -float3 EvaluateScatteringColor(float3 positionOS, float lowFrequencyHeight, float horizontalDisplacement, float3 absorptionTint, float deepFoam) +float3 EvaluateScatteringColor(float3 positionRWS, float lowFrequencyHeight, float3 displacement, float3 absorptionTint, float deepFoam) { // Evaluate the pre-displaced absolute position - float3 positionRWS = TransformObjectToWorld(positionOS); - float distanceToCamera = length(positionRWS); + float distanceToCamera = length(positionRWS - displacement); // Evaluate the scattering terms (where the refraction doesn't happen) - float heightBasedScattering = EvaluateHeightBasedScattering(lowFrequencyHeight, distanceToCamera); - float displacementScattering = EvaluateDisplacementScattering(horizontalDisplacement); + float heightBasedScattering = EvaluateHeightBasedScattering(RemapLowFrequencyHeight(lowFrequencyHeight), distanceToCamera); + float displacementScattering = EvaluateDisplacementScattering(length(displacement.xz)); float ambientScattering = AMBIENT_SCATTERING_INTENSITY * _AmbientScattering; // Sum the scattering terms diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterDecal/WaterDecal.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterDecal/WaterDecal.cs index 13a9e96f..b4844921 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterDecal/WaterDecal.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterDecal/WaterDecal.cs @@ -12,10 +12,11 @@ namespace UnityEngine.Rendering.HighDefinition { internal enum PassType { - DeformationAndFoam = 0, - SimulationMask = 1, - LargeCurrent = 2, - RipplesCurrent = 3, + Deformation = 0, + Foam = 1, + SimulationMask = 2, + LargeCurrent = 3, + RipplesCurrent = 4, } #region General diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterSurface/WaterSurface.Deformation.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterSurface/WaterSurface.Deformation.cs index 27f5aac0..e2f071ef 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterSurface/WaterSurface.Deformation.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterSurface/WaterSurface.Deformation.cs @@ -58,7 +58,7 @@ namespace UnityEngine.Rendering.HighDefinition wsd.waterForwardXZ = float2(worldToWater.m00, worldToWater.m02); } - internal void CheckDeformationResources() + internal void CheckDeformationResources(bool horizontalDeformation = false) { if (deformation) { @@ -68,8 +68,12 @@ namespace UnityEngine.Rendering.HighDefinition if (deformationBuffer == null) { - deformationBuffer = RTHandles.Alloc(resolution, resolution, 1, dimension: TextureDimension.Tex2D, colorFormat: GraphicsFormat.R16_SFloat, enableRandomWrite: true, wrapMode: TextureWrapMode.Clamp, name: "Water Deformation"); - deformationSGBuffer = RTHandles.Alloc(resolution, resolution, 1, dimension: TextureDimension.Tex2D, colorFormat: GraphicsFormat.R16G16_SFloat, enableRandomWrite: true, wrapMode: TextureWrapMode.Clamp, name: "Water Deformation SG"); + // If we support horizontal deformation we need more channels. + var formatDeformationBuffer = horizontalDeformation ? GraphicsFormat.R16G16B16A16_SFloat : GraphicsFormat.R16_SFloat; + var formatDeformationSGBuffer = horizontalDeformation ? GraphicsFormat.R16G16B16A16_SFloat : GraphicsFormat.R16G16_SFloat; + + deformationBuffer = RTHandles.Alloc(resolution, resolution, 1, dimension: TextureDimension.Tex2D, colorFormat: formatDeformationBuffer, enableRandomWrite: true, wrapMode: TextureWrapMode.Clamp, name: "Water Deformation"); + deformationSGBuffer = RTHandles.Alloc(resolution, resolution, 1, dimension: TextureDimension.Tex2D, colorFormat: formatDeformationSGBuffer, enableRandomWrite: true, wrapMode: TextureWrapMode.Clamp, name: "Water Deformation SG"); } } else if (deformationBuffer != null) diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterSurface/WaterSurface.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterSurface/WaterSurface.cs index f4d68f90..e0643e48 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterSurface/WaterSurface.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterSurface/WaterSurface.cs @@ -86,6 +86,7 @@ namespace UnityEngine.Rendering.HighDefinition { #region Instance Management // Management to avoid memory allocations at fetch time + // NOTE: instances tracks active instances, disabled instances can exist and are not included. internal static HashSet instances = new HashSet(); internal static WaterSurface[] instancesAsArray = null; internal static int instanceCount = 0; diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterSystemDef.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterSystemDef.cs index 6d602ab2..72165435 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterSystemDef.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterSystemDef.cs @@ -386,7 +386,8 @@ namespace UnityEngine.Rendering.HighDefinition public float padding1; public float padding2; - public Vector4 deformFoamScaleOffset; + public Vector4 deformScaleOffset; + public Vector4 foamScaleOffset; public Vector4 maskScaleOffset; public Vector4 largeCurrentScaleOffset; public Vector4 ripplesCurrentScaleOffset; diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterSystemDef.cs.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterSystemDef.cs.hlsl index 138e39d2..b1b19984 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterSystemDef.cs.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterSystemDef.cs.hlsl @@ -56,7 +56,8 @@ struct WaterDecalData float padding0; float padding1; float padding2; - float4 deformFoamScaleOffset; + float4 deformScaleOffset; + float4 foamScaleOffset; float4 maskScaleOffset; float4 largeCurrentScaleOffset; float4 ripplesCurrentScaleOffset; diff --git a/Packages/com.unity.render-pipelines.high-definition/Tests/Editor/HDAnalyticsTests_Defaults.txt b/Packages/com.unity.render-pipelines.high-definition/Tests/Editor/HDAnalyticsTests_Defaults.txt index 73220fce..57d04ade 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Tests/Editor/HDAnalyticsTests_Defaults.txt +++ b/Packages/com.unity.render-pipelines.high-definition/Tests/Editor/HDAnalyticsTests_Defaults.txt @@ -4,6 +4,7 @@ {"supportSSAO":"True"}, {"supportSSGI":"False"}, {"supportSubsurfaceScattering":"True"}, +{"subsurfaceScatteringAttenuation":"True"}, {"sssSampleBudget.m_Values":"[20,40,80]"}, {"sssSampleBudget.m_SchemaId.m_Id":"With3Levels"}, {"sssDownsampleSteps.m_Values":"[0,0,0]"}, @@ -15,6 +16,7 @@ {"supportWater":"False"}, {"waterSimulationResolution":"Medium128"}, {"supportWaterExclusion":"True"}, +{"supportWaterHorizontalDeformation":"False"}, {"supportWaterDecals":"True"}, {"waterDecalAtlasSize":"AtlasSize1024"}, {"maximumWaterDecalCount":"48"}, @@ -28,6 +30,7 @@ {"supportTransparentDepthPostpass":"True"}, {"colorBufferFormat":"R11G11B10"}, {"supportCustomPass":"True"}, +{"supportVariableRateShading":"True"}, {"customBufferFormat":"R8G8B8A8"}, {"supportedLitShaderMode":"DeferredOnly"}, {"planarReflectionResolution.m_Values":"[Resolution256,Resolution1024,Resolution2048]"}, diff --git a/Packages/com.unity.render-pipelines.high-definition/package.json b/Packages/com.unity.render-pipelines.high-definition/package.json index 4bfc2a16..81e5a434 100644 --- a/Packages/com.unity.render-pipelines.high-definition/package.json +++ b/Packages/com.unity.render-pipelines.high-definition/package.json @@ -1,17 +1,17 @@ { "name": "com.unity.render-pipelines.high-definition", "description": "The High Definition Render Pipeline (HDRP) is a high-fidelity Scriptable Render Pipeline built by Unity to target modern (Compute Shader compatible) platforms. HDRP utilizes Physically-Based Lighting techniques, linear lighting, HDR lighting, and a configurable hybrid Tile/Cluster deferred/Forward lighting architecture and gives you the tools you need to create games, technical demos, animations, and more to a high graphical standard.", - "version": "17.0.4", - "unity": "6000.0", - "displayName": "High Definition RP", + "version": "17.1.0", + "unity": "6000.1", + "displayName": "High Definition Render Pipeline", "dependencies": { "com.unity.modules.video": "1.0.0", "com.unity.modules.animation": "1.0.0", "com.unity.modules.imageconversion": "1.0.0", - "com.unity.render-pipelines.core": "17.0.4", - "com.unity.shadergraph": "17.0.4", - "com.unity.visualeffectgraph": "17.0.4", - "com.unity.render-pipelines.high-definition-config": "17.0.4" + "com.unity.render-pipelines.core": "17.1.0", + "com.unity.shadergraph": "17.1.0", + "com.unity.visualeffectgraph": "17.1.0", + "com.unity.render-pipelines.high-definition-config": "17.1.0" }, "keywords": [ "graphics", @@ -83,7 +83,7 @@ }, { "displayName": "Water Samples", - "description": "Add a set of examples using the Water System, showcasing various environements using all the features of the system.", + "description": "Add a set of examples using the Water System, showcasing various environments using all the features of the system.", "path": "Samples~/WaterSamples", "dependencies": [ "com.unity.render-pipelines.high-definition/Samples~/Common", @@ -100,5 +100,5 @@ ] } ], - "_fingerprint": "51792a1ba6925f88f17d1060626c3b35c93eaff5" + "_fingerprint": "d227fa58be29c449fb909ae51545deea1ba1a475" } diff --git a/Packages/com.unity.shadergraph/CHANGELOG.md b/Packages/com.unity.shadergraph/CHANGELOG.md index dab411d4..da17ab4a 100644 --- a/Packages/com.unity.shadergraph/CHANGELOG.md +++ b/Packages/com.unity.shadergraph/CHANGELOG.md @@ -12,13 +12,43 @@ The version number for this package has increased due to a version update of a r ## [17.0.3] - 2025-02-13 -This version is compatible with Unity 6000.0.39f1. +This version is compatible with Unity 6000.2.0a1. ### Changed +- Added support for spacewarp to Shader Graph. +- Added a new *Shader Graph UGUI Shaders* sample content set to the Shader Graph package. This sample demonstrates how to use the new Canvas target in Shader Graph to create dynamic UI elements. You can import this sample from the *Samples* tab in the Package Manager after selecting the Shader Graph package. - Removed duplicate LIGHTMAP_ON and DIRLIGHTMAP_COMBINED variants when generating shaders for builtin-deferred. - Added a new set of sample content - Shader Graph UGUI Shaders - to the Shader Graph package that contains examples of how to use the new Canvas target in Shader Graph to create dynamic UI elements. This new sample can be imported from the Sample tab of the Package Manager after selecting the Shader Graph package ### Fixed +- Fixed a bug that a shader graph is reverted to its last saved state when entering Play Mode without saving changes. +- Added missing documentation about the Custom Render Texture in Shader Graph. +- [Metal] Fix shader compilation errors due to Foveated Rendering when building URP 3D template. +- Fixed an issue where the Main Light Direction node always returned 0 on the built-in render pipeline. +- Added new manipulator for ShaderGraph MainPreview to fix wrong drag handing on OSX. +- Fixed an issue where Unity pragmas were not used in files included by the Custom Function Node, and added a "Use Pragmas" toggle to enable/disable them as needed. +- Mark a shader graph dirty when toggling checkboxes in its Graph Settings. +- Fixed Shader warnings in URP ShaderGraph when using the Normal From Texture node. +- Fixed an issue with addding a Vector4 slot in a sub-graph when converting from a node. +- Fixed an issue where an unnecessary error message was generated for non-conflicting duplicate property declarations when using multiple targets. +- Fixed an issue where right-clicking on the Blackboard or Graph Inspector displayed an incorrect context menu. +- Fixed an issue where the Create Node menu remained visible on screen when closing a Shader Graph window. +- Fixed an issue where the Console logged the error "Element 'UnityEditor.UIElements.VisualSplitter' is missing a UxmlElementAttribute" when creating a new node in Shader Graph. +- Fixed "Shader error in 'ProBuilder6/Standard Vertex Color': 'PBRDeferredFragment'" error logged in the console when compiling the shader. +- Allowed latin alphabet for variable names. +- Correct sticky note context menu shortcut display text. +- Color properties now default to opaque (alpha = 1). +- Forum link in info replaced with link to unity discussions. +- Exposed aniso setting on blackboard sampler state properties. +- Added SHADERGRAPH_PREVIEW_MAIN define specifically for main previews. +- Fixed an issue where the Main Preview could be resized beyond its containing Shader Graph window. +- Fixed an issue where using HDR colors with custom Render Texture targets caused errors. +- Fixed an issue where some resources were not properly disposed of when entering Play mode in the Editor. +- Fixed an issue where the property sheet displayed an incorrect type mismatch error for preview properties. +- Fixed a null reference exception that occurred when the Shader Graph Editor was open while entering Play mode. +- Updated the Custom Function Node so that previews are hidden unless the first output is a previewable type, such as a vector or float. +- Fixed an issue where graphs containing groups were unintentionally modified when opening the Shader Graph Editor. +- Enabled custom interpolators for custom sprite lit targets. The shader's *Sprite Custom Lit* material mode now changes the sprite to the desired color instead of remaining black. - Added an issue where convert-to subgraph would sometimes result in an exception. - Added an issue where the GI Node would only display correctly after deserialization. - Added support for perceptual color mode for gradients in shader graph. diff --git a/Packages/com.unity.shadergraph/Editor/AssetCallbacks/CreateShaderSubGraph.cs b/Packages/com.unity.shadergraph/Editor/AssetCallbacks/CreateShaderSubGraph.cs index eda117d7..3f1091a6 100644 --- a/Packages/com.unity.shadergraph/Editor/AssetCallbacks/CreateShaderSubGraph.cs +++ b/Packages/com.unity.shadergraph/Editor/AssetCallbacks/CreateShaderSubGraph.cs @@ -10,7 +10,7 @@ namespace UnityEditor.ShaderGraph public static void CreateMaterialSubGraph() { ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, CreateInstance(), - string.Format("New Shader Sub Graph.{0}", ShaderSubGraphImporter.Extension), null, null); + string.Format("New Shader Sub Graph.{0}", ShaderSubGraphImporter.Extension), ShaderSubGraphImporter.GetIcon(), null); } public override void Action(int instanceId, string pathName, string resourceFile) diff --git a/Packages/com.unity.shadergraph/Editor/Data/Graphs/ColorShaderProperty.cs b/Packages/com.unity.shadergraph/Editor/Data/Graphs/ColorShaderProperty.cs index 9f768ca0..7a8c5169 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Graphs/ColorShaderProperty.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Graphs/ColorShaderProperty.cs @@ -20,6 +20,7 @@ namespace UnityEditor.ShaderGraph.Internal internal ColorShaderProperty() { displayName = "Color"; + value = Color.black; } internal ColorShaderProperty(int version) : this() diff --git a/Packages/com.unity.shadergraph/Editor/Data/Graphs/GraphConcretization.cs b/Packages/com.unity.shadergraph/Editor/Data/Graphs/GraphConcretization.cs index 2b570d13..98dccfb8 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Graphs/GraphConcretization.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Graphs/GraphConcretization.cs @@ -17,7 +17,17 @@ namespace UnityEditor.ShaderGraph // get all property nodes whose property doesn't exist? var propertyNodes = graph.GetNodes().Where(n => !graph.m_Properties.Any(p => p.value == n.property || n.property != null && p.value.objectId == n.property.objectId)).ToArray(); foreach (var pNode in propertyNodes) - graph.ReplacePropertyNodeWithConcreteNodeNoValidate(pNode); + { + if (graph.replaceInProgress) + { + // If the graph is being replaced, the replacement graph should already contain a concrete node for this property node. + graph.RemoveNodeNoValidate(pNode); + } + else + { + graph.ReplacePropertyNodeWithConcreteNodeNoValidate(pNode); + } + } } public static void ConcretizeGraph(GraphData graph) diff --git a/Packages/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs b/Packages/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs index 8b64acbf..120d2c8d 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs @@ -1371,12 +1371,33 @@ namespace UnityEditor.ShaderGraph } } + private static void CollectSubgraphKeywordsR(KeywordCollector collector, SubGraphAsset asset) + { + if (asset is null || !asset.isValid || asset.isNull) + return; + + foreach(var keyword in asset.keywords) + { + collector.AddShaderKeyword(keyword); + } + foreach(var guid in asset.children) + { + var path = AssetDatabase.GUIDToAssetPath(guid); + var child = AssetDatabase.LoadAssetAtPath(path); + CollectSubgraphKeywordsR(collector, child); + } + } + public void CollectShaderKeywords(KeywordCollector collector, GenerationMode generationMode) { foreach (var keyword in keywords) { collector.AddShaderKeyword(keyword); } + foreach(var node in GetNodes()) + { + CollectSubgraphKeywordsR(collector, node.asset); + } // Alwways calculate permutations when collecting collector.CalculateKeywordPermutations(); @@ -2048,7 +2069,7 @@ namespace UnityEditor.ShaderGraph { removedNodeEdges.AddRange(m_Edges); foreach (var edge in removedNodeEdges) - RemoveEdgeNoValidate(edge); + RemoveEdgeNoValidate(edge, false); } using (var nodesToRemove = PooledList.Get()) @@ -2854,6 +2875,8 @@ namespace UnityEditor.ShaderGraph node.OnEnable(); } + // OnEnable may be called multiple times. Ensure the callback only exists once. + ShaderGraphPreferences.onVariantLimitChanged -= OnKeywordChanged; ShaderGraphPreferences.onVariantLimitChanged += OnKeywordChanged; } diff --git a/Packages/com.unity.shadergraph/Editor/Data/Graphs/Texture2DShaderProperty.cs b/Packages/com.unity.shadergraph/Editor/Data/Graphs/Texture2DShaderProperty.cs index de23111c..2446491e 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Graphs/Texture2DShaderProperty.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Graphs/Texture2DShaderProperty.cs @@ -49,7 +49,11 @@ namespace UnityEditor.ShaderGraph.Internal [SerializeField] internal bool useTilingAndOffset = false; + [SerializeField] + internal bool useTexelSize = true; + internal string useSTString => useTilingAndOffset ? "" : "[NoScaleOffset]"; + internal string useTexelSizeString => useTexelSize ? "" : "[NoTexelSize]"; internal string mainTextureString => isMainTexture ? "[MainTexture]" : ""; internal override string GetPropertyBlockString() @@ -67,7 +71,10 @@ namespace UnityEditor.ShaderGraph.Internal action(new HLSLProperty(HLSLType._Texture2D, referenceName, HLSLDeclaration.Global)); action(new HLSLProperty(HLSLType._SamplerState, "sampler" + referenceName, HLSLDeclaration.Global)); - action(new HLSLProperty(HLSLType._float4, referenceName + "_TexelSize", decl)); + if (useTexelSize) + { + action(new HLSLProperty(HLSLType._float4, referenceName + "_TexelSize", decl)); + } if (useTilingAndOffset) { action(new HLSLProperty(HLSLType._float4, referenceName + "_ST", decl)); @@ -90,13 +97,27 @@ namespace UnityEditor.ShaderGraph.Internal return referenceName; else { - if (useTilingAndOffset) + if (useTexelSize) { - return $"UnityBuildTexture2DStruct({referenceName})"; + if (useTilingAndOffset) + { + return $"UnityBuildTexture2DStruct({referenceName})"; + } + else + { + return $"UnityBuildTexture2DStructNoScale({referenceName})"; + } } else { - return $"UnityBuildTexture2DStructNoScale({referenceName})"; + if (useTilingAndOffset) + { + return $"UnityBuildTexture2DStructNoTexelSize({referenceName})"; + } + else + { + return $"UnityBuildTexture2DStructNoScaleNoTexelSize({referenceName})"; + } } } } @@ -142,6 +163,7 @@ namespace UnityEditor.ShaderGraph.Internal value = value, defaultType = defaultType, useTilingAndOffset = useTilingAndOffset, + useTexelSize = useTexelSize, isMainTexture = isMainTexture }; } diff --git a/Packages/com.unity.shadergraph/Editor/Data/Implementation/NodeUtils.cs b/Packages/com.unity.shadergraph/Editor/Data/Implementation/NodeUtils.cs index d593322d..13ed5baa 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Implementation/NodeUtils.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Implementation/NodeUtils.cs @@ -864,9 +864,11 @@ namespace UnityEditor.Graphing if (originalId == null) originalId = ""; - var result = Regex.Replace(originalId, @"^[^A-Za-z0-9_]+|[^A-Za-z0-9_]+$", ""); // trim leading/trailing bad characters (excl '_'). - result = Regex.Replace(result, @"[^A-Za-z0-9]+", "_"); // replace sequences of bad characters with underscores (incl '_'). - + // trim bad sequences (excl '_' to allow '_' as suffix) from start/end. + var result = Regex.Replace(originalId, @"^[^A-Za-zŽžÀ-ÿ0-9_]+|[^A-Za-zŽžÀ-ÿ0-9_]+$", ""); + // replaces bad sequences (incl '_' to prevent '__') with an underscore. + result = Regex.Replace(result, @"[^A-Za-zŽžÀ-ÿ0-9]+", "_"); + for (int i = 0; result.Length == 0 || Char.IsDigit(result[0]) || IsHLSLKeyword(result) || (isDisallowedIdentifier?.Invoke(result) ?? false);) { if (result.StartsWith("_")) diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Lighting/BakedGINode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Lighting/BakedGINode.cs index 3c2e861c..0cde32f1 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Lighting/BakedGINode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Lighting/BakedGINode.cs @@ -76,7 +76,7 @@ namespace UnityEditor.ShaderGraph public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode) { - if (generationMode == GenerationMode.ForReals) + if (generationMode == GenerationMode.ForReals || generationMode == GenerationMode.VFX) { sb.AppendLine("$precision3 {6} = SHADERGRAPH_BAKED_GI({0}, {1}, IN.{2}.xy, {3}, {4}, {5});", GetSlotValue(kPositionWSInputSlotId, generationMode), diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Scene/FogNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Scene/FogNode.cs index ad0822b8..6e742854 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Scene/FogNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Scene/FogNode.cs @@ -4,7 +4,7 @@ using UnityEngine; namespace UnityEditor.ShaderGraph { [Title("Input", "Scene", "Fog")] - class FogNode : CodeFunctionNode + class FogNode : CodeFunctionNode, IMayRequireTransform { public FogNode() { @@ -31,5 +31,7 @@ namespace UnityEditor.ShaderGraph } "; } + + public NeededTransform[] RequiresTransform(ShaderStageCapability stageCapability = ShaderStageCapability.All) => new[] { NeededTransform.ObjectToWorld }; } } diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/TextureStackNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/TextureStackNode.cs index f4b98287..bd1a751d 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/TextureStackNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/TextureStackNode.cs @@ -51,7 +51,6 @@ namespace UnityEditor.ShaderGraph if (vtNode.noFeedback) continue; if (keywordPermutationsPerNode[index] == null) { - Debug.Assert(shaderKeywords.permutations.Count == 0, $"Shader has {shaderKeywords.permutations.Count} permutations but keywordPermutationsPerNode of some nodes are null."); feedbackVariablesPerPermutation[0].Add(vtNode.GetFeedbackVariableName()); } else @@ -68,7 +67,6 @@ namespace UnityEditor.ShaderGraph if (sgNode.asset == null) continue; if (keywordPermutationsPerNode[index] == null) { - Debug.Assert(shaderKeywords.permutations.Count == 0, $"Shader has {shaderKeywords.permutations.Count} permutations but keywordPermutationsPerNode of some nodes are null."); foreach (var feedbackSlot in sgNode.asset.vtFeedbackVariables) { feedbackVariablesPerPermutation[0].Add(node.GetVariableNameForNode() + "_" + feedbackSlot); diff --git a/Packages/com.unity.shadergraph/Editor/Data/SubGraph/SubGraphAsset.cs b/Packages/com.unity.shadergraph/Editor/Data/SubGraph/SubGraphAsset.cs index 023bdeb5..797e52a6 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/SubGraph/SubGraphAsset.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/SubGraph/SubGraphAsset.cs @@ -83,6 +83,8 @@ namespace UnityEditor.ShaderGraph public string assetGuid; + public bool isNull => m_SubGraphData == null; + public ShaderGraphRequirements requirements; public string path; diff --git a/Packages/com.unity.shadergraph/Editor/Data/Util/GraphUtil.cs b/Packages/com.unity.shadergraph/Editor/Data/Util/GraphUtil.cs index b72980df..93815cac 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Util/GraphUtil.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Util/GraphUtil.cs @@ -188,7 +188,7 @@ namespace UnityEditor.ShaderGraph var graphItem = ScriptableObject.CreateInstance(); graphItem.targets = null; ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, graphItem, - string.Format("New Shader Graph.{0}", ShaderGraphImporter.Extension), null, null); + string.Format("New Shader Graph.{0}", ShaderGraphImporter.Extension), ShaderGraphImporter.GetIcon(), null); } public static void CreateNewGraphWithOutputs(Target[] targets, BlockFieldDescriptor[] blockDescriptors) @@ -197,7 +197,7 @@ namespace UnityEditor.ShaderGraph graphItem.targets = targets; graphItem.blocks = blockDescriptors; ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, graphItem, - string.Format("New Shader Graph.{0}", ShaderGraphImporter.Extension), null, null); + string.Format("New Shader Graph.{0}", ShaderGraphImporter.Extension), ShaderGraphImporter.GetIcon(), null); } public static bool TryGetMetadataOfType(this Shader shader, out T obj) where T : ScriptableObject diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/Blackboard/SGBlackboardCategory.cs b/Packages/com.unity.shadergraph/Editor/Drawing/Blackboard/SGBlackboardCategory.cs index e5bd0989..20755251 100644 --- a/Packages/com.unity.shadergraph/Editor/Drawing/Blackboard/SGBlackboardCategory.cs +++ b/Packages/com.unity.shadergraph/Editor/Drawing/Blackboard/SGBlackboardCategory.cs @@ -366,20 +366,37 @@ namespace UnityEditor.ShaderGraph.Drawing RemoveFromClassList("hovered"); } + static bool SelectionContainsAny(IList selection) where T : ISelectable + { + for (var i = 0; i < selection.Count; i++) + { + if (selection[i] is T) + { + return true; + } + } + + return false; + } + void OnDragUpdatedEvent(DragUpdatedEvent evt) { - var selection = DragAndDrop.GetGenericData("DragSelection") as List; + if (DragAndDrop.GetGenericData("DragSelection") is not List dragSelection) + { + SetDragIndicatorVisible(false); + return; + } // Don't show drag indicator if selection has categories, // We don't want category drag & drop to be ambiguous with shader input drag & drop - if (selection.OfType().Any()) + if (SelectionContainsAny(dragSelection)) { SetDragIndicatorVisible(false); return; } // If can't find at least one blackboard field in the selection, don't update drag indicator - if (selection.OfType().Any() == false) + if (!SelectionContainsAny(dragSelection)) { SetDragIndicatorVisible(false); return; @@ -455,13 +472,17 @@ namespace UnityEditor.ShaderGraph.Drawing void OnDragPerformEvent(DragPerformEvent evt) { - var selection = DragAndDrop.GetGenericData("DragSelection") as List; - m_IsDragInProgress = false; + if (DragAndDrop.GetGenericData("DragSelection") is not List dragSelection) + { + SetDragIndicatorVisible(false); + return; + } + // Don't show drag indicator if selection has categories, // We don't want category drag & drop to be ambiguous with shader input drag & drop - if (selection.OfType().Any()) + if (SelectionContainsAny(dragSelection)) { SetDragIndicatorVisible(false); return; @@ -476,7 +497,7 @@ namespace UnityEditor.ShaderGraph.Drawing // Map of containing categories to the actual dragged elements within them SortedDictionary> draggedElements = new SortedDictionary>(); - foreach (ISelectable selectedElement in selection) + foreach (ISelectable selectedElement in dragSelection) { var draggedElement = selectedElement as VisualElement; if (draggedElement == null) @@ -588,7 +609,7 @@ namespace UnityEditor.ShaderGraph.Drawing m_ViewModel.requestModelChangeAction(moveShaderInputAction); // Make sure to remove the element from the selection so it doesn't get re-handled by the blackboard as well, leads to duplicates - selection.Remove(blackboardField); + dragSelection.Remove(blackboardField); if (insertIndex > indexOfDraggedElement) continue; @@ -647,7 +668,7 @@ namespace UnityEditor.ShaderGraph.Drawing m_ViewModel.requestModelChangeAction(addItemToCategoryAction); // Make sure to remove the element from the selection so it doesn't get re-handled by the blackboard as well, leads to duplicates - selection.Remove(blackboardField); + dragSelection.Remove(blackboardField); // If adding to the end of the list, we no longer need to increment the index if (insertIndex != -1) diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/Controllers/BlackboardCategoryController.cs b/Packages/com.unity.shadergraph/Editor/Drawing/Controllers/BlackboardCategoryController.cs index cea9bd2c..c2197882 100644 --- a/Packages/com.unity.shadergraph/Editor/Drawing/Controllers/BlackboardCategoryController.cs +++ b/Packages/com.unity.shadergraph/Editor/Drawing/Controllers/BlackboardCategoryController.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using UnityEditor.Experimental.GraphView; using UnityEditor.Graphing; +using UnityEditor.Graphing.Util; using UnityEditor.ShaderGraph.Internal; using UnityEngine; using UnityEngine.Assertions; @@ -157,15 +158,17 @@ namespace UnityEditor.ShaderGraph.Drawing switch (changeAction) { case AddShaderInputAction addBlackboardItemAction: + var addedInteractively = addBlackboardItemAction.addInputActionType == AddShaderInputAction.AddActionSource.AddMenu; if (addBlackboardItemAction.shaderInputReference != null && IsInputInCategory(addBlackboardItemAction.shaderInputReference)) { var blackboardRow = FindBlackboardRow(addBlackboardItemAction.shaderInputReference); if (blackboardRow == null) - blackboardRow = InsertBlackboardRow(addBlackboardItemAction.shaderInputReference); + blackboardRow = InsertBlackboardRow(addBlackboardItemAction.shaderInputReference, ensureVisible: addedInteractively); + // Rows should auto-expand when an input is first added // blackboardRow.expanded = true; var propertyView = blackboardRow.Q(); - if (addBlackboardItemAction.addInputActionType == AddShaderInputAction.AddActionSource.AddMenu) + if (addedInteractively) propertyView.OpenTextEditor(); } break; @@ -174,7 +177,7 @@ namespace UnityEditor.ShaderGraph.Drawing // In the specific case of only-one keywords like Material Quality and Raytracing, they can get copied, but because only one can exist, the output copied value is null if (copyShaderInputAction.copiedShaderInput != null && IsInputInCategory(copyShaderInputAction.copiedShaderInput)) { - var blackboardRow = InsertBlackboardRow(copyShaderInputAction.copiedShaderInput, copyShaderInputAction.insertIndex); + var blackboardRow = InsertBlackboardRow(copyShaderInputAction.copiedShaderInput, copyShaderInputAction.insertIndex, ensureVisible: true); if (blackboardRow != null) { var graphView = ViewModel.parentView.GetFirstAncestorOfType(); @@ -188,7 +191,8 @@ namespace UnityEditor.ShaderGraph.Drawing // If item was added to category that this controller manages, then add blackboard row to represent that item if (addItemToCategoryAction.itemToAdd != null && addItemToCategoryAction.categoryGuid == ViewModel.associatedCategoryGuid) { - InsertBlackboardRow(addItemToCategoryAction.itemToAdd, addItemToCategoryAction.indexToAddItemAt); + var dragged = addItemToCategoryAction.addActionSource == AddItemToCategoryAction.AddActionSource.DragDrop; + InsertBlackboardRow(addItemToCategoryAction.itemToAdd, addItemToCategoryAction.indexToAddItemAt, ensureVisible: !dragged); } else { @@ -246,7 +250,7 @@ namespace UnityEditor.ShaderGraph.Drawing // Creates controller, view and view model for a blackboard item and adds the view to the specified index in the category // By default adds it to the end of the list if no insertionIndex specified - internal SGBlackboardRow InsertBlackboardRow(BlackboardItem shaderInput, int insertionIndex = -1) + internal SGBlackboardRow InsertBlackboardRow(BlackboardItem shaderInput, int insertionIndex = -1, bool ensureVisible = false) { var shaderInputViewModel = new ShaderInputViewModel() { @@ -258,16 +262,23 @@ namespace UnityEditor.ShaderGraph.Drawing m_BlackboardItemControllers.TryGetValue(shaderInput.objectId, out var existingItemController); if (existingItemController == null) { + var itemView = blackboardItemController.BlackboardItemView; m_BlackboardItemControllers.Add(shaderInput.objectId, blackboardItemController); + // If no index specified, or if trying to insert at last index, add to end of category - if (insertionIndex == -1 || insertionIndex == m_BlackboardItemControllers.Count() - 1) + if (insertionIndex == -1 || insertionIndex == m_BlackboardItemControllers.Count - 1) blackboardCategoryView.Add(blackboardItemController.BlackboardItemView); else blackboardCategoryView.Insert(insertionIndex, blackboardItemController.BlackboardItemView); blackboardCategoryView.MarkDirtyRepaint(); - return blackboardItemController.BlackboardItemView; + if (ensureVisible) + { + blackboard.scrollView.ScrollToElementAfterGeometryChange(itemView); + } + + return itemView; } else { diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/Controllers/BlackboardController.cs b/Packages/com.unity.shadergraph/Editor/Drawing/Controllers/BlackboardController.cs index 155658d3..c5ea520a 100644 --- a/Packages/com.unity.shadergraph/Editor/Drawing/Controllers/BlackboardController.cs +++ b/Packages/com.unity.shadergraph/Editor/Drawing/Controllers/BlackboardController.cs @@ -5,6 +5,7 @@ using UnityEditor.Experimental.GraphView; using UnityEngine.UIElements; using System; using UnityEditor.Graphing; +using UnityEditor.Graphing.Util; using UnityEditor.ShaderGraph.Internal; using GraphDataStore = UnityEditor.ShaderGraph.DataStore; using BlackboardItem = UnityEditor.ShaderGraph.Internal.ShaderInput; @@ -569,7 +570,7 @@ namespace UnityEditor.ShaderGraph.Drawing internal string editorPrefsBaseKey => "unity.shadergraph." + DataStore.State.objectId; - BlackboardCategoryController AddBlackboardCategory(GraphDataStore graphDataStore, CategoryData categoryInfo) + BlackboardCategoryController AddBlackboardCategory(GraphDataStore graphDataStore, CategoryData categoryInfo, bool ensureVisible = false) { var blackboardCategoryViewModel = new BlackboardCategoryViewModel(); blackboardCategoryViewModel.parentView = blackboard; @@ -583,19 +584,26 @@ namespace UnityEditor.ShaderGraph.Drawing { m_BlackboardCategoryControllers.Add(categoryInfo.categoryGuid, blackboardCategoryController); m_DefaultCategoryController = m_BlackboardCategoryControllers.Values.FirstOrDefault(); + + if (ensureVisible) + { + blackboard.scrollView.ScrollToElementAfterGeometryChange(blackboardCategoryController.blackboardCategoryView); + } + } else { AssertHelpers.Fail("Failed to add category controller due to category with same GUID already having been added."); return null; } + return blackboardCategoryController; } // Creates controller, view and view model for a blackboard item and adds the view to the specified index in the category - SGBlackboardRow InsertBlackboardRow(BlackboardItem shaderInput, int insertionIndex = -1) + SGBlackboardRow InsertBlackboardRow(BlackboardItem shaderInput, int insertionIndex = -1, bool ensureVisible = false) { - return m_DefaultCategoryController.InsertBlackboardRow(shaderInput, insertionIndex); + return m_DefaultCategoryController.InsertBlackboardRow(shaderInput, insertionIndex, ensureVisible); } public void UpdateBlackboardTitle(string newTitle) @@ -612,6 +620,7 @@ namespace UnityEditor.ShaderGraph.Drawing // Called by GraphDataStore.Subscribe after the model has been changed protected override void ModelChanged(GraphData graphData, IGraphDataAction changeAction) { + if (ViewModel == null) return; // Reconstruct view-model first // TODO: hide this more generically for category types. bool useDropdowns = graphData.isSubGraph; @@ -625,11 +634,12 @@ namespace UnityEditor.ShaderGraph.Drawing case AddShaderInputAction addBlackboardItemAction: if (IsInputUncategorized(addBlackboardItemAction.shaderInputReference)) { - var blackboardRow = InsertBlackboardRow(addBlackboardItemAction.shaderInputReference); + var addedInteractively = addBlackboardItemAction.addInputActionType == AddShaderInputAction.AddActionSource.AddMenu; + var blackboardRow = InsertBlackboardRow(addBlackboardItemAction.shaderInputReference, ensureVisible: addedInteractively); if (blackboardRow != null) { var propertyView = blackboardRow.Q(); - if (addBlackboardItemAction.addInputActionType == AddShaderInputAction.AddActionSource.AddMenu) + if (addedInteractively) propertyView.OpenTextEditor(); } } @@ -654,7 +664,7 @@ namespace UnityEditor.ShaderGraph.Drawing // In the specific case of only-one keywords like Material Quality and Raytracing, they can get copied, but because only one can exist, the output copied value is null if (copyShaderInputAction.copiedShaderInput != null && IsInputUncategorized(copyShaderInputAction.copiedShaderInput)) { - var blackboardRow = InsertBlackboardRow(copyShaderInputAction.copiedShaderInput, copyShaderInputAction.insertIndex); + var blackboardRow = InsertBlackboardRow(copyShaderInputAction.copiedShaderInput, copyShaderInputAction.insertIndex, ensureVisible: true); var propertyView = blackboardRow.Q(); graphView?.AddToSelectionNoUndoRecord(propertyView); } @@ -662,7 +672,7 @@ namespace UnityEditor.ShaderGraph.Drawing break; case AddCategoryAction addCategoryAction: - AddBlackboardCategory(DataStore, addCategoryAction.categoryDataReference); + AddBlackboardCategory(DataStore, addCategoryAction.categoryDataReference, ensureVisible: true); // Iterate through anything that is selected currently foreach (var selectedElement in blackboard.selection.ToList()) { @@ -695,7 +705,7 @@ namespace UnityEditor.ShaderGraph.Drawing break; case CopyCategoryAction copyCategoryAction: - var blackboardCategory = AddBlackboardCategory(graphData.owner.graphDataStore, copyCategoryAction.newCategoryDataReference); + var blackboardCategory = AddBlackboardCategory(graphData.owner.graphDataStore, copyCategoryAction.newCategoryDataReference, ensureVisible: true); if (blackboardCategory != null) graphView?.AddToSelectionNoUndoRecord(blackboardCategory.blackboardCategoryView); break; diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/EdgeConnectorListener.cs b/Packages/com.unity.shadergraph/Editor/Drawing/EdgeConnectorListener.cs index d3782f66..c8e92e08 100644 --- a/Packages/com.unity.shadergraph/Editor/Drawing/EdgeConnectorListener.cs +++ b/Packages/com.unity.shadergraph/Editor/Drawing/EdgeConnectorListener.cs @@ -20,14 +20,22 @@ namespace UnityEditor.ShaderGraph.Drawing public void OnDropOutsidePort(Edge edge, Vector2 position) { - var draggedPort = (edge.output != null ? edge.output.edgeConnector.edgeDragHelper.draggedPort : null) ?? (edge.input != null ? edge.input.edgeConnector.edgeDragHelper.draggedPort : null); + if (m_SearchWindowProvider is not SearcherProvider searcherProvider) + { + return; + } + + var draggedPort = edge.output?.edgeConnector.edgeDragHelper.draggedPort ?? edge.input?.edgeConnector.edgeDragHelper.draggedPort; + m_SearchWindowProvider.target = null; m_SearchWindowProvider.connectedPort = (ShaderPort)draggedPort; - m_SearchWindowProvider.regenerateEntries = true;//need to be sure the entires are relevant to the edge we are dragging - SearcherWindow.Show(m_editorWindow, (m_SearchWindowProvider as SearcherProvider).LoadSearchWindow(), - item => (m_SearchWindowProvider as SearcherProvider).OnSearcherSelectEntry(item, position), + m_SearchWindowProvider.regenerateEntries = true; //need to be sure the entires are relevant to the edge we are dragging + + SearcherWindow.Show(m_editorWindow, + searcherProvider.LoadSearchWindow(), + item => item != null && searcherProvider.OnSearcherSelectEntry(item, position), position, null); - m_SearchWindowProvider.regenerateEntries = true;//entries no longer necessarily relevant, need to regenerate + m_SearchWindowProvider.regenerateEntries = true; //entries no longer necessarily relevant, need to regenerate } public void OnDrop(GraphView graphView, Edge edge) diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/Inspector/InspectorView.cs b/Packages/com.unity.shadergraph/Editor/Drawing/Inspector/InspectorView.cs index a4c30239..b87dd7ca 100644 --- a/Packages/com.unity.shadergraph/Editor/Drawing/Inspector/InspectorView.cs +++ b/Packages/com.unity.shadergraph/Editor/Drawing/Inspector/InspectorView.cs @@ -106,13 +106,11 @@ namespace UnityEditor.ShaderGraph.Drawing.Inspector void GraphSettingsTabClicked(TabButton button) { m_GraphSettingsTabFocused = true; - m_ScrollView.mode = ScrollViewMode.Vertical; } void NodeSettingsTabClicked(TabButton button) { m_GraphSettingsTabFocused = false; - m_ScrollView.mode = ScrollViewMode.VerticalAndHorizontal; } public void InitializeGraphSettings() @@ -194,15 +192,6 @@ namespace UnityEditor.ShaderGraph.Drawing.Inspector public void RefreshInspectables() { - // Set callbacks to newly created Inspectables - VisualElement temp = new VisualElement(); - var inspectables = new List(); - FindChildrenRecursive(ParentView, inspectables); - foreach (IInspectable inspectable in inspectables) - { - DrawInspectable(temp, inspectable, null); - } - // And redraw the inspector doesInspectorNeedUpdate = true; Update(); diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/Inspector/MasterPreviewView.cs b/Packages/com.unity.shadergraph/Editor/Drawing/Inspector/MasterPreviewView.cs index 87ad9394..6780a27e 100644 --- a/Packages/com.unity.shadergraph/Editor/Drawing/Inspector/MasterPreviewView.cs +++ b/Packages/com.unity.shadergraph/Editor/Drawing/Inspector/MasterPreviewView.cs @@ -1,22 +1,19 @@ using System; using System.Collections.Generic; -using System.Diagnostics.Eventing.Reader; using System.Linq; using System.Reflection; using UnityEngine; using UnityEditor.Graphing; using UnityEditor.Graphing.Util; -using UnityEditor.ShaderGraph.Internal; +using UnityEditor.ShaderGraph.Drawing.Interfaces; using Object = UnityEngine.Object; using UnityEditor.UIElements; using UnityEngine.UIElements; -using UnityEngine.UIElements.StyleSheets; -using UnityEditor.SearchService; namespace UnityEditor.ShaderGraph.Drawing.Inspector { - class MasterPreviewView : VisualElement + class MasterPreviewView : VisualElement, ISGResizable { PreviewManager m_PreviewManager; GraphData m_Graph; @@ -34,14 +31,7 @@ namespace UnityEditor.ShaderGraph.Drawing.Inspector Mesh m_PreviousMesh; - bool m_RecalculateLayout; - - ResizeBorderFrame m_PreviewResizeBorderFrame; - - public ResizeBorderFrame previewResizeBorderFrame - { - get { return m_PreviewResizeBorderFrame; } - } + ResizableElement m_ResizableElement; VisualElement m_Preview; Label m_Title; @@ -52,16 +42,16 @@ namespace UnityEditor.ShaderGraph.Drawing.Inspector } List m_DoNotShowPrimitives = new List(new string[] { PrimitiveType.Plane.ToString() }); - static Type s_ContextualMenuManipulator = AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => x.GetTypesOrNothing()).FirstOrDefault(t => t.FullName == "UnityEngine.UIElements.ContextualMenuManipulator"); static Type s_ObjectSelector = AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => x.GetTypesOrNothing()).FirstOrDefault(t => t.FullName == "UnityEditor.ObjectSelector"); - public string assetName { get { return m_Title.text; } set { m_Title.text = value; } } + public Action onResized; + public MasterPreviewView(PreviewManager previewManager, GraphData graph) { style.overflow = Overflow.Hidden; @@ -76,6 +66,9 @@ namespace UnityEditor.ShaderGraph.Drawing.Inspector m_PreviewRenderHandle.onPreviewChanged += OnPreviewChanged; } + var mainContainer = new VisualElement(); + mainContainer.AddToClassList("mainContainer"); + var topContainer = new VisualElement() { name = "top" }; { m_Title = new Label() { name = "title" }; @@ -83,7 +76,7 @@ namespace UnityEditor.ShaderGraph.Drawing.Inspector topContainer.Add(m_Title); } - Add(topContainer); + mainContainer.Add(topContainer); m_Preview = new VisualElement { name = "middle" }; { @@ -92,14 +85,14 @@ namespace UnityEditor.ShaderGraph.Drawing.Inspector preview.Add(m_PreviewTextureView); preview.AddManipulator(new Scrollable(OnScroll)); } - Add(preview); + mainContainer.Add(preview); + + Add(mainContainer); - m_PreviewResizeBorderFrame = new ResizeBorderFrame(this, this) { name = "resizeBorderFrame" }; - m_PreviewResizeBorderFrame.maintainAspectRatio = true; - Add(m_PreviewResizeBorderFrame); + m_ResizableElement = new ResizableElement(); + Add(m_ResizableElement); - m_RecalculateLayout = false; - this.RegisterCallback(OnGeometryChanged); + RegisterCallback(OnGeometryChanged); } Image CreatePreview(Texture texture) @@ -111,7 +104,7 @@ namespace UnityEditor.ShaderGraph.Drawing.Inspector var image = new Image { name = "preview", image = texture, scaleMode = ScaleMode.ScaleAndCrop }; image.AddManipulator(new Draggable(OnMouseDragPreviewMesh, true)); - image.AddManipulator((IManipulator)Activator.CreateInstance(s_ContextualMenuManipulator, (Action)BuildContextualMenu)); + image.AddManipulator(new MasterPreviewManipulator((Action)BuildContextualMenu)); return image; } @@ -192,15 +185,6 @@ namespace UnityEditor.ShaderGraph.Drawing.Inspector void OnGeometryChanged(GeometryChangedEvent evt) { - if (m_RecalculateLayout) - { - WindowDockingLayout dockingLayout = new WindowDockingLayout(); - dockingLayout.CalculateDockingCornerAndOffset(layout, parent.layout); - dockingLayout.ClampToParentWindow(); - dockingLayout.ApplyPosition(this); - m_RecalculateLayout = false; - } - var currentWidth = m_PreviewRenderHandle?.texture != null ? m_PreviewRenderHandle.texture.width : -1; var currentHeight = m_PreviewRenderHandle?.texture != null ? m_PreviewRenderHandle.texture.height : -1; @@ -211,7 +195,10 @@ namespace UnityEditor.ShaderGraph.Drawing.Inspector return; m_PreviewTextureView.style.width = evt.newRect.width; - m_PreviewTextureView.style.height = evt.newRect.height - 40.0f; + + const float offsetFromHeader = 40.0f; + const float offsetFromMargin = 2 * 6.0f; + m_PreviewTextureView.style.height = evt.newRect.height - (offsetFromHeader + offsetFromMargin); m_PreviewManager.ResizeMasterPreview(new Vector2(evt.newRect.width, evt.newRect.width)); } @@ -236,5 +223,17 @@ namespace UnityEditor.ShaderGraph.Drawing.Inspector m_PreviewManager.UpdateMasterPreview(ModificationScope.Node); } + + public void OnStartResize() + { + } + + public void OnResized() + { + onResized?.Invoke(); + } + + public bool CanResizePastParentBounds() => false; + public bool KeepSquareAspect() => true; } } diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/Inspector/PropertyDrawers/AbstractMaterialNodePropertyDrawer.cs b/Packages/com.unity.shadergraph/Editor/Drawing/Inspector/PropertyDrawers/AbstractMaterialNodePropertyDrawer.cs index 445fb273..de0cc7a4 100644 --- a/Packages/com.unity.shadergraph/Editor/Drawing/Inspector/PropertyDrawers/AbstractMaterialNodePropertyDrawer.cs +++ b/Packages/com.unity.shadergraph/Editor/Drawing/Inspector/PropertyDrawers/AbstractMaterialNodePropertyDrawer.cs @@ -66,7 +66,7 @@ namespace UnityEditor.ShaderGraph.Drawing.Inspector.PropertyDrawers }; } - var help = HelpBoxRow.TryGetDeprecatedHelpBoxRow($"{node.name} Node", + var help = HelpBoxRow.CreateUpgradePrompt($"{node.name} Node", () => { // upgrade m_setNodesAsDirtyCallback?.Invoke(); diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/Inspector/PropertyDrawers/GraphDataPropertyDrawer.cs b/Packages/com.unity.shadergraph/Editor/Drawing/Inspector/PropertyDrawers/GraphDataPropertyDrawer.cs index 73fb40d9..dcf3d7d9 100644 --- a/Packages/com.unity.shadergraph/Editor/Drawing/Inspector/PropertyDrawers/GraphDataPropertyDrawer.cs +++ b/Packages/com.unity.shadergraph/Editor/Drawing/Inspector/PropertyDrawers/GraphDataPropertyDrawer.cs @@ -182,16 +182,10 @@ namespace UnityEditor.ShaderGraph.Drawing.Inspector.PropertyDrawers // Inform the user that VFXTarget is deprecated, if they are using one. if (graphData.m_ActiveTargets.Any(t => t.value is VFXTarget)) //Use Old VFXTarget { - var vfxWarning = new HelpBoxRow(MessageType.Info); - - var vfxWarningLabel = new Label("The Visual Effect target is deprecated.\n" + + var vfxWarning = new HelpBoxRow("The Visual Effect target is deprecated.\n" + "Use the SRP target(s) instead, and enable 'Support VFX Graph' in the Graph Inspector.\n" + - "Then, you can remove the Visual Effect Target."); - - vfxWarningLabel.style.color = new StyleColor(Color.white); - vfxWarningLabel.style.whiteSpace = WhiteSpace.Normal; + "Then, you can remove the Visual Effect Target.", MessageType.Info); - vfxWarning.Add(vfxWarningLabel); element.Add(vfxWarning); } #endif diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/Inspector/PropertyDrawers/SampleVirtualTextureNodePropertyDrawer.cs b/Packages/com.unity.shadergraph/Editor/Drawing/Inspector/PropertyDrawers/SampleVirtualTextureNodePropertyDrawer.cs index 8914625c..9cc61739 100644 --- a/Packages/com.unity.shadergraph/Editor/Drawing/Inspector/PropertyDrawers/SampleVirtualTextureNodePropertyDrawer.cs +++ b/Packages/com.unity.shadergraph/Editor/Drawing/Inspector/PropertyDrawers/SampleVirtualTextureNodePropertyDrawer.cs @@ -101,7 +101,6 @@ namespace UnityEditor.ShaderGraph.Drawing.Inspector.PropertyDrawers // } // display warning if the current render pipeline doesn't support virtual texturing - HelpBoxRow help = new HelpBoxRow(MessageType.Warning); string labelText; IVirtualTexturingEnabledRenderPipeline vtRp = GraphicsSettings.currentRenderPipeline as IVirtualTexturingEnabledRenderPipeline; @@ -120,13 +119,9 @@ namespace UnityEditor.ShaderGraph.Drawing.Inspector.PropertyDrawers if (!string.IsNullOrEmpty(labelText)) { - var label = new Label(labelText) - { - name = "message-warn" - }; - label.style.whiteSpace = WhiteSpace.Normal; - propertySheet.Add(help, (row) => row.Add(label)); + propertySheet.Add(new HelpBoxRow(labelText, MessageType.Warning)); } + propertyVisualElement = propertySheet; return propertySheet; } diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/Inspector/PropertyDrawers/ShaderInputPropertyDrawer.cs b/Packages/com.unity.shadergraph/Editor/Drawing/Inspector/PropertyDrawers/ShaderInputPropertyDrawer.cs index 75d21a6f..cecad87f 100644 --- a/Packages/com.unity.shadergraph/Editor/Drawing/Inspector/PropertyDrawers/ShaderInputPropertyDrawer.cs +++ b/Packages/com.unity.shadergraph/Editor/Drawing/Inspector/PropertyDrawers/ShaderInputPropertyDrawer.cs @@ -182,9 +182,15 @@ namespace UnityEditor.ShaderGraph.Drawing.Inspector.PropertyDrawers propertySheet.Add(toggleDataPropertyDrawer.CreateGUI( evt => { + if (shaderInput is AbstractShaderProperty property && + (!property.overrideHLSLDeclaration || property.hlslDeclarationOverride == HLSLDeclaration.DoNotDeclare)) + { + property.hlslDeclarationOverride = property.GetDefaultHLSLDeclaration(); + property.overrideHLSLDeclaration = true; + } this._preChangeValueCallback("Change Exposed Toggle"); this._exposedFieldChangedCallback(evt.isOn); - this._postChangeValueCallback(false, ModificationScope.Graph); + this._postChangeValueCallback(true, ModificationScope.Graph); }, new ToggleData(shaderInput.isExposed), shaderInput is ShaderKeyword ? "Generate Material Property" : "Show In Inspector", @@ -404,7 +410,7 @@ namespace UnityEditor.ShaderGraph.Drawing.Inspector.PropertyDrawers }; } - var help = HelpBoxRow.TryGetDeprecatedHelpBoxRow($"{typeString} Property", + var help = HelpBoxRow.CreateUpgradePrompt($"{typeString} Property", () => property.ChangeVersion(property.latestVersion), dismissAction); if (help != null) @@ -424,9 +430,8 @@ namespace UnityEditor.ShaderGraph.Drawing.Inspector.PropertyDrawers case IShaderPropertyDrawer propDrawer: propDrawer.HandlePropertyField(propertySheet, _preChangeValueCallback, _postChangeValueCallback); break; - case UnityEditor.ShaderGraph.Serialization.MultiJsonInternal.UnknownShaderPropertyType unknownProperty: - var helpBox = new HelpBoxRow(MessageType.Warning); - helpBox.Add(new Label("Cannot find the code for this Property, a package may be missing.")); + case UnityEditor.ShaderGraph.Serialization.MultiJsonInternal.UnknownShaderPropertyType: + var helpBox = new HelpBoxRow("Cannot find the code for this Property, a package may be missing.", MessageType.Warning); propertySheet.Add(helpBox); break; case Vector1ShaderProperty vector1Property: @@ -529,8 +534,11 @@ namespace UnityEditor.ShaderGraph.Drawing.Inspector.PropertyDrawers property.hlslDeclarationOverride = evt.newValue; property.overrideHLSLDeclaration = true; UpdateEnableState(); - this._exposedFieldChangedCallback(evt.newValue != HLSLDeclaration.Global); - property.generatePropertyBlock = evt.newValue != HLSLDeclaration.Global; + if ((evt.newValue == HLSLDeclaration.Global) ^ (evt.previousValue == HLSLDeclaration.Global)) + { + this._exposedFieldChangedCallback(evt.newValue != HLSLDeclaration.Global); + property.generatePropertyBlock = evt.newValue != HLSLDeclaration.Global; + } this._postChangeValueCallback(true, ModificationScope.Graph); }); @@ -562,7 +570,7 @@ namespace UnityEditor.ShaderGraph.Drawing.Inspector.PropertyDrawers void HandleVector1ShaderProperty(PropertySheet propertySheet, Vector1ShaderProperty vector1ShaderProperty) { - var floatType = isCurrentPropertyGlobal ? FloatType.Default : vector1ShaderProperty.floatType; + var floatType = (isSubGraph || isCurrentPropertyGlobal) ? FloatType.Default : vector1ShaderProperty.floatType; // Handle vector 1 mode parameters switch (floatType) { @@ -836,6 +844,18 @@ namespace UnityEditor.ShaderGraph.Drawing.Inspector.PropertyDrawers new ToggleData(texture2DProperty.useTilingAndOffset, true), "Use Tiling and Offset", out var tilingAndOffsetToggle)); + propertySheet.Add(togglePropertyDrawer.CreateGUI( + newValue => + { + this._preChangeValueCallback("Change Use TexelSize"); + if (texture2DProperty.useTexelSize == newValue.isOn) + return; + texture2DProperty.useTexelSize = newValue.isOn; + this._postChangeValueCallback(); + }, + new ToggleData(texture2DProperty.useTexelSize, true), + "Use TexelSize", + out var texelSizeToggle)); } } @@ -1229,6 +1249,21 @@ namespace UnityEditor.ShaderGraph.Drawing.Inspector.PropertyDrawers "Wrap", TextureSamplerState.WrapMode.Repeat, out var wrapVisualElement)); + + propertySheet.Add(enumPropertyDrawer.CreateGUI( + newValue => + { + this._preChangeValueCallback("Change property value"); + TextureSamplerState state = samplerStateShaderProperty.value; + state.anisotropic = (TextureSamplerState.Anisotropic)newValue; + samplerStateShaderProperty.value = state; + this._postChangeValueCallback(false, ModificationScope.Graph); + this.inspectorUpdateDelegate(); + }, + samplerStateShaderProperty.value.anisotropic, + "Aniso", + TextureSamplerState.Anisotropic.None, + out var anisoVisualElement)); } void HandleGradientPropertyField(PropertySheet propertySheet, GradientShaderProperty gradientShaderProperty) @@ -1278,12 +1313,7 @@ namespace UnityEditor.ShaderGraph.Drawing.Inspector.PropertyDrawers if (keyword.keywordDefinition == KeywordDefinition.ShaderFeature && isSubGraph) { - var help = new HelpBoxRow(MessageType.Info); - var warning = new TextElement(); - warning.tabIndex = 1; - warning.style.alignSelf = Align.Center; - warning.text = "Shader Feature Keywords in SubGraphs do not generate variant permutations."; - help.Add(warning); + var help = new HelpBoxRow("Shader Feature Keywords in SubGraphs do not generate variant permutations.", MessageType.Info); propertySheet.Add(help); } @@ -1440,6 +1470,8 @@ namespace UnityEditor.ShaderGraph.Drawing.Inspector.PropertyDrawers if (EditorGUI.EndChangeCheck()) { + this._preChangeValueCallback("Edit Enum Keyword Entry"); + displayName = GetSanitizedDisplayName(displayName); referenceName = GetSanitizedReferenceName(displayName.ToUpper()); var duplicateIndex = FindDuplicateKeywordReferenceNameIndex(entry.id, referenceName); @@ -1560,6 +1592,7 @@ namespace UnityEditor.ShaderGraph.Drawing.Inspector.PropertyDrawers void KeywordReorderEntries(ReorderableList list) { + this._preChangeValueCallback("Reorder Keyword Entry"); this._postChangeValueCallback(true); } @@ -1619,7 +1652,6 @@ namespace UnityEditor.ShaderGraph.Drawing.Inspector.PropertyDrawers return; BuildDropdownField(propertySheet, dropdown); - BuildExposedField(propertySheet); } void BuildDropdownField(PropertySheet propertySheet, ShaderDropdown dropdown) diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/Interfaces/IResizable.cs b/Packages/com.unity.shadergraph/Editor/Drawing/Interfaces/IResizable.cs index e0941391..6e712ce7 100644 --- a/Packages/com.unity.shadergraph/Editor/Drawing/Interfaces/IResizable.cs +++ b/Packages/com.unity.shadergraph/Editor/Drawing/Interfaces/IResizable.cs @@ -6,5 +6,8 @@ namespace UnityEditor.ShaderGraph.Drawing.Interfaces { // Depending on the return value, the ElementResizer either allows resizing past parent view edge (like in case of StickyNote) or clamps the size at the edges of parent view (like for GraphSubWindows) bool CanResizePastParentBounds(); + + // If true, element will be kept square when resizing. Otherwise, both axes can be resized freely. + bool KeepSquareAspect() => false; } } diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/Manipulators/ElementResizer.cs b/Packages/com.unity.shadergraph/Editor/Drawing/Manipulators/ElementResizer.cs index 5c99ce35..4d5fda89 100644 --- a/Packages/com.unity.shadergraph/Editor/Drawing/Manipulators/ElementResizer.cs +++ b/Packages/com.unity.shadergraph/Editor/Drawing/Manipulators/ElementResizer.cs @@ -1,6 +1,5 @@ using System; using UnityEditor.ShaderGraph.Drawing.Interfaces; -using UnityEditor.ShaderGraph.Drawing.Views; using UnityEngine; using UnityEngine.UIElements; @@ -9,6 +8,7 @@ namespace UnityEditor.ShaderGraph.Drawing class ElementResizer : Manipulator { bool m_IsEnabled = true; + public bool isEnabled { get => m_IsEnabled; @@ -84,49 +84,158 @@ namespace UnityEditor.ShaderGraph.Drawing } } + void ApplyLayoutToTargetAsStyle(Rect rect) + { + var resizedTarget = resizedElement.parent; + resizedTarget.style.left = rect.x; + resizedTarget.style.top = rect.y; + resizedTarget.style.width = rect.width; + resizedTarget.style.height = rect.height; + } + + static Rect CropToParent(Rect rect, Rect parent) + { + rect.xMin = Mathf.Max(rect.xMin, parent.xMin); + rect.yMin = Mathf.Max(rect.yMin, parent.yMin); + rect.xMax = Mathf.Min(rect.xMax, parent.xMax); + rect.yMax = Mathf.Min(rect.yMax, parent.yMax); + return rect; + } + + static float GetSquareSize(Rect rect, ResizableElement.Resizer resizeDirection) + { + var horizontal = (resizeDirection & (ResizableElement.Resizer.Left | ResizableElement.Resizer.Right)) != 0; + var vertical = (resizeDirection & (ResizableElement.Resizer.Top | ResizableElement.Resizer.Bottom)) != 0; + + if (horizontal && vertical) + { + return Mathf.Min(rect.width, rect.height); + } + + return horizontal ? rect.width : rect.height; + } + + Rect ApplySquareAspect(Rect element, ResizableElement.Resizer resizeDirection, Rect? keepInParent = null) + { + var newLayout = element; + var size = GetSquareSize(element, resizeDirection); + + size = Mathf.Clamp(size, m_MinSize.x, m_MaxSize.x); + size = Mathf.Clamp(size, m_MinSize.y, m_MaxSize.y); + ResizeNewLayoutAndFixPosition(resizeDirection, size); + + if (keepInParent is { } parentRect) + { + newLayout = CropToParent(newLayout, parentRect); + size = Mathf.Min(newLayout.width, newLayout.height); + ResizeNewLayoutAndFixPosition(resizeDirection, size); + } + + return newLayout; + + void ResizeNewLayoutAndFixPosition(ResizableElement.Resizer grabbedSide, float newSize) + { + newLayout.width = newSize; + newLayout.height = newSize; + + var deltaWidth = element.width - newSize; + var deltaHeight = element.height - newSize; + + // Anchoring rules were written with the main preview in mind, which is in the bottom-right corner + // by default. + switch (grabbedSide) + { + // Anchor to bottom-right. + case ResizableElement.Resizer.Top: + case ResizableElement.Resizer.Top | ResizableElement.Resizer.Left: + case ResizableElement.Resizer.Left: + { + newLayout.x = element.x + deltaWidth; + newLayout.y = element.y + deltaHeight; + break; + } + + // Anchor to bottom-left. + case ResizableElement.Resizer.Top | ResizableElement.Resizer.Right: + { + newLayout.y = element.y + deltaHeight; + break; + } + + // Anchor to top-left. + case ResizableElement.Resizer.Right: + case ResizableElement.Resizer.Bottom | ResizableElement.Resizer.Right: + case ResizableElement.Resizer.Bottom: + { + // Element is positioned by its top-left, so no adjustment is needed. + break; + } + + // Anchor to top-right. + case ResizableElement.Resizer.Bottom | ResizableElement.Resizer.Left: + { + newLayout.x = element.x + deltaWidth; + break; + } + + case ResizableElement.Resizer.None: + default: + break; + } + } + } + void OnMouseMove(MouseMoveEvent e) { if (!isEnabled) return; - VisualElement resizedTarget = resizedElement.parent; - VisualElement resizedBase = resizedTarget.parent; + var resizedTarget = resizedElement.parent; + var resizedBase = resizedTarget.parent; // Top left position of the parent visual element var parentRootPosition = resizedBase.worldBound; + // Top left of the target visual element for resizing var targetRootPosition = resizedTarget.worldBound; - var canResizePastParentBounds = ((ISGResizable)resizedTarget).CanResizePastParentBounds(); - Vector2 mousePos = resizedBase.WorldToLocal(e.mousePosition); + var sgResizable = resizedTarget as ISGResizable; + var canResizePastParentBounds = sgResizable?.CanResizePastParentBounds() ?? false; + var keepSquareAspect = sgResizable?.KeepSquareAspect() ?? false; + + var mousePos = resizedBase.WorldToLocal(e.mousePosition); if (!m_DragStarted) { - if (resizedTarget is ISGResizable resizable) - resizable.OnStartResize(); + sgResizable?.OnStartResize(); m_DragStarted = true; } + var newLayout = new Rect(m_StartPosition, m_StartSize); + if ((direction & ResizableElement.Resizer.Right) != 0) { - var newWidth = m_StartSize.x + mousePos.x - m_StartMouse.x; + newLayout.width = m_StartSize.x + mousePos.x - m_StartMouse.x; var parentRightBoundary = parentRootPosition.x + resizedBase.layout.width; + // Also ensure resizing does not happen past edge of parent views boundaries if the target does not allow it if (!canResizePastParentBounds) { - if ((targetRootPosition.x + newWidth) > parentRightBoundary) + if ((targetRootPosition.x + newLayout.width) > parentRightBoundary) { var targetToRightBoundaryDelta = parentRightBoundary - targetRootPosition.x; - newWidth = targetToRightBoundaryDelta; + newLayout.width = targetToRightBoundaryDelta; } + var newLayoutLeft = targetRootPosition.x - parentRootPosition.x; + // When resizing to right, make sure to calculate and set the target elements Style.left before resizing to ensure correct resizing behavior // If Style.left is NaNpx it results in scaling towards the left // This is due to how the WindowDockingLayout code affects GraphSubWindows - resizedTarget.style.left = newLayoutLeft; + newLayout.x = newLayoutLeft; } - resizedTarget.style.width = Mathf.Clamp(newWidth, m_MinSize.x, m_MaxSize.x); + newLayout.width = Mathf.Clamp(newLayout.width, m_MinSize.x, m_MaxSize.x); } else if ((direction & ResizableElement.Resizer.Left) != 0) { @@ -141,7 +250,7 @@ namespace UnityEditor.ShaderGraph.Drawing delta = -m_MaxSize.x + m_StartSize.x; } - var newWidth = -delta + m_StartSize.x; + newLayout.width = -delta + m_StartSize.x; var targetToLeftBoundaryDelta = delta + m_StartPosition.x; if (!canResizePastParentBounds) @@ -151,38 +260,36 @@ namespace UnityEditor.ShaderGraph.Drawing // Clamps width to max out at left edge of parent window if (Mathf.Approximately(targetToLeftBoundaryDelta, 2.5f)) - newWidth = (m_StartPosition.x + m_StartSize.x); + newLayout.width = (m_StartPosition.x + m_StartSize.x); - newWidth = Mathf.Clamp(newWidth, m_MinSize.x, m_MaxSize.x); + newLayout.width = Mathf.Clamp(newLayout.width, m_MinSize.x, m_MaxSize.x); } - resizedTarget.style.left = targetToLeftBoundaryDelta; - resizedTarget.style.width = newWidth; + newLayout.x = targetToLeftBoundaryDelta; } if ((direction & ResizableElement.Resizer.Bottom) != 0) { var delta = mousePos.y - m_StartMouse.y; - var newHeight = m_StartSize.y + delta; + newLayout.height = m_StartSize.y + delta; var parentBottomBoundary = parentRootPosition.y + resizedBase.layout.height; if (!canResizePastParentBounds) { - if ((targetRootPosition.y + newHeight) > parentBottomBoundary) + if ((targetRootPosition.y + newLayout.height) > parentBottomBoundary) { var targetToBottomBoundaryDelta = parentBottomBoundary - targetRootPosition.y; - newHeight = targetToBottomBoundaryDelta; + newLayout.height = targetToBottomBoundaryDelta; } + var targetToTopBoundaryDelta = targetRootPosition.y - parentRootPosition.y; + // When resizing to bottom, make sure to calculate and set the target elements Style.top before resizing to ensure correct resizing behavior // If Style.top is NaNpx it results in scaling towards the bottom // This is due to how the WindowDockingLayout code affects GraphSubWindows - resizedTarget.style.top = targetToTopBoundaryDelta; - - newHeight = Mathf.Clamp(newHeight, m_MinSize.y, m_MaxSize.y); + newLayout.y = targetToTopBoundaryDelta; + newLayout.height = Mathf.Clamp(newLayout.height, m_MinSize.y, m_MaxSize.y); } - - resizedTarget.style.height = newHeight; } else if ((direction & ResizableElement.Resizer.Top) != 0) { @@ -197,7 +304,7 @@ namespace UnityEditor.ShaderGraph.Drawing delta = -m_MaxSize.y + m_StartSize.y; } - var newHeight = -delta + m_StartSize.y; + newLayout.height = -delta + m_StartSize.y; var targetToTopBoundaryDelta = m_StartPosition.y + delta; if (!canResizePastParentBounds) { @@ -206,14 +313,24 @@ namespace UnityEditor.ShaderGraph.Drawing // Clamps height to max out at top edge of parent window if (Mathf.Approximately(targetToTopBoundaryDelta, 2.5f)) - newHeight = (m_StartPosition.y + m_StartSize.y); + newLayout.height = (m_StartPosition.y + m_StartSize.y); - newHeight = Mathf.Clamp(newHeight, m_MinSize.y, m_MaxSize.y); + newLayout.height = Mathf.Clamp(newLayout.height, m_MinSize.y, m_MaxSize.y); } - resizedTarget.style.top = targetToTopBoundaryDelta; - resizedTarget.style.height = newHeight; + newLayout.y = targetToTopBoundaryDelta; } + + if (keepSquareAspect) + { + newLayout = ApplySquareAspect( + newLayout, + direction, + canResizePastParentBounds ? null : new Rect(0, 0, parentRootPosition.width, parentRootPosition.height) + ); + } + + ApplyLayoutToTargetAsStyle(newLayout); e.StopPropagation(); } @@ -230,6 +347,7 @@ namespace UnityEditor.ShaderGraph.Drawing if (resizedTarget is ISGResizable resizable) resizable.OnResized(); } + target.UnregisterCallback(OnMouseMove); target.ReleaseMouse(); e.StopPropagation(); diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/Manipulators/MasterPreviewManipulator.cs b/Packages/com.unity.shadergraph/Editor/Drawing/Manipulators/MasterPreviewManipulator.cs new file mode 100644 index 00000000..f1bbcfc1 --- /dev/null +++ b/Packages/com.unity.shadergraph/Editor/Drawing/Manipulators/MasterPreviewManipulator.cs @@ -0,0 +1,41 @@ +using System; +using UnityEngine; + +using UnityEngine.UIElements; + +namespace UnityEditor.ShaderGraph.Drawing +{ + internal sealed class MasterPreviewManipulator : ContextualMenuManipulator + { + internal MasterPreviewManipulator(Action menuBuilder) : base(menuBuilder) + { + + } + + protected override void RegisterCallbacksOnTarget() + { + base.RegisterCallbacksOnTarget(); + if (IsOSXContextualMenuPlatform()) + { + target.RegisterCallback(MasterPointerDownEventOSX); + } + } + + protected override void UnregisterCallbacksFromTarget() + { + base.UnregisterCallbacksFromTarget(); + if (IsOSXContextualMenuPlatform()) + { + target.UnregisterCallback(MasterPointerDownEventOSX); + } + } + + void MasterPointerDownEventOSX(IPointerEvent evt) + { + if (CanStartManipulation(evt)) + { + (evt as EventBase)?.StopImmediatePropagation(); + } + } + } +} diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/Manipulators/MasterPreviewManipulator.cs.meta b/Packages/com.unity.shadergraph/Editor/Drawing/Manipulators/MasterPreviewManipulator.cs.meta new file mode 100644 index 00000000..7be2c6ee --- /dev/null +++ b/Packages/com.unity.shadergraph/Editor/Drawing/Manipulators/MasterPreviewManipulator.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: f3738117378a2c645ae46e837d3cffe8 \ No newline at end of file diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/MaterialEditor/ShaderGraphPropertyDrawers.cs b/Packages/com.unity.shadergraph/Editor/Drawing/MaterialEditor/ShaderGraphPropertyDrawers.cs index c6833330..31e048ba 100644 --- a/Packages/com.unity.shadergraph/Editor/Drawing/MaterialEditor/ShaderGraphPropertyDrawers.cs +++ b/Packages/com.unity.shadergraph/Editor/Drawing/MaterialEditor/ShaderGraphPropertyDrawers.cs @@ -39,7 +39,7 @@ namespace UnityEditor.ShaderGraph.Drawing { foreach (var property in properties) { - if ((property.flags & (MaterialProperty.PropFlags.HideInInspector | MaterialProperty.PropFlags.PerRendererData)) != 0) + if ((property.propertyFlags & (ShaderPropertyFlags.HideInInspector | ShaderPropertyFlags.PerRendererData)) != 0) continue; float h = materialEditor.GetPropertyHeight(property, property.displayName); diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs b/Packages/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs index 1cb0888c..9e60d1c4 100644 --- a/Packages/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs +++ b/Packages/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs @@ -183,6 +183,7 @@ namespace UnityEditor.ShaderGraph.Drawing return (saved || okToClose); } + bool firstUpdate = true; void Update() { if (m_HasError) @@ -381,13 +382,14 @@ namespace UnityEditor.ShaderGraph.Drawing graphEditorView.inspectorView.RefreshInspectables(); } - if (updateTitle) + if (updateTitle && !firstUpdate) UpdateTitle(); + firstUpdate = false; } catch (Exception e) { m_HasError = true; - m_GraphEditorView = null; + graphEditorView = null; graphObject = null; Debug.LogException(e); throw; @@ -416,9 +418,17 @@ namespace UnityEditor.ShaderGraph.Drawing } } + void OnPlayMode(PlayModeStateChange change) + { + if (change == PlayModeStateChange.ExitingEditMode) + graphEditorView = null; + } + void OnEnable() { this.SetAntiAliasing(4); + + EditorApplication.playModeStateChanged += OnPlayMode; } void OnDisable() @@ -431,6 +441,8 @@ namespace UnityEditor.ShaderGraph.Drawing Resources.UnloadUnusedAssets(); WereWindowResourcesDisposed = true; + + EditorApplication.playModeStateChanged -= OnPlayMode; } // returns true only when the file on disk doesn't match the graph we last loaded or saved to disk (i.e. someone else changed it) @@ -807,6 +819,11 @@ namespace UnityEditor.ShaderGraph.Drawing subGraph.AddNode(subGraphOutputNode); subGraph.outputNode = subGraphOutputNode; + var inputSlots = new List(); + subGraphOutputNode.GetInputSlots(inputSlots); + if (inputSlots.Count == 0) + subGraphOutputNode.AddSlot(ConcreteSlotValueType.Vector4); + // Always copy deserialized keyword inputs foreach (ShaderKeyword keyword in deserialized.metaKeywords) { @@ -1191,7 +1208,7 @@ namespace UnityEditor.ShaderGraph.Drawing { Debug.LogException(e); m_HasError = true; - m_GraphEditorView = null; + graphEditorView = null; graphObject = null; throw; } @@ -1271,7 +1288,7 @@ namespace UnityEditor.ShaderGraph.Drawing catch (Exception) { m_HasError = true; - m_GraphEditorView = null; + graphEditorView = null; graphObject = null; throw; } diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/PreviewManager.cs b/Packages/com.unity.shadergraph/Editor/Drawing/PreviewManager.cs index ce8006a7..98f2b0d9 100644 --- a/Packages/com.unity.shadergraph/Editor/Drawing/PreviewManager.cs +++ b/Packages/com.unity.shadergraph/Editor/Drawing/PreviewManager.cs @@ -323,6 +323,7 @@ namespace UnityEditor.ShaderGraph.Drawing } } + Dictionary propertyTypeCache; public void HandleGraphChanges() { foreach (var node in m_Graph.addedNodes) @@ -381,6 +382,23 @@ namespace UnityEditor.ShaderGraph.Drawing } } + bool mpbNeedsRebuild = false; + if (propertyTypeCache == null) + propertyTypeCache = new(); + foreach (var property in m_Graph.properties) + { + // if the reference name of a property type becomes associated with a different property type, + // the property sheet will emit an error. This error is sort of a false positive, but to comply + // we need to rebuild the MPB whenever a reference name's corresponding type is different. + mpbNeedsRebuild |= propertyTypeCache.TryGetValue(property.referenceName, out var propType) && propType != property.propertyType; + propertyTypeCache[property.referenceName] = property.propertyType; + } + if (mpbNeedsRebuild) + { + m_NodesPropertyChanged.UnionWith(m_Graph.GetNodes()); + m_SharedPreviewPropertyBlock = new(); + } + // remove the nodes from the state trackers m_NodesShaderChanged.ExceptWith(m_Graph.removedNodes); m_NodesPropertyChanged.ExceptWith(m_Graph.removedNodes); @@ -520,6 +538,7 @@ namespace UnityEditor.ShaderGraph.Drawing private static int k_spriteProps = Shader.PropertyToID("unity_SpriteProps"); private static int k_spriteColor = Shader.PropertyToID("unity_SpriteColor"); private static int k_rendererColor = Shader.PropertyToID("_RendererColor"); + private float previewTime = 0; public void RenderPreviews(EditorWindow editorWindow, bool requestShaders = true) { using (RenderPreviewsMarker.Auto()) @@ -619,11 +638,11 @@ namespace UnityEditor.ShaderGraph.Drawing if (drawPreviewCount <= 0) return; - var time = Time.realtimeSinceStartup; - var timeParameters = new Vector4(time, Mathf.Sin(time), Mathf.Cos(time), 0.0f); + previewTime += Time.fixedDeltaTime; + var timeParameters = new Vector4(previewTime, Mathf.Sin(previewTime), Mathf.Cos(previewTime), 0.0f); m_SharedPreviewPropertyBlock.SetVector("_TimeParameters", timeParameters); - EditorUtility.SetCameraAnimateMaterialsTime(m_SceneResources.camera, time); + EditorUtility.SetCameraAnimateMaterialsTime(m_SceneResources.camera, previewTime); m_SceneResources.light0.enabled = true; m_SceneResources.light0.intensity = 1.0f; diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs b/Packages/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs index c06b6632..2347e7f4 100644 --- a/Packages/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs +++ b/Packages/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs @@ -253,9 +253,9 @@ namespace UnityEditor.ShaderGraph.Drawing { Application.OpenURL("https://unity.com/features/shader-graph"); }); - menu.AddItem(new GUIContent("Shader Graph Forums"), false, () => + menu.AddItem(new GUIContent("Shader Graph Discussions"), false, () => { - Application.OpenURL("https://forum.unity.com/forums/shader-graph.346/"); + Application.OpenURL("https://discussions.unity.com/tag/Shader-Graph"); }); menu.AddItem(new GUIContent("Shader Graph Roadmap"), false, () => { @@ -425,16 +425,20 @@ namespace UnityEditor.ShaderGraph.Drawing void NodeCreationRequest(NodeCreationContext c) { - if (EditorWindow.focusedWindow == m_EditorWindow) //only display the search window when current graph view is focused + if (EditorWindow.focusedWindow != m_EditorWindow || //only display the search window when current graph view is focused + m_SearchWindowProvider is not SearcherProvider searcherProvider) { - m_SearchWindowProvider.connectedPort = null; - m_SearchWindowProvider.target = c.target ?? m_HoveredContextView; - var displayPosition = graphView.cachedMousePosition; - - SearcherWindow.Show(m_EditorWindow, (m_SearchWindowProvider as SearcherProvider).LoadSearchWindow(), - item => (m_SearchWindowProvider as SearcherProvider).OnSearcherSelectEntry(item, displayPosition), - displayPosition, null, new SearcherWindow.Alignment(SearcherWindow.Alignment.Vertical.Center, SearcherWindow.Alignment.Horizontal.Left)); + return; } + + m_SearchWindowProvider.connectedPort = null; + m_SearchWindowProvider.target = c.target ?? m_HoveredContextView; + var displayPosition = graphView.cachedMousePosition; + + SearcherWindow.Show(m_EditorWindow, + searcherProvider.LoadSearchWindow(), + item => item != null && searcherProvider.OnSearcherSelectEntry(item, displayPosition), + displayPosition, null, new SearcherWindow.Alignment(SearcherWindow.Alignment.Vertical.Center, SearcherWindow.Alignment.Horizontal.Left)); } // Master Preview, Inspector and Blackboard all need to keep their layouts when hidden in order to restore user preferences. @@ -483,7 +487,7 @@ namespace UnityEditor.ShaderGraph.Drawing m_GraphView.Add(m_MasterPreviewView); masterPreviewViewDraggable.OnDragFinished += UpdateSerializedWindowLayout; - m_MasterPreviewView.previewResizeBorderFrame.OnResizeFinished += UpdateSerializedWindowLayout; + m_MasterPreviewView.onResized += UpdateSerializedWindowLayout; } void CreateInspector() @@ -1419,13 +1423,14 @@ namespace UnityEditor.ShaderGraph.Drawing } } } + var edges = edgesToUpdate.ToArray(); + edgesToUpdate.Dispose(); schedule.Execute(() => { - foreach (Edge e in edgesToUpdate) + foreach (Edge e in edges) { e.UpdateEdgeControl(); } - edgesToUpdate.Dispose(); }).StartingIn(0); } diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/Views/GraphSubWindow.cs b/Packages/com.unity.shadergraph/Editor/Drawing/Views/GraphSubWindow.cs index 06b2fa9d..c2e99305 100644 --- a/Packages/com.unity.shadergraph/Editor/Drawing/Views/GraphSubWindow.cs +++ b/Packages/com.unity.shadergraph/Editor/Drawing/Views/GraphSubWindow.cs @@ -282,6 +282,9 @@ namespace UnityEditor.ShaderGraph.Drawing.Views m_Dragger = new Dragger { clampToParentEdges = true }; RegisterCallback(OnMoveEnd); this.AddManipulator(m_Dragger); + + // Prevent the base graph view options (i.e. Create Node) from appearing. + this.AddManipulator(new ContextualMenuManipulator(_ => { })); } #region Layout diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/Views/HelpBoxRow.cs b/Packages/com.unity.shadergraph/Editor/Drawing/Views/HelpBoxRow.cs index b4fd5207..7c118cf3 100644 --- a/Packages/com.unity.shadergraph/Editor/Drawing/Views/HelpBoxRow.cs +++ b/Packages/com.unity.shadergraph/Editor/Drawing/Views/HelpBoxRow.cs @@ -1,111 +1,90 @@ using System; -using System.Linq; using UnityEngine; using UnityEngine.UIElements; namespace UnityEditor.ShaderGraph.Drawing { - // Similar in function to the old EditorGUILayout.HelpBox class HelpBoxRow : VisualElement { - VisualElement m_ContentContainer; - VisualElement m_LabelContainer; + // This element was originally reimplementing the entire HelpBox, but now that a UI Toolkit version is + // available, we are wrapping that for better consistency. + HelpBox m_HelpBox; - public override VisualElement contentContainer - { - get { return m_ContentContainer; } - } + // Space beneath the help box for actions, i.e. Upgrade/Dismiss buttons on out-of-date nodes. + VisualElement m_ActionContainer; + + public override VisualElement contentContainer => m_ActionContainer; - public HelpBoxRow(MessageType type) + HelpBoxRow(string text, HelpBoxMessageType messageType) { - styleSheets.Add(Resources.Load("Styles/HelpBoxRow")); - VisualElement container = new VisualElement { name = "container" }; - m_ContentContainer = new VisualElement { name = "content" }; - m_LabelContainer = new VisualElement { name = "label" }; + m_HelpBox = new HelpBox(text, messageType); + m_ActionContainer = new VisualElement(); - switch (type) - { - case MessageType.None: - container.AddToClassList("help-box-row-style-info"); - break; - case MessageType.Info: - container.AddToClassList("help-box-row-style-info"); - break; - case MessageType.Warning: - container.AddToClassList("help-box-row-style-warning"); - break; - case MessageType.Error: - container.AddToClassList("help-box-row-style-error"); - break; - default: - break; - } + hierarchy.Add(m_HelpBox); + hierarchy.Add(m_ActionContainer); + } - container.Add(m_LabelContainer); - container.Add(m_ContentContainer); + static HelpBoxMessageType ToHelpBoxMessageType(MessageType messageType) => + messageType switch + { + MessageType.Info => HelpBoxMessageType.Info, + MessageType.Warning => HelpBoxMessageType.Warning, + MessageType.Error => HelpBoxMessageType.Error, + MessageType.None => HelpBoxMessageType.None, + _ => HelpBoxMessageType.None + }; - hierarchy.Add(container); - } + public HelpBoxRow(string text, MessageType messageType) : this(text, ToHelpBoxMessageType(messageType)) { } - public static VisualElement CreateVariantLimitHelpBox(int currentVariantCount, int maxVariantCount) - { - var messageType = MessageType.Error; - HelpBoxRow help = new HelpBoxRow(messageType); - var label = new Label("Variant limit exceeded: Hover for more info") + public static VisualElement CreateVariantLimitHelpBox(int currentVariantCount, int maxVariantCount) => + new HelpBoxRow("Variant limit exceeded. Hover for more info.", HelpBoxMessageType.Error) { - tooltip = ShaderKeyword.kVariantLimitWarning, - name = "message-" + (messageType == MessageType.Warning ? "warn" : "info") + tooltip = ShaderKeyword.kVariantLimitWarning }; - help.Add(label); - return help; - } - public static VisualElement TryGetDeprecatedHelpBoxRow(string deprecatedTypeName, Action upgradeAction, Action dismissAction, string deprecationText = null, string buttonText = null, string labelText = null, MessageType messageType = MessageType.Warning) + // Creates a standard prompt for upgrading a Shader Graph element. + // If dismissAction is provided, a help box is created with an upgrade button and a dismiss button. + // Otherwise, only an upgrade button is created. + public static VisualElement CreateUpgradePrompt( + string deprecatedTypeName, + Action upgradeAction, + Action dismissAction, + string tooltip = null, + string buttonText = null, + string labelText = null, + MessageType messageType = MessageType.Warning + ) { - if (deprecationText == null) - { - deprecationText = $"The {deprecatedTypeName} has new updates. This version maintains the old behavior. " + - $"If you update a {deprecatedTypeName}, you can use Undo to change it back. See the {deprecatedTypeName} " + - $"documentation for more information."; - } - if (buttonText == null) - { - buttonText = "Update"; - } - if (labelText == null) - { - labelText = $"The {deprecatedTypeName} has new updates. This version maintains the old behavior. " + - $"If you update a {deprecatedTypeName}, you can use Undo to change it back. See the {deprecatedTypeName} " + - $"documentation for more information."; - } + tooltip ??= GetDefaultDeprecationMessage(deprecatedTypeName); + buttonText ??= "Update"; + labelText ??= GetDefaultDeprecationMessage(deprecatedTypeName); + + // If we are given a dismiss action, the user has not yet dismissed the warning and should be given the + // full message. Otherwise, assume the warning has already been dismissed and show just the upgrade button. + var displayFullWarning = dismissAction != null; + var upgradeButton = new Button(upgradeAction) { text = buttonText, tooltip = tooltip }; - Button upgradeButton = new Button(upgradeAction) { text = buttonText, tooltip = deprecationText }; - Button dismissButton = null; - if (dismissAction != null) - dismissButton = new Button(dismissAction) { text = "Dismiss" }; + VisualElement container; - if (dismissAction != null) + if (displayFullWarning) { - HelpBoxRow help = new HelpBoxRow(messageType); - var label = new Label(labelText) - { - tooltip = labelText, - name = "message-" + (messageType == MessageType.Warning ? "warn" : "info") - }; - help.Add(label); - help.contentContainer.Add(upgradeButton); - if (dismissButton != null) - help.contentContainer.Add(dismissButton); - return help; + var dismissButton = new Button(dismissAction) { text = "Dismiss" }; + container = new HelpBoxRow(labelText, messageType); + container.Add(upgradeButton); + container.Add(dismissButton); } else { - var box = new VisualElement(); - box.Add(upgradeButton); - if (dismissButton != null) - box.Add(dismissButton); - return box; + container = new VisualElement(); + container.Add(upgradeButton); } + + return container; + + static string GetDefaultDeprecationMessage(string typeName) => + $"The {typeName} has new updates. This version maintains the old behavior. " + + $"If you update a {typeName}, you can use Undo to change it back. See the {typeName} " + + "documentation for more information."; } } } diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/Views/MaterialGraphView.cs b/Packages/com.unity.shadergraph/Editor/Drawing/Views/MaterialGraphView.cs index c0ebe52d..fc49da8a 100644 --- a/Packages/com.unity.shadergraph/Editor/Drawing/Views/MaterialGraphView.cs +++ b/Packages/com.unity.shadergraph/Editor/Drawing/Views/MaterialGraphView.cs @@ -413,8 +413,8 @@ namespace UnityEditor.ShaderGraph.Drawing // We can manually add them back in here (although the context menu ordering is different). if (evt.target is StickyNote) { - evt.menu.AppendAction("Copy %d", (e) => CopySelectionCallback(), (a) => canCopySelection ? DropdownMenuAction.Status.Normal : DropdownMenuAction.Status.Disabled); - evt.menu.AppendAction("Cut %d", (e) => CutSelectionCallback(), (a) => canCutSelection ? DropdownMenuAction.Status.Normal : DropdownMenuAction.Status.Disabled); + evt.menu.AppendAction("Copy %c", (e) => CopySelectionCallback(), (a) => canCopySelection ? DropdownMenuAction.Status.Normal : DropdownMenuAction.Status.Disabled); + evt.menu.AppendAction("Cut %x", (e) => CutSelectionCallback(), (a) => canCutSelection ? DropdownMenuAction.Status.Normal : DropdownMenuAction.Status.Disabled); evt.menu.AppendAction("Duplicate %d", (e) => DuplicateSelectionCallback(), (a) => canDuplicateSelection ? DropdownMenuAction.Status.Normal : DropdownMenuAction.Status.Disabled); } @@ -965,7 +965,8 @@ namespace UnityEditor.ShaderGraph.Drawing bool CanPasteSerializedDataImplementation(string serializedData) { - return CopyPasteGraph.FromJson(serializedData, graph) != null; + var json = CopyPasteGraph.FromJson(serializedData, graph); + return json != null && !json.IsEmpty(); } void UnserializeAndPasteImplementation(string operationName, string serializedData) diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/Views/MaterialNodeView.cs b/Packages/com.unity.shadergraph/Editor/Drawing/Views/MaterialNodeView.cs index ca91cb6f..6390afa8 100644 --- a/Packages/com.unity.shadergraph/Editor/Drawing/Views/MaterialNodeView.cs +++ b/Packages/com.unity.shadergraph/Editor/Drawing/Views/MaterialNodeView.cs @@ -26,6 +26,7 @@ namespace UnityEditor.ShaderGraph.Drawing VisualElement m_PreviewContainer; VisualElement m_PreviewFiller; + VisualElement m_PreviewExpand; VisualElement m_ControlItems; VisualElement m_ControlsDivider; VisualElement m_DropdownItems; @@ -130,13 +131,13 @@ namespace UnityEditor.ShaderGraph.Drawing previewDivider.AddToClassList("horizontal"); m_PreviewFiller.Add(previewDivider); - var expandPreviewButton = new VisualElement { name = "expand" }; - expandPreviewButton.Add(new VisualElement { name = "icon" }); - expandPreviewButton.AddManipulator(new Clickable(() => + m_PreviewExpand = new VisualElement { name = "expand" }; + m_PreviewExpand.Add(new VisualElement { name = "icon" }); + m_PreviewExpand.AddManipulator(new Clickable(() => { SetPreviewExpandedStateOnSelection(true); })); - m_PreviewFiller.Add(expandPreviewButton); + m_PreviewFiller.Add(m_PreviewExpand); } contents.Add(m_PreviewFiller); @@ -481,9 +482,32 @@ namespace UnityEditor.ShaderGraph.Drawing return !(node is BlockNode) && m_CollapseButton.enabledInHierarchy; } + static bool IsPreviewable(AbstractMaterialNode node) + { + // only the first output slot is considered. + foreach (var slot in node.GetOutputSlots()) + { + switch (slot.concreteValueType) + { + case ConcreteSlotValueType.Vector4: + case ConcreteSlotValueType.Vector3: + case ConcreteSlotValueType.Vector2: + case ConcreteSlotValueType.Vector1: + return true; + } + return false; + } + return false; + } + void UpdatePreviewExpandedState(bool expanded) { - node.previewExpanded = expanded; + var previewable = IsPreviewable(node); + + if (m_PreviewExpand != null) + m_PreviewExpand.visible = previewable; + + node.previewExpanded = expanded && previewable; if (m_PreviewFiller == null) return; if (expanded) diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/Views/ResizableElement.cs b/Packages/com.unity.shadergraph/Editor/Drawing/Views/ResizableElement.cs index 7c13ed96..84a545d8 100644 --- a/Packages/com.unity.shadergraph/Editor/Drawing/Views/ResizableElement.cs +++ b/Packages/com.unity.shadergraph/Editor/Drawing/Views/ResizableElement.cs @@ -1,5 +1,5 @@ +using System; using System.Collections.Generic; -using UnityEditor.ShaderGraph.Drawing; using UnityEngine; using UnityEngine.UIElements; @@ -72,6 +72,7 @@ namespace UnityEditor.ShaderGraph.Drawing } } + [Flags] public enum Resizer { None = 0, diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Contexts/TargetPropertyGUIContext.cs b/Packages/com.unity.shadergraph/Editor/Generation/Contexts/TargetPropertyGUIContext.cs index 6b9e9984..071df567 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/Contexts/TargetPropertyGUIContext.cs +++ b/Packages/com.unity.shadergraph/Editor/Generation/Contexts/TargetPropertyGUIContext.cs @@ -72,8 +72,7 @@ namespace UnityEditor.ShaderGraph public void AddHelpBox(MessageType messageType, string messageText) { - var helpBox = new HelpBoxRow(messageType); - helpBox.Add(new Label(messageText)); + var helpBox = new HelpBoxRow(messageText, messageType); this.hierarchy.Add(helpBox); } diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Descriptors/PragmaDescriptor.cs b/Packages/com.unity.shadergraph/Editor/Generation/Descriptors/PragmaDescriptor.cs index c21a3528..03b87171 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/Descriptors/PragmaDescriptor.cs +++ b/Packages/com.unity.shadergraph/Editor/Generation/Descriptors/PragmaDescriptor.cs @@ -31,6 +31,8 @@ namespace UnityEditor.ShaderGraph public static PragmaDescriptor ExcludeRenderers(Platform[] renderers) => new PragmaDescriptor { value = $"exclude_renderers {GetPlatformList(renderers)}" }; public static PragmaDescriptor PreferHlslCC(Platform[] renderers) => new PragmaDescriptor { value = $"prefer_hlslcc {GetPlatformList(renderers)}" }; public static PragmaDescriptor InstancingOptions(InstancingOptions value) => new PragmaDescriptor { value = $"instancing_options {value.ToShaderString()}" }; + public static PragmaDescriptor ShaderFeatureLocal(string value) => new PragmaDescriptor { value = $"shader_feature_local {value}" }; + public static PragmaDescriptor ShaderFeatureLocalVertex(string value) => new PragmaDescriptor { value = $"shader_feature_local_vertex {value}" }; public static PragmaDescriptor MultiCompileInstancing => new PragmaDescriptor { value = "multi_compile_instancing" }; public static PragmaDescriptor MultiCompileForwardBase => new PragmaDescriptor { value = "multi_compile_fwdbase" }; public static PragmaDescriptor MultiCompileForwardAddFullShadowsBase => new PragmaDescriptor { value = "multi_compile_fwdadd_fullshadows" }; @@ -38,6 +40,7 @@ namespace UnityEditor.ShaderGraph public static PragmaDescriptor MultiCompileShadowCaster => new PragmaDescriptor { value = "multi_compile_shadowcaster" }; public static PragmaDescriptor DOTSInstancing => new PragmaDescriptor { value = "multi_compile _ DOTS_INSTANCING_ON" }; public static PragmaDescriptor MultiCompileFog => new PragmaDescriptor { value = "multi_compile_fog" }; + public static PragmaDescriptor MultiCompileLodCrossfade => new PragmaDescriptor { value = "multi_compile _ LOD_FADE_CROSSFADE" }; public static PragmaDescriptor EditorSyncCompilation => new PragmaDescriptor { value = "editor_sync_compilation" }; public static PragmaDescriptor DebugSymbols => new PragmaDescriptor { value = "enable_d3d11_debug_symbols" }; public static PragmaDescriptor SkipVariants(string[] variants) => new PragmaDescriptor { value = $"skip_variants {string.Join(" ", variants)}" }; diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Processors/GenerationUtils.cs b/Packages/com.unity.shadergraph/Editor/Generation/Processors/GenerationUtils.cs index efe3bf09..b8759db9 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/Processors/GenerationUtils.cs +++ b/Packages/com.unity.shadergraph/Editor/Generation/Processors/GenerationUtils.cs @@ -496,81 +496,19 @@ namespace UnityEditor.ShaderGraph ShaderGraphRequirementsPerKeyword vertexRequirements = new ShaderGraphRequirementsPerKeyword(); graphRequirements = new ShaderGraphRequirementsPerKeyword(); - // Evaluate all Keyword permutations - if (keywordCollector.permutations.Count > 0) - { - for (int i = 0; i < keywordCollector.permutations.Count; i++) - { - // Get active nodes for this permutation - var localVertexNodes = Pool.HashSetPool.Get(); - var localPixelNodes = Pool.HashSetPool.Get(); - - localVertexNodes.EnsureCapacity(vertexNodes.Count); - localPixelNodes.EnsureCapacity(pixelNodes.Count); - - foreach (var vertexNode in vertexNodes) - { - NodeUtils.DepthFirstCollectNodesFromNode(localVertexNodes, vertexNode, NodeUtils.IncludeSelf.Include, keywordCollector.permutations[i]); - } - - foreach (var pixelNode in pixelNodes) - { - NodeUtils.DepthFirstCollectNodesFromNode(localPixelNodes, pixelNode, NodeUtils.IncludeSelf.Include, keywordCollector.permutations[i]); - } - - // Track each vertex node in this permutation - foreach (AbstractMaterialNode vertexNode in localVertexNodes) - { - int nodeIndex = vertexNodes.IndexOf(vertexNode); - - if (vertexNodePermutations[nodeIndex] == null) - vertexNodePermutations[nodeIndex] = new List(); - vertexNodePermutations[nodeIndex].Add(i); - } - - // Track each pixel node in this permutation - foreach (AbstractMaterialNode pixelNode in localPixelNodes) - { - int nodeIndex = pixelNodes.IndexOf(pixelNode); + // Get requirements + vertexRequirements.baseInstance.SetRequirements(ShaderGraphRequirements.FromNodes(vertexNodes, ShaderStageCapability.Vertex, false, texCoordNeedsDerivs)); + pixelRequirements.baseInstance.SetRequirements(ShaderGraphRequirements.FromNodes(pixelNodes, ShaderStageCapability.Fragment, false, texCoordNeedsDerivs)); - if (pixelNodePermutations[nodeIndex] == null) - pixelNodePermutations[nodeIndex] = new List(); - pixelNodePermutations[nodeIndex].Add(i); - } - - // Get requirements for this permutation - vertexRequirements[i].SetRequirements(ShaderGraphRequirements.FromNodes(localVertexNodes, ShaderStageCapability.Vertex, false, texCoordNeedsDerivs)); - pixelRequirements[i].SetRequirements(ShaderGraphRequirements.FromNodes(localPixelNodes, ShaderStageCapability.Fragment, false, texCoordNeedsDerivs)); - - // Add active fields - var conditionalFields = GetActiveFieldsFromConditionals(GetConditionalFieldsFromPixelRequirements(pixelRequirements[i].requirements)); - if (activeFields[i].Contains(Fields.GraphVertex)) - { - conditionalFields.AddRange(GetActiveFieldsFromConditionals(GetConditionalFieldsFromVertexRequirements(vertexRequirements[i].requirements))); - } - foreach (var field in conditionalFields) - { - activeFields[i].Add(field); - } - } + // Add active fields + var conditionalFields = GetActiveFieldsFromConditionals(GetConditionalFieldsFromPixelRequirements(pixelRequirements.baseInstance.requirements)); + if (activeFields.baseInstance.Contains(Fields.GraphVertex)) + { + conditionalFields.AddRange(GetActiveFieldsFromConditionals(GetConditionalFieldsFromVertexRequirements(vertexRequirements.baseInstance.requirements))); } - // No Keywords - else + foreach (var field in conditionalFields) { - // Get requirements - vertexRequirements.baseInstance.SetRequirements(ShaderGraphRequirements.FromNodes(vertexNodes, ShaderStageCapability.Vertex, false, texCoordNeedsDerivs)); - pixelRequirements.baseInstance.SetRequirements(ShaderGraphRequirements.FromNodes(pixelNodes, ShaderStageCapability.Fragment, false, texCoordNeedsDerivs)); - - // Add active fields - var conditionalFields = GetActiveFieldsFromConditionals(GetConditionalFieldsFromPixelRequirements(pixelRequirements.baseInstance.requirements)); - if (activeFields.baseInstance.Contains(Fields.GraphVertex)) - { - conditionalFields.AddRange(GetActiveFieldsFromConditionals(GetConditionalFieldsFromVertexRequirements(vertexRequirements.baseInstance.requirements))); - } - foreach (var field in conditionalFields) - { - activeFields.baseInstance.Add(field); - } + activeFields.baseInstance.Add(field); } // Build graph requirements diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Processors/Generator.cs b/Packages/com.unity.shadergraph/Editor/Generation/Processors/Generator.cs index 34598d64..926f78ca 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/Processors/Generator.cs +++ b/Packages/com.unity.shadergraph/Editor/Generation/Processors/Generator.cs @@ -50,6 +50,8 @@ namespace UnityEditor.ShaderGraph readonly GeneratedShader m_PrimaryShader; readonly List m_PrimaryShaderTemporaryBlocks; + readonly Dictionary m_IncludeCache; + // direct accessors for primary shader results public string generatedShader => m_PrimaryShader.codeString; public List configuredTextures => m_PrimaryShader.assignedTextures; @@ -131,7 +133,7 @@ namespace UnityEditor.ShaderGraph m_AdditionalShaderIDs = additionalShaderIDs.AsReadOnly(); m_PrimaryShaderTemporaryBlocks = new List(); - + m_IncludeCache = new Dictionary(); // build the primary shader immediately (and populate the temporary block list for it) m_PrimaryShader = BuildShader(null, m_PrimaryShaderTemporaryBlocks); } @@ -393,6 +395,9 @@ namespace UnityEditor.ShaderGraph if (m_Mode == GenerationMode.Preview) activeFields.baseInstance.Add(Fields.IsPreview); + if (m_OutputNode == null && m_Mode == GenerationMode.Preview) + activeFields.baseInstance.Add(Fields.IsMainPreview); + // Check masternode fields for valid passes if (pass.TestActive(activeFields)) GenerateShaderPass(targetIndex, pass.descriptor, activeFields, activeBlockDescriptors.Select(x => x.descriptor).ToList(), subShaderProperties); @@ -1230,7 +1235,7 @@ namespace UnityEditor.ShaderGraph // Process Template Profiler.BeginSample("ProcessTemplate"); var templatePreprocessor = new ShaderSpliceUtil.TemplatePreprocessor(activeFields, spliceCommands, - isDebug, sharedTemplateDirectories, m_AssetCollection, m_HumanReadable); + isDebug, sharedTemplateDirectories, m_AssetCollection, m_HumanReadable, m_IncludeCache); templatePreprocessor.ProcessTemplateFile(passTemplatePath); m_Builder.Concat(templatePreprocessor.GetShaderCode()); diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Processors/PropertyCollector.cs b/Packages/com.unity.shadergraph/Editor/Generation/Processors/PropertyCollector.cs index 792e1ca8..f33adab5 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/Processors/PropertyCollector.cs +++ b/Packages/com.unity.shadergraph/Editor/Generation/Processors/PropertyCollector.cs @@ -92,11 +92,18 @@ namespace UnityEditor.ShaderGraph { Debug.LogError("Two properties with the same reference name (" + prop.referenceName + ") using different types"); } - else - { - if (!EquivalentHLSLProperties(existingProp, prop)) - Debug.LogError("Two properties with the same reference name (" + prop.referenceName + ") produce different HLSL properties"); - } + // else + // { + // if (!EquivalentHLSLProperties(existingProp, prop)) + // { + // NOTE: + // Shader Graph won't produce a duplicate property. + // Since the type is already the same (as per above) + // and by way of how targets/properties/subshaders work, + // any duplicate properties in SG will just use the same declaration. + // Debug.LogError("Two properties with the same reference name (" + prop.referenceName + ") produce different HLSL properties"); + // } + // } } } else diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Processors/ShaderSpliceUtil.cs b/Packages/com.unity.shadergraph/Editor/Generation/Processors/ShaderSpliceUtil.cs index f92282a5..c0f6b990 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/Processors/ShaderSpliceUtil.cs +++ b/Packages/com.unity.shadergraph/Editor/Generation/Processors/ShaderSpliceUtil.cs @@ -34,7 +34,16 @@ namespace UnityEditor.ShaderGraph while (index < end) { char c = str[index]; - if (!whitespace.Contains(c)) + bool containsWhiteSpace = false; + foreach (var whiteSpaceChar in whitespace) + { + if (c == whiteSpaceChar) + { + containsWhiteSpace = true; + break; + } + } + if (!containsWhiteSpace) { break; } @@ -53,12 +62,13 @@ namespace UnityEditor.ShaderGraph // intermediates HashSet includedFiles; + Dictionary includeCache; // this cache is reused across passes // outputs ShaderStringBuilder result; AssetCollection assetCollection; - public TemplatePreprocessor(ActiveFields activeFields, Dictionary namedFragments, bool isDebug, string[] templatePaths, AssetCollection assetCollection, bool humanReadable, ShaderStringBuilder outShaderCodeResult = null) + public TemplatePreprocessor(ActiveFields activeFields, Dictionary namedFragments, bool isDebug, string[] templatePaths, AssetCollection assetCollection, bool humanReadable, Dictionary includeCache, ShaderStringBuilder outShaderCodeResult = null) { this.activeFields = activeFields; this.namedFragments = namedFragments; @@ -67,6 +77,7 @@ namespace UnityEditor.ShaderGraph this.assetCollection = assetCollection; this.result = outShaderCodeResult ?? new ShaderStringBuilder(humanReadable: humanReadable); includedFiles = new HashSet(); + this.includeCache = includeCache; } public ShaderStringBuilder GetShaderCode() @@ -76,8 +87,7 @@ namespace UnityEditor.ShaderGraph public void ProcessTemplateFile(string filePath) { - if (File.Exists(filePath) && - !includedFiles.Contains(filePath)) + if (!includedFiles.Contains(filePath) && (includeCache.ContainsKey(filePath) || File.Exists(filePath))) { includedFiles.Add(filePath); @@ -88,8 +98,12 @@ namespace UnityEditor.ShaderGraph assetCollection.AddAssetDependency(guid, AssetCollection.Flags.SourceDependency); } - string[] templateLines = File.ReadAllLines(filePath); - foreach (string line in templateLines) + string[] templateLines; + if (!includeCache.TryGetValue(filePath, out templateLines)) + { + templateLines = File.ReadAllLines(filePath); + includeCache.TryAdd(filePath, templateLines); + } foreach (string line in templateLines) { ProcessTemplateLine(line, 0, line.Length); } @@ -223,8 +237,8 @@ namespace UnityEditor.ShaderGraph { string templatePath = templatePaths[i]; includeLocation = Path.Combine(templatePath, param.GetString()); - if (File.Exists(includeLocation)) - { + bool cacheHit = includeCache.ContainsKey(includeLocation); + if (cacheHit || File.Exists(includeLocation)) { found = true; break; } @@ -243,39 +257,29 @@ namespace UnityEditor.ShaderGraph } else { - int endIndex = result.length; - using (var temp = new ShaderStringBuilder(humanReadable: true)) + int oldLength = result.length; + // Wrap in debug mode + if (isDebug) { - // Wrap in debug mode - if (isDebug) - { - result.AppendLine("//-------------------------------------------------------------------------------------"); - result.AppendLine("// TEMPLATE INCLUDE : " + param.GetString()); - result.AppendLine("//-------------------------------------------------------------------------------------"); - result.AppendNewLine(); - } - - // Recursively process templates - ProcessTemplateFile(includeLocation); + result.AppendLine("//-------------------------------------------------------------------------------------"); + result.AppendLine("// TEMPLATE INCLUDE : " + param.GetString()); + result.AppendLine("//-------------------------------------------------------------------------------------"); + result.AppendNewLine(); + } - // Wrap in debug mode - if (isDebug) - { - result.AppendNewLine(); - result.AppendLine("//-------------------------------------------------------------------------------------"); - result.AppendLine("// END TEMPLATE INCLUDE : " + param.GetString()); - result.AppendLine("//-------------------------------------------------------------------------------------"); - } + // Recursively process templates + ProcessTemplateFile(includeLocation); + // Wrap in debug mode + if (isDebug) + { result.AppendNewLine(); - - // Required to enforce indentation rules - // Append lines from this include into temporary StringBuilder - // Reduce result length to remove this include - temp.AppendLines(result.ToString(endIndex, result.length - endIndex)); - result.length = endIndex; - result.AppendLines(temp.ToCodeBlock()); + result.AppendLine("//-------------------------------------------------------------------------------------"); + result.AppendLine("// END TEMPLATE INCLUDE : " + param.GetString()); + result.AppendLine("//-------------------------------------------------------------------------------------"); } + + result.ToCodeBlock(oldLength, result.length - oldLength, true); } } } diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Processors/ShaderStringBuilder.cs b/Packages/com.unity.shadergraph/Editor/Generation/Processors/ShaderStringBuilder.cs index 18029478..3de456e4 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/Processors/ShaderStringBuilder.cs +++ b/Packages/com.unity.shadergraph/Editor/Generation/Processors/ShaderStringBuilder.cs @@ -280,6 +280,15 @@ namespace UnityEditor.ShaderGraph return m_StringBuilder.ToString(); } + public void ToCodeBlock(int startIndex, int length, bool forceHumanReadable) + { + if (forceHumanReadable || m_HumanReadable) + { + // Set indentations + m_StringBuilder.Replace(Environment.NewLine, Environment.NewLine + k_IndentationString, startIndex, length); + } + } + public override string ToString() { return m_StringBuilder.ToString(); diff --git a/Packages/com.unity.shadergraph/Editor/Generation/ShaderGraphVfxAsset.cs b/Packages/com.unity.shadergraph/Editor/Generation/ShaderGraphVfxAsset.cs index 4b37554f..d283c23f 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/ShaderGraphVfxAsset.cs +++ b/Packages/com.unity.shadergraph/Editor/Generation/ShaderGraphVfxAsset.cs @@ -133,6 +133,11 @@ namespace UnityEditor.ShaderGraph.Internal internal set { m_OutputStructName = value; } } + internal void SetGUID(string guid) + { + m_Data.OverrideObjectId(guid, "SerializedVfxAssetData"); + } + public List properties { get diff --git a/Packages/com.unity.shadergraph/Editor/Generation/TargetResources/Fields.cs b/Packages/com.unity.shadergraph/Editor/Generation/TargetResources/Fields.cs index 153a9ddd..ebc1b330 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/TargetResources/Fields.cs +++ b/Packages/com.unity.shadergraph/Editor/Generation/TargetResources/Fields.cs @@ -19,6 +19,7 @@ namespace UnityEditor.ShaderGraph public static FieldDescriptor BlendAlpha = new FieldDescriptor(kBlendMode, "Alpha", "_BLENDMODE_ALPHA 1"); // URP: only sprite targets, vfx: HDRP? public static FieldDescriptor DoubleSided = new FieldDescriptor(string.Empty, "DoubleSided", "_DOUBLE_SIDED 1"); // URP: only sprite targets, duplicated in HD public static FieldDescriptor IsPreview = new FieldDescriptor(string.Empty, "isPreview", "SHADERGRAPH_PREVIEW"); + public static FieldDescriptor IsMainPreview = new FieldDescriptor(string.Empty, "isMainPreview", "SHADERGRAPH_PREVIEW_MAIN"); public static FieldDescriptor LodCrossFade = new FieldDescriptor(string.Empty, "LodCrossFade", "_LODCROSSFADE 1"); // HD only public static FieldDescriptor AlphaToMask = new FieldDescriptor(string.Empty, "AlphaToMask", "_ALPHATOMASK_ON 1"); // HD only diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/Editor/ShaderPreprocessor.cs b/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/Editor/ShaderPreprocessor.cs index 5f9000df..1bd6dde2 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/Editor/ShaderPreprocessor.cs +++ b/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/Editor/ShaderPreprocessor.cs @@ -28,6 +28,7 @@ namespace UnityEditor.Rendering.BuiltIn ScreenSpaceShadows = (1 << 12), ReflectionProbeBlending = (1 << 13), ReflectionProbeBoxProjection = (1 << 14), + ReflectionProbeAtlas = (1 << 15), } // This should really be part of the main BuiltIn Target Keyword list we use for reference names @@ -41,6 +42,8 @@ namespace UnityEditor.Rendering.BuiltIn public static readonly string AdditionalLightShadows = "_ADDITIONAL_LIGHT_SHADOWS"; public static readonly string ReflectionProbeBlending = "_REFLECTION_PROBE_BLENDING"; public static readonly string ReflectionProbeBoxProjection = "_REFLECTION_PROBE_BOX_PROJECTION"; + /// Keyword used for Reflection probe atlas. + public static readonly string ReflectionProbeAtlas = "_REFLECTION_PROBE_ATLAS"; // This is used during shadow map generation to differentiate between directional and punctual light shadows, // as they use different formulas to apply Normal Bias public static readonly string SoftShadows = "_SHADOWS_SOFT"; @@ -75,6 +78,7 @@ namespace UnityEditor.Rendering.BuiltIn ShaderKeyword m_AdditionalLightShadows = new ShaderKeyword(ShaderKeywordStrings.AdditionalLightShadows); ShaderKeyword m_ReflectionProbeBlending = new ShaderKeyword(ShaderKeywordStrings.ReflectionProbeBlending); ShaderKeyword m_ReflectionProbeBoxProjection = new ShaderKeyword(ShaderKeywordStrings.ReflectionProbeBoxProjection); + ShaderKeyword m_ReflectionProbeAtlas = new ShaderKeyword(ShaderKeywordStrings.ReflectionProbeAtlas); ShaderKeyword m_CastingPunctualLightShadow = new ShaderKeyword(ShaderKeywordStrings.CastingPunctualLightShadow); ShaderKeyword m_SoftShadows = new ShaderKeyword(ShaderKeywordStrings.SoftShadows); ShaderKeyword m_MixedLightingSubtractive = new ShaderKeyword(ShaderKeywordStrings.MixedLightingSubtractive); @@ -229,6 +233,10 @@ namespace UnityEditor.Rendering.BuiltIn if (!IsFeatureEnabled(features, ShaderFeatures.ReflectionProbeBoxProjection) && isReflectionProbeBoxProjection) return true; + bool isReflectionProbeAtlas = compilerData.shaderKeywordSet.IsEnabled(m_ReflectionProbeAtlas); + if (!IsFeatureEnabled(features, ShaderFeatures.ReflectionProbeAtlas) && isReflectionProbeAtlas) + return true; + bool isPunctualLightShadowCasterPass = (snippetData.passType == PassType.ShadowCaster) && compilerData.shaderKeywordSet.IsEnabled(m_CastingPunctualLightShadow); if (!IsFeatureEnabled(features, ShaderFeatures.AdditionalLightShadows) && isPunctualLightShadowCasterPass) return true; diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Input.hlsl b/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Input.hlsl index 403b06e6..a80df578 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Input.hlsl +++ b/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Input.hlsl @@ -56,7 +56,7 @@ StructuredBuffer _AdditionalLightsBuffer; StructuredBuffer _AdditionalLightsIndices; #else // GLES3 causes a performance regression in some devices when using CBUFFER. -#ifndef SHADER_API_GLES3 +#ifndef LIGHT_SHADOWS_NO_CBUFFER CBUFFER_START(AdditionalLights) #endif float4 _AdditionalLightsPosition[MAX_VISIBLE_LIGHTS]; @@ -64,7 +64,7 @@ half4 _AdditionalLightsColor[MAX_VISIBLE_LIGHTS]; half4 _AdditionalLightsAttenuation[MAX_VISIBLE_LIGHTS]; half4 _AdditionalLightsSpotDir[MAX_VISIBLE_LIGHTS]; half4 _AdditionalLightsOcclusionProbes[MAX_VISIBLE_LIGHTS]; -#ifndef SHADER_API_GLES3 +#ifndef LIGHT_SHADOWS_NO_CBUFFER CBUFFER_END #endif #endif diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Shadows.hlsl b/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Shadows.hlsl index 14a5d167..016c7e75 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Shadows.hlsl +++ b/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Shadows.hlsl @@ -49,7 +49,7 @@ TEXTURE2D_SHADOW(_AdditionalLightsShadowmapTexture); SAMPLER_CMP(sampler_AdditionalLightsShadowmapTexture); // GLES3 causes a performance regression in some devices when using CBUFFER. -#ifndef SHADER_API_GLES3 +#ifndef LIGHT_SHADOWS_NO_CBUFFER CBUFFER_START(MainLightShadows) #endif // Last cascade is initialized with a no-op matrix. It always transforms @@ -67,7 +67,7 @@ half4 _MainLightShadowOffset2; half4 _MainLightShadowOffset3; half4 _MainLightShadowParams; // (x: shadowStrength, y: 1.0 if soft shadows, 0.0 otherwise, z: main light fade scale, w: main light fade bias) float4 _MainLightShadowmapSize; // (xy: 1/width and 1/height, zw: width and height) -#ifndef SHADER_API_GLES3 +#ifndef LIGHT_SHADOWS_NO_CBUFFER CBUFFER_END #endif @@ -98,7 +98,7 @@ float4 _AdditionalShadowmapSize; // (xy: 1/width and 1/height, zw: width an #endif // GLES3 causes a performance regression in some devices when using CBUFFER. -#ifndef SHADER_API_GLES3 +#ifndef LIGHT_SHADOWS_NO_CBUFFER CBUFFER_START(AdditionalLightShadows) #endif @@ -112,7 +112,7 @@ half4 _AdditionalShadowOffset3; half4 _AdditionalShadowFadeParams; // x: additional light fade scale, y: additional light fade bias, z: 0.0, w: 0.0) float4 _AdditionalShadowmapSize; // (xy: 1/width and 1/height, zw: width and height) -#ifndef SHADER_API_GLES3 +#ifndef LIGHT_SHADOWS_NO_CBUFFER CBUFFER_END #endif @@ -326,8 +326,8 @@ half AdditionalLightRealtimeShadow(int lightIndex, float3 positionWS, half3 ligh if (isPointLight) { // This is a point light, we have to find out which shadow slice to sample from - float cubemapFaceId = CubeMapFaceID(-lightDirection); - shadowSliceIndex += cubemapFaceId; + const int cubeFaceOffset = CubeMapFaceID(-lightDirection); + shadowSliceIndex += cubeFaceOffset; } #if USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Targets/CustomRenderTexture/CustomTextureGraph.hlsl b/Packages/com.unity.shadergraph/Editor/Generation/Targets/CustomRenderTexture/CustomTextureGraph.hlsl index eadf042f..02a40f66 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/Targets/CustomRenderTexture/CustomTextureGraph.hlsl +++ b/Packages/com.unity.shadergraph/Editor/Generation/Targets/CustomRenderTexture/CustomTextureGraph.hlsl @@ -3,10 +3,12 @@ float4 SRGBToLinear( float4 c ) { return c; } float3 SRGBToLinear( float3 c ) { return c; } +float4 LinearToSRGB( float4 c ) { return c; } +float3 LinearToSRGB( float3 c ) { return c; } // Unpack normal as DXT5nm (1, y, 1, x) or BC5 (x, y, 0, 1) // Note neutral texture like "bump" is (0, 0, 1, 1) to work with both plain RGB normal and DXT5nm/BC5 -float3 UnpackNormalmapRGorAG(float4 packednormal) +float3 UnpackNormalMapRGAG(float4 packednormal) { // This do the trick packednormal.x *= packednormal.w; @@ -22,7 +24,7 @@ inline float3 UnpackNormal(float4 packednormal) #if defined(UNITY_NO_DXT5nm) return packednormal.xyz * 2 - 1; #else - return UnpackNormalmapRGorAG(packednormal); + return UnpackNormalMapRGAG(packednormal); #endif } diff --git a/Packages/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs b/Packages/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs index a27eb52a..2eaa4ae3 100644 --- a/Packages/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs +++ b/Packages/com.unity.shadergraph/Editor/Importers/ShaderGraphImporter.cs @@ -20,6 +20,7 @@ namespace UnityEditor.ShaderGraph { public const string Extension = "shadergraph"; public const string LegacyExtension = "ShaderGraph"; + const string IconBasePath = "Packages/com.unity.shadergraph/Editor/Resources/Icons/sg_graph_icon.png"; public const string k_ErrorShader = @" Shader ""Hidden/GraphErrorShader2"" @@ -63,6 +64,8 @@ Shader ""Hidden/GraphErrorShader2"" Fallback Off }"; + public static Texture2D GetIcon() => EditorGUIUtility.IconContent(IconBasePath)?.image as Texture2D; + [SuppressMessage("ReSharper", "UnusedMember.Local")] static string[] GatherDependenciesFromSourceFile(string assetPath) { @@ -236,8 +239,7 @@ Shader ""Hidden/GraphErrorShader2"" mainObject = ShaderUtil.CreateShaderAsset(ctx, k_ErrorShader, false); } - Texture2D texture = Resources.Load("Icons/sg_graph_icon"); - ctx.AddObjectToAsset("MainAsset", mainObject, texture); + ctx.AddObjectToAsset("MainAsset", mainObject, GetIcon()); ctx.SetMainObject(mainObject); var graphDataReadOnly = new GraphDataReadOnly(graph); @@ -699,7 +701,7 @@ Shader ""Hidden/GraphErrorShader2"" // foreach (var node in source.nodes) // { // message.AppendLine($"{node.name} ({node.objectId}): {node.concretePrecision}"); - // } + // } // throw new InvalidOperationException(message.ToString()); //} @@ -986,6 +988,7 @@ Shader ""Hidden/GraphErrorShader2"" asset.inputStructName = inputStructName; asset.outputStructName = outputStructName; asset.portRequirements = portRequirements; + asset.SetGUID(assetGuid); asset.m_PropertiesStages = propertiesStages.ToArray(); asset.concretePrecision = graph.graphDefaultConcretePrecision; asset.SetProperties(inputProperties); diff --git a/Packages/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs b/Packages/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs index edfe5951..46b3d920 100644 --- a/Packages/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs +++ b/Packages/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs @@ -23,6 +23,9 @@ namespace UnityEditor.ShaderGraph class ShaderSubGraphImporter : ScriptedImporter { public const string Extension = "shadersubgraph"; + const string IconBasePath = "Packages/com.unity.shadergraph/Editor/Resources/Icons/sg_subgraph_icon.png"; + + public static Texture2D GetIcon() => EditorGUIUtility.IconContent(IconBasePath)?.image as Texture2D; [SuppressMessage("ReSharper", "UnusedMember.Local")] static string[] GatherDependenciesFromSourceFile(string assetPath) @@ -112,8 +115,7 @@ namespace UnityEditor.ShaderGraph messageManager.ClearAll(); } - Texture2D texture = Resources.Load("Icons/sg_subgraph_icon"); - ctx.AddObjectToAsset("MainAsset", graphAsset, texture); + ctx.AddObjectToAsset("MainAsset", graphAsset, GetIcon()); ctx.SetMainObject(graphAsset); var metadata = ScriptableObject.CreateInstance(); @@ -275,6 +277,7 @@ namespace UnityEditor.ShaderGraph { asset.isValid = false; registry.ProvideFunction(asset.functionName, sb => { }); + outputSlots.Dispose(); return; } diff --git a/Packages/com.unity.shadergraph/Editor/Resources/Icons/sg_graph_icon@2x.png b/Packages/com.unity.shadergraph/Editor/Resources/Icons/sg_graph_icon@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..40064d03a42022e6275092a146a71672c10a3414 GIT binary patch literal 1426 zcmZ{kX;4#F6vtm80RbV5nb1*auvGySK}so6kUdC-eHAL3mJ%(JKnc>IK*}x(iVuN6 zP@!y97K=zG1p!%PXiQK*AOsVZVAuoF5R){ekMf0n=$*Ou%-nnDf41M8o8F%1v@{NC z005wccXjrKEOmSDRfWzT+lwp!Km_BR9sGZSt-L2))=SV=T@zR1<^AM_mYLr@>A3zt z?xv&3zFGd}U0EjRM`XwfN{i#+f?aQt&-n@DC)X=WuHS({`OvyKwfOI~3lrJUExku(ly z{lpp(Bd8%~fxUrJW z+iYEQuTPzKP4RgKOsfE&O(av_i61AGALYuz6Y@Krn$!%-c;cs(abPsR^xHSIn}z(E z4gWStEik15h$d|9XJOC#CcT@jJL|%7S%uaX;MareA5RLVO$IsKB^;{SZsF>(Pw=tI z$@N?T`GX5Nn^Qn&NLdGr0IW0&VSKuzGXeaRgEq4YX1>ID5BFqit|k_VM&mcLkN2sW zxQ&WP9mRv_85ooS5u>*Du1K8Id&0f(M$MRTnf41pTHN%*S6BM}=&fDsb)o}P5qvFj z>sqe$Bkey!QIL-@L+XBtk8vy(mIEz-dCk^7c&Sm5VPi4YDLt_cgd?c&D_HwLTvkTA zaDaOOlGs&p(^H~7^>yY3>tN7GczLKR&j|TY5BcGo#%WlW>>9kVZzX$l%cX1}FOQM? zFxl>s=WOvP2Ls0c+M)u3oC`duY>#LUc`_>zduNz3ncZRig+rG*z+s>sHMf)B&e=VX zv4jg7v%c?`;G+^bzsyVm4@gjaH9zKr!Uy3q6xJD#4DW`=<)jQz{ zFNR8#g^I9b$D*0}d9h(zQjct!u%nmW?`3-B#bSnXWtwEy8IXelFuP#f&FE{(bp2tA z4a2erJVuqo$c%$8fx=BM18DWihOnMaI%-CRx`Q@?XfP!)vMRgry+Y~h&Y|HP`nT(1 zX{#8_#1&f$4lPy*LKfl_=$$fF7^Hl|6oF!QlYKv|FEdEW?(7;d1zc>6gC2GzWJ94&3m#gczjg;26Da^rwd)>8k z_V{_}nbhUOpyq(NLpKx*TmA0l)K)u@B~BU<_P$90XZM66q+>1ZSDO+^Z3EB3I}h7} zXe5+jd|Y&Z0q@FLQ(GOk@$-`0BHoxj#$Y*&e3n3oi6*=hpFDEwdO)+AzV5%jW8hV< zY90(7XljuA*B)KeJyv-cm-j+J!kwYx&MOfo?s2yGnDPZ-kWaX_FFjGMQxuQ zxc)k&IZBY}ccx#pjc6t7TTK(u6+DtQY_yeJ;zw~w3~bUp1QG0L2Rn#7{%no_g6UBX zRgu-&_k&MuwU{VKF-LqPR8B!{Lqz#VVmSmyW(xc-uVWh_V;G%yS8ujge?tCh-Bk2vU0)PKg&ZUT0Jp;Qy>*PBjeIuW5+3*d2{ K&W(-{Y5xEtAEmwk literal 0 HcmV?d00001 diff --git a/Packages/com.unity.shadergraph/Editor/Resources/Icons/sg_graph_icon@2x.png.meta b/Packages/com.unity.shadergraph/Editor/Resources/Icons/sg_graph_icon@2x.png.meta new file mode 100644 index 00000000..d9de57b2 --- /dev/null +++ b/Packages/com.unity.shadergraph/Editor/Resources/Icons/sg_graph_icon@2x.png.meta @@ -0,0 +1,117 @@ +fileFormatVersion: 2 +guid: c1e1b751487e43d43923f055990214ea +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 4 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 4 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + customData: + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spriteCustomMetadata: + entries: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.shadergraph/Editor/Resources/Icons/sg_subgraph_icon@2x.png b/Packages/com.unity.shadergraph/Editor/Resources/Icons/sg_subgraph_icon@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..f6ed8352b39137e71311e7f3678a528b646a3308 GIT binary patch literal 1635 zcmbW2`#TeQ9LK-AGz+gchW z-0wyrR_CAg`<}1H+QU@lQ2>-QzZ(K_g}MMBw4EKvjJSZ$`P<7}U9_4oQakn20y(dvD4=Q$h_O@=qd+xNTl-)U>}jS>nI z+9zbM@4lK?iLhRHQ6_6=mosDMUkK~smlKn+pS#`eIl3XcO!?DND!=gkcms}|X~oLRp@5@uxQ@73)744KJ|qUr%JG9;I}kUEJozVbBMh5)nIkw`3Z6tG z@cWz)p%==^6p`FNmflp`Ai2-PEhT}+RIFZU&e_Pck}4yTOYOht5Be}IB3|jSxWTpO z&G+~tu&T{ssqGU#_W9ZCl(PbeohXa3213uU+5T5D_`>z_(1w$o`{zcLppRj`&Yo(( z_+x4n@1WfnFbjbOrkl8k$Hqf2v5bDil&PGzo_Z?TeqGQ<2$NUof z9!17C5cQ_rV>Eapx>5b4d*Lk5J?U&oTh`|~b*z{BSxP_nWg589mE2MeJ@7}NLXd1BHKlDlLtE&&jMc9Q&=I*=s@JRwl5 zxqOLl3}(JzOQCR**OE++0)`jJUTa3?p`j*hf~H@GKv%X2^OPkI5ig6D$Yq~Y@d=2Q62@wourHuAF*Z)cZAFsG}J68 z?+W&9<*)+oom{azdRfoFH`AMppkDNeh2?H}T!W6L#0>{H^Rk1d++NF%=WuXA{v%Om zomxue)?4u0)L12pA_DA1>3g}uEuy^qW!BiFi6Vl<#p!-Vlfmn+d$c|v|95eZHx+Pt zhP$Rl6B~)Jw^e>-Au@)t2B-#UQo`hQGPZ?P6kUq~>d zqMVfmkS3wEiE|G@jdW7=vgF<4*Jg(geb~9smlau~XH{%_$?Q9LmjXl${7?$KQt#Kn ztrH0Jh5gidGqnT^cz9CYcJmf*7Q9Sv7_fx;AjjgYus{u9%p}v3#xN|{MiULaqaa4( zfa6{T-EFF0a^F<6zNnt$7uGkUx2Xp1ipBZ;!?*(fZR#ynlquS<`Za*_PMTxIj= #top { +.mainContainer > #top { flex-direction: row; justify-content: space-between; - background-color: rgb(64, 64, 64); + background-color: #393939; padding: 8px; border-top-left-radius: 6px; border-top-right-radius: 6px; } -MasterPreviewView > #top > #title { +.mainContainer > #top > #title { overflow: hidden; font-size: 14px; color: rgb(180, 180, 180); padding: 1px 2px 2px; } -MasterPreviewView > #middle { - background-color: rgb(49, 49, 49); +.mainContainer > #middle { + background-color: #2e2e2e; flex-grow: 1; flex-direction: row; } -MasterPreviewView > #middle > #preview { +.mainContainer > #middle > #preview { flex-grow: 1; width: 100px; height: 100px; diff --git a/Packages/com.unity.shadergraph/Editor/Resources/UXML/Blackboard/SGBlackboard.uxml b/Packages/com.unity.shadergraph/Editor/Resources/UXML/Blackboard/SGBlackboard.uxml index 5de9d564..d0af4dfc 100644 --- a/Packages/com.unity.shadergraph/Editor/Resources/UXML/Blackboard/SGBlackboard.uxml +++ b/Packages/com.unity.shadergraph/Editor/Resources/UXML/Blackboard/SGBlackboard.uxml @@ -10,8 +10,8 @@ - - + + diff --git a/Packages/com.unity.shadergraph/Editor/Resources/UXML/GraphInspector.uxml b/Packages/com.unity.shadergraph/Editor/Resources/UXML/GraphInspector.uxml index de551f9c..0ba8a9e2 100644 --- a/Packages/com.unity.shadergraph/Editor/Resources/UXML/GraphInspector.uxml +++ b/Packages/com.unity.shadergraph/Editor/Resources/UXML/GraphInspector.uxml @@ -6,7 +6,7 @@ - + diff --git a/Packages/com.unity.shadergraph/Editor/Serialization/MultiJsonInternal.cs b/Packages/com.unity.shadergraph/Editor/Serialization/MultiJsonInternal.cs index 34c825e5..94bc45f6 100644 --- a/Packages/com.unity.shadergraph/Editor/Serialization/MultiJsonInternal.cs +++ b/Packages/com.unity.shadergraph/Editor/Serialization/MultiJsonInternal.cs @@ -438,8 +438,7 @@ namespace UnityEditor.ShaderGraph.Serialization internal override void OnPropertiesGUI(VisualElement context, Action onChange, Action registerUndo, GraphData owner) { - var helpBox = new HelpBoxRow(MessageType.Info); - helpBox.Add(new Label("Cannot find the code for this data extension, a package may be missing.")); + var helpBox = new HelpBoxRow("Cannot find the code for this data extension, a package may be missing.", MessageType.Info); context.hierarchy.Add(helpBox); } } diff --git a/Packages/com.unity.shadergraph/Editor/ShaderGraphProjectSettings.cs b/Packages/com.unity.shadergraph/Editor/ShaderGraphProjectSettings.cs index 876c46bf..229f0d87 100644 --- a/Packages/com.unity.shadergraph/Editor/ShaderGraphProjectSettings.cs +++ b/Packages/com.unity.shadergraph/Editor/ShaderGraphProjectSettings.cs @@ -31,15 +31,15 @@ namespace UnityEditor.ShaderGraph { private static int kMaxChannelThreshold = 32; private static int kMinChannelThreshold = 8; - private static string kCustomInterpolatorHelpBox = "Unity uses these options to help ShaderGraph users maintain known compatibilities with target platform(s) when using Custom Interpolators."; + private static string kCustomInterpolatorHelpBox = "Unity uses these options to help Shader Graph users maintain known compatibilities with target platform(s) when using Custom Interpolators."; private static string kCustomInterpolatorDocumentationURL = UnityEngine.Rendering.ShaderGraph.Documentation.GetPageLink("Custom-Interpolators"); private class Styles { public static readonly GUIContent shaderVariantLimitLabel = L10n.TextContent("Shader Variant Limit", ""); public static readonly GUIContent CustomInterpLabel = L10n.TextContent("Custom Interpolator Channel Settings", ""); - public static readonly GUIContent CustomInterpWarnThresholdLabel = L10n.TextContent("Warning Threshold", $"ShaderGraph displays a warning when the user creates more custom interpolators than permitted by this setting. The number of interpolators that trigger this warning must be between {kMinChannelThreshold} and the Error Threshold."); - public static readonly GUIContent CustomInterpErrorThresholdLabel = L10n.TextContent("Error Threshold", $"ShaderGraph displays an error message when the user tries to create more custom interpolators than permitted by this setting. The number of interpolators that trigger this error must be between {kMinChannelThreshold} and {kMaxChannelThreshold}."); + public static readonly GUIContent CustomInterpWarnThresholdLabel = L10n.TextContent("Warning Threshold", $"Shader Graph displays a warning when the user creates more custom interpolators than permitted by this setting. The number of interpolators that trigger this warning must be between {kMinChannelThreshold} and the Error Threshold."); + public static readonly GUIContent CustomInterpErrorThresholdLabel = L10n.TextContent("Error Threshold", $"Shader Graph displays an error message when the user tries to create more custom interpolators than permitted by this setting. The number of interpolators that trigger this error must be between {kMinChannelThreshold} and {kMaxChannelThreshold}."); public static readonly GUIContent ReadMore = L10n.TextContent("Read more"); public static readonly GUIContent HeatmapSectionLabel = L10n.TextContent("Heatmap Color Mode Settings", ""); @@ -136,7 +136,7 @@ namespace UnityEditor.ShaderGraph [SettingsProvider] public static SettingsProvider CreateShaderGraphProjectSettingsProvider() { - var provider = new ShaderGraphProjectSettingsProvider("Project/ShaderGraph", SettingsScope.Project); + var provider = new ShaderGraphProjectSettingsProvider("Project/Shader Graph", SettingsScope.Project); return provider; } } diff --git a/Packages/com.unity.shadergraph/Editor/Util/CopyPasteGraph.cs b/Packages/com.unity.shadergraph/Editor/Util/CopyPasteGraph.cs index b00c0e5a..4458f4a7 100644 --- a/Packages/com.unity.shadergraph/Editor/Util/CopyPasteGraph.cs +++ b/Packages/com.unity.shadergraph/Editor/Util/CopyPasteGraph.cs @@ -151,6 +151,22 @@ namespace UnityEditor.ShaderGraph m_Edges = distinct.ToList(); } + public bool IsEmpty() + { + return m_MetaDropdownIds.Count == 0 + && m_MetaDropdowns.Count == 0 + && m_MetaKeywordIds.Count == 0 + && m_MetaKeywords.Count == 0 + && m_MetaProperties.Count == 0 + && m_MetaPropertyIds.Count == 0 + && m_Edges.Count == 0 + && m_Categories.Count == 0 + && m_Groups.Count == 0 + && m_Inputs.Count == 0 + && m_Nodes.Count == 0 + && m_StickyNotes.Count == 0; + } + public bool IsInputCategorized(ShaderInput shaderInput) { foreach (var category in categories) diff --git a/Packages/com.unity.shadergraph/Editor/Util/UIUtilities.cs b/Packages/com.unity.shadergraph/Editor/Util/UIUtilities.cs index 0301c787..83d54b92 100644 --- a/Packages/com.unity.shadergraph/Editor/Util/UIUtilities.cs +++ b/Packages/com.unity.shadergraph/Editor/Util/UIUtilities.cs @@ -39,6 +39,7 @@ namespace UnityEditor.Graphing.Util { hashCode = hashCode * 31 + (@object == null ? 79 : @object.GetHashCode()); } + return hashCode; } @@ -75,7 +76,18 @@ namespace UnityEditor.Graphing.Util centroid = centroid + (position - centroid) / count; ++count; } + return centroid; } + + // A new element added to a ScrollView can't be scrolled to until its layout is calculated. + // This function will scroll to the target element after the scroll view's layout is updated. + public static void ScrollToElementAfterGeometryChange(this ScrollView scrollView, VisualElement target) + { + scrollView.contentContainer.RegisterCallbackOnce(e => + { + scrollView.ScrollTo(target); + }); + } } } diff --git a/Packages/com.unity.shadergraph/README.md b/Packages/com.unity.shadergraph/README.md index 2afc4b14..6964f3bc 100644 --- a/Packages/com.unity.shadergraph/README.md +++ b/Packages/com.unity.shadergraph/README.md @@ -10,7 +10,7 @@ Unless you intend to modify Shader Graph or want to try out the latest and unsup 2. Open the **Package Manager** window (**Window** > **Package Manager**). 3. In the **Package Manager** window, in the **Packages** menu, select **Unity Registry**. 4. Do one of the following, based on your project needs: - - To use Shader Graph and the [Universal Render Pipeline (URP)](https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@latest) in your project, select **Universal RP**. + - To use Shader Graph and the [Universal Render Pipeline (URP)](https://docs.unity3d.com/Manual/urp/urp-introduction.html) in your project, select **Universal RP**. - To use Shader Graph and the [High Definition Render Pipeline (HDRP)](https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@latest), select **High Definition RP**. - To use Shader Graph with Unity's [Built-In Render Pipeline](https://docs.unity3d.com/2020.3/Documentation/Manual/built-in-render-pipeline.html), select **Shader Graph**. diff --git a/Packages/com.unity.shadergraph/ShaderGraphLibrary/Nature/SpeedTree8InterpolatedNormals.shadersubgraph b/Packages/com.unity.shadergraph/ShaderGraphLibrary/Nature/SpeedTree8InterpolatedNormals.shadersubgraph index 1f94e132..f10546b9 100644 --- a/Packages/com.unity.shadergraph/ShaderGraphLibrary/Nature/SpeedTree8InterpolatedNormals.shadersubgraph +++ b/Packages/com.unity.shadergraph/ShaderGraphLibrary/Nature/SpeedTree8InterpolatedNormals.shadersubgraph @@ -51,9 +51,6 @@ { "m_Id": "dd03de9776a64dfdb64ef4ac2f305ae3" }, - { - "m_Id": "d4a1cb334c16407da0eb7a4d243196cb" - }, { "m_Id": "0f4038e8d88c497a9848d40cea1db0a8" }, @@ -90,9 +87,6 @@ { "m_Id": "29c30d95951e4d9a9741deb69d673713" }, - { - "m_Id": "bc90282dda9f4917a7bae0c6aeb470d3" - }, { "m_Id": "f36e6c8eb7034a9ea61c2e81ad7cde3b" }, @@ -110,9 +104,31 @@ }, { "m_Id": "554037657d664172aaa8465f199bbeb1" + }, + { + "m_Id": "7b4a6ad1f8f0484ab1a0fa456cce6f1c" + }, + { + "m_Id": "fbdf75d73fab4ab19d741189db36eefb" + }, + { + "m_Id": "a3a614da9af04ec39f1170d7b782558e" + }, + { + "m_Id": "333d81460a3445b88019a0a6aa388a7e" + }, + { + "m_Id": "a6957c55b3b54f4d9e52907f1ec73825" + }, + { + "m_Id": "940efe1fbe1c4282b6ef117cac6dae02" + } + ], + "m_GroupDatas": [ + { + "m_Id": "d58da93c92c248cba0b083045eaaccbb" } ], - "m_GroupDatas": [], "m_StickyNoteDatas": [], "m_Edges": [ { @@ -185,6 +201,20 @@ "m_SlotId": 2 } }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "333d81460a3445b88019a0a6aa388a7e" + }, + "m_SlotId": 2 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "a6957c55b3b54f4d9e52907f1ec73825" + }, + "m_SlotId": 0 + } + }, { "m_OutputSlot": { "m_Node": { @@ -297,6 +327,48 @@ "m_SlotId": 1 } }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "7b4a6ad1f8f0484ab1a0fa456cce6f1c" + }, + "m_SlotId": 4 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "a3a614da9af04ec39f1170d7b782558e" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "7b4a6ad1f8f0484ab1a0fa456cce6f1c" + }, + "m_SlotId": 5 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "a3a614da9af04ec39f1170d7b782558e" + }, + "m_SlotId": 2 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "7b4a6ad1f8f0484ab1a0fa456cce6f1c" + }, + "m_SlotId": 6 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "a3a614da9af04ec39f1170d7b782558e" + }, + "m_SlotId": 3 + } + }, { "m_OutputSlot": { "m_Node": { @@ -328,27 +400,27 @@ { "m_OutputSlot": { "m_Node": { - "m_Id": "a78b467401cb4f2c90ea5876534cb2eb" + "m_Id": "940efe1fbe1c4282b6ef117cac6dae02" }, "m_SlotId": 2 }, "m_InputSlot": { "m_Node": { - "m_Id": "ad59d8af04f34879a7db1f47ac21d918" + "m_Id": "333d81460a3445b88019a0a6aa388a7e" }, - "m_SlotId": 1 + "m_SlotId": 0 } }, { "m_OutputSlot": { "m_Node": { - "m_Id": "ad59d8af04f34879a7db1f47ac21d918" + "m_Id": "a3a614da9af04ec39f1170d7b782558e" }, - "m_SlotId": 3 + "m_SlotId": 0 }, "m_InputSlot": { "m_Node": { - "m_Id": "2c7b5b9152be452e9b7e932fe1aac767" + "m_Id": "940efe1fbe1c4282b6ef117cac6dae02" }, "m_SlotId": 0 } @@ -356,13 +428,13 @@ { "m_OutputSlot": { "m_Node": { - "m_Id": "ad59d8af04f34879a7db1f47ac21d918" + "m_Id": "a3a614da9af04ec39f1170d7b782558e" }, - "m_SlotId": 3 + "m_SlotId": 0 }, "m_InputSlot": { "m_Node": { - "m_Id": "d34a6dac40b643db9cb4e799d2310ac7" + "m_Id": "940efe1fbe1c4282b6ef117cac6dae02" }, "m_SlotId": 1 } @@ -370,27 +442,55 @@ { "m_OutputSlot": { "m_Node": { - "m_Id": "bc90282dda9f4917a7bae0c6aeb470d3" + "m_Id": "a3a614da9af04ec39f1170d7b782558e" }, "m_SlotId": 0 }, "m_InputSlot": { "m_Node": { - "m_Id": "d4a1cb334c16407da0eb7a4d243196cb" + "m_Id": "a6957c55b3b54f4d9e52907f1ec73825" }, - "m_SlotId": 1 + "m_SlotId": 2 } }, { "m_OutputSlot": { + "m_Node": { + "m_Id": "a6957c55b3b54f4d9e52907f1ec73825" + }, + "m_SlotId": 3 + }, + "m_InputSlot": { "m_Node": { "m_Id": "cafe4baf3a264c5f8cf3d57e6b8d567e" }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "a78b467401cb4f2c90ea5876534cb2eb" + }, "m_SlotId": 2 }, "m_InputSlot": { "m_Node": { - "m_Id": "d262d084d8a24f75a887851e71acd55c" + "m_Id": "ad59d8af04f34879a7db1f47ac21d918" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "ad59d8af04f34879a7db1f47ac21d918" + }, + "m_SlotId": 3 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "2c7b5b9152be452e9b7e932fe1aac767" }, "m_SlotId": 0 } @@ -398,13 +498,27 @@ { "m_OutputSlot": { "m_Node": { - "m_Id": "d262d084d8a24f75a887851e71acd55c" + "m_Id": "ad59d8af04f34879a7db1f47ac21d918" + }, + "m_SlotId": 3 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "d34a6dac40b643db9cb4e799d2310ac7" }, "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "cafe4baf3a264c5f8cf3d57e6b8d567e" + }, + "m_SlotId": 2 }, "m_InputSlot": { "m_Node": { - "m_Id": "025880703d8641548199db0fbf89c334" + "m_Id": "d262d084d8a24f75a887851e71acd55c" }, "m_SlotId": 0 } @@ -414,11 +528,11 @@ "m_Node": { "m_Id": "d262d084d8a24f75a887851e71acd55c" }, - "m_SlotId": 2 + "m_SlotId": 1 }, "m_InputSlot": { "m_Node": { - "m_Id": "ee7cba1ca7b14dd8a840edaa0eaa988a" + "m_Id": "025880703d8641548199db0fbf89c334" }, "m_SlotId": 0 } @@ -428,11 +542,11 @@ "m_Node": { "m_Id": "d262d084d8a24f75a887851e71acd55c" }, - "m_SlotId": 3 + "m_SlotId": 2 }, "m_InputSlot": { "m_Node": { - "m_Id": "4b7bc34646b04cb7807c181ddfe5eac9" + "m_Id": "ee7cba1ca7b14dd8a840edaa0eaa988a" }, "m_SlotId": 0 } @@ -440,13 +554,13 @@ { "m_OutputSlot": { "m_Node": { - "m_Id": "d4a1cb334c16407da0eb7a4d243196cb" + "m_Id": "d262d084d8a24f75a887851e71acd55c" }, - "m_SlotId": 0 + "m_SlotId": 3 }, "m_InputSlot": { "m_Node": { - "m_Id": "cafe4baf3a264c5f8cf3d57e6b8d567e" + "m_Id": "4b7bc34646b04cb7807c181ddfe5eac9" }, "m_SlotId": 0 } @@ -562,6 +676,20 @@ }, "m_SlotId": 2 } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "fbdf75d73fab4ab19d741189db36eefb" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "7b4a6ad1f8f0484ab1a0fa456cce6f1c" + }, + "m_SlotId": 1 + } } ], "m_VertexContext": { @@ -595,23 +723,6 @@ "m_ActiveTargets": [] } -{ - "m_SGVersion": 0, - "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", - "m_ObjectId": "002f7a37543b4846b92fd8afb6311f3f", - "m_Id": 6, - "m_DisplayName": "B", - "m_SlotType": 1, - "m_Hidden": false, - "m_ShaderOutputName": "B", - "m_StageCapability": 2, - "m_Value": 0.0, - "m_DefaultValue": 0.0, - "m_Labels": [ - "X" - ] -} - { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.MultiplyNode", @@ -674,19 +785,6 @@ "m_Value": false } -{ - "m_SGVersion": 0, - "m_Type": "UnityEditor.ShaderGraph.Texture2DMaterialSlot", - "m_ObjectId": "0acc6e49c6294c598efc84ee69e9c9dd", - "m_Id": 0, - "m_DisplayName": "Normal Map", - "m_SlotType": 1, - "m_Hidden": false, - "m_ShaderOutputName": "Out", - "m_StageCapability": 3, - "m_BareResource": false -} - { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.MultiplyNode", @@ -726,6 +824,30 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "1006650ac09b43d689f0193e9caecf04", + "m_Id": 2, + "m_DisplayName": "False", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "False", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + } +} + { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", @@ -750,6 +872,31 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.UVMaterialSlot", + "m_ObjectId": "12283ba3e0ca466a80accfcb386ddafa", + "m_Id": 2, + "m_DisplayName": "UV", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "UV", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [ + "X", + "Y" + ], + "m_Channel": 0 +} + { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", @@ -919,6 +1066,19 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.SamplerStateMaterialSlot", + "m_ObjectId": "20180b2172364710aca8c3ba90da06d7", + "m_Id": 3, + "m_DisplayName": "Sampler", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Sampler", + "m_StageCapability": 3, + "m_BareResource": false +} + { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", @@ -1037,25 +1197,49 @@ { "m_SGVersion": 0, - "m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot", - "m_ObjectId": "30661deea6f8424caa25ffae6f1b42be", - "m_Id": 1, - "m_DisplayName": "B", + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "2ce6f03f33974059b1f202ac4d03486a", + "m_Id": 0, + "m_DisplayName": "A", "m_SlotType": 0, "m_Hidden": false, - "m_ShaderOutputName": "B", + "m_ShaderOutputName": "A", "m_StageCapability": 3, "m_Value": { - "e00": 2.0, - "e01": 2.0, - "e02": 2.0, - "e03": 2.0, - "e10": 2.0, - "e11": 2.0, - "e12": 2.0, - "e13": 2.0, - "e20": 2.0, - "e21": 2.0, + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot", + "m_ObjectId": "30661deea6f8424caa25ffae6f1b42be", + "m_Id": 1, + "m_DisplayName": "B", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "B", + "m_StageCapability": 3, + "m_Value": { + "e00": 2.0, + "e01": 2.0, + "e02": 2.0, + "e03": 2.0, + "e10": 2.0, + "e11": 2.0, + "e12": 2.0, + "e13": 2.0, + "e20": 2.0, + "e21": 2.0, "e22": 2.0, "e23": 2.0, "e30": 2.0, @@ -1083,6 +1267,23 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "309687172c564016b047f7200ae8fbe8", + "m_Id": 4, + "m_DisplayName": "R", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "R", + "m_StageCapability": 2, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [ + "X" + ] +} + { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", @@ -1109,15 +1310,46 @@ { "m_SGVersion": 0, - "m_Type": "UnityEditor.ShaderGraph.SamplerStateMaterialSlot", - "m_ObjectId": "322a98a3b4d14d99a9f0730bb0893ba1", - "m_Id": 3, - "m_DisplayName": "Sampler", - "m_SlotType": 0, - "m_Hidden": false, - "m_ShaderOutputName": "Sampler", - "m_StageCapability": 3, - "m_BareResource": false + "m_Type": "UnityEditor.ShaderGraph.ComparisonNode", + "m_ObjectId": "333d81460a3445b88019a0a6aa388a7e", + "m_Group": { + "m_Id": "d58da93c92c248cba0b083045eaaccbb" + }, + "m_Name": "Comparison", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -832.8001098632813, + "y": -596.800048828125, + "width": 145.60003662109376, + "height": 134.4000244140625 + } + }, + "m_Slots": [ + { + "m_Id": "ac1eef4d63c4466790c7ef9b25b07cd6" + }, + { + "m_Id": "47dcf3e62a634f83b968c5738e48b57b" + }, + { + "m_Id": "8203a6f798b44147b0c0bf993207187c" + } + ], + "synonyms": [ + "equal", + "greater than", + "less than" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_ComparisonType": 0 } { @@ -1168,6 +1400,21 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "36936a75dfec44debc15803e7c625e58", + "m_Id": 2, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + { "m_SGVersion": 1, "m_Type": "UnityEditor.ShaderGraph.Internal.Vector3ShaderProperty", @@ -1280,6 +1527,21 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "47dcf3e62a634f83b968c5738e48b57b", + "m_Id": 1, + "m_DisplayName": "B", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "B", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.MultiplyNode", @@ -1415,6 +1677,38 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "5246029e9cd64f1798e4ae12d0ee1f2c", + "m_Id": 7, + "m_DisplayName": "A", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "A", + "m_StageCapability": 2, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [ + "X" + ] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "5471c6aca1ff43609297d27872bd2cbb", + "m_Id": 1, + "m_DisplayName": "X", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "X", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.BranchNode", @@ -1568,11 +1862,12 @@ "hlslDeclarationOverride": 0, "m_Hidden": false, "m_Value": { - "m_SerializedTexture": "{\"texture\":{\"instanceID\":0}}", + "m_SerializedTexture": "", "m_Guid": "" }, "isMainTexture": false, "useTilingAndOffset": false, + "useTexelSize": true, "m_Modifiable": true, "m_DefaultType": 0 } @@ -1697,23 +1992,6 @@ } } -{ - "m_SGVersion": 0, - "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", - "m_ObjectId": "603de1984c174d249bc0c7e2a71011d8", - "m_Id": 5, - "m_DisplayName": "G", - "m_SlotType": 1, - "m_Hidden": false, - "m_ShaderOutputName": "G", - "m_StageCapability": 2, - "m_Value": 0.0, - "m_DefaultValue": 0.0, - "m_Labels": [ - "X" - ] -} - { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", @@ -1898,6 +2176,23 @@ "m_Normalize": false } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "706bfcfe5eea4a568c7c1d95d422b24d", + "m_Id": 5, + "m_DisplayName": "G", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "G", + "m_StageCapability": 2, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [ + "X" + ] +} + { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", @@ -1923,14 +2218,14 @@ { "m_SGVersion": 0, - "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", - "m_ObjectId": "74a6c3503f9a413ca1986f90835cea76", - "m_Id": 2, - "m_DisplayName": "Out", + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "71b00b6da2314cba9b46569e2e0ad010", + "m_Id": 0, + "m_DisplayName": "RGBA", "m_SlotType": 1, "m_Hidden": false, - "m_ShaderOutputName": "Out", - "m_StageCapability": 3, + "m_ShaderOutputName": "RGBA", + "m_StageCapability": 2, "m_Value": { "x": 0.0, "y": 0.0, @@ -1942,19 +2237,20 @@ "y": 0.0, "z": 0.0, "w": 0.0 - } + }, + "m_Labels": [] } { "m_SGVersion": 0, - "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", - "m_ObjectId": "7b931cc4e0804b6eafdadab298002052", - "m_Id": 0, - "m_DisplayName": "RGBA", + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "74a6c3503f9a413ca1986f90835cea76", + "m_Id": 2, + "m_DisplayName": "Out", "m_SlotType": 1, "m_Hidden": false, - "m_ShaderOutputName": "RGBA", - "m_StageCapability": 2, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, "m_Value": { "x": 0.0, "y": 0.0, @@ -1966,8 +2262,65 @@ "y": 0.0, "z": 0.0, "w": 0.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.SampleTexture2DNode", + "m_ObjectId": "7b4a6ad1f8f0484ab1a0fa456cce6f1c", + "m_Group": { + "m_Id": "" }, - "m_Labels": [] + "m_Name": "Sample Texture 2D", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1363.2000732421875, + "y": -576.0000610351563, + "width": 183.199951171875, + "height": 248.00003051757813 + } + }, + "m_Slots": [ + { + "m_Id": "71b00b6da2314cba9b46569e2e0ad010" + }, + { + "m_Id": "309687172c564016b047f7200ae8fbe8" + }, + { + "m_Id": "706bfcfe5eea4a568c7c1d95d422b24d" + }, + { + "m_Id": "98aba4059e5b409ba88cc955334b8afd" + }, + { + "m_Id": "5246029e9cd64f1798e4ae12d0ee1f2c" + }, + { + "m_Id": "dfacbd9183e04017a3e4e1aa6ff41ee3" + }, + { + "m_Id": "12283ba3e0ca466a80accfcb386ddafa" + }, + { + "m_Id": "20180b2172364710aca8c3ba90da06d7" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_TextureType": 1, + "m_NormalMapSpace": 0, + "m_EnableGlobalMipBias": true, + "m_MipSamplingMode": 0 } { @@ -1998,6 +2351,29 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "7e00fe8dea22473781700594fe0bc78e", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.BooleanMaterialSlot", @@ -2035,6 +2411,19 @@ "m_Value": false } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Texture2DMaterialSlot", + "m_ObjectId": "81561763e93e4eb9a95c5229e88246dd", + "m_Id": 0, + "m_DisplayName": "Normal Map", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_BareResource": false +} + { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.BooleanMaterialSlot", @@ -2049,6 +2438,20 @@ "m_DefaultValue": false } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BooleanMaterialSlot", + "m_ObjectId": "8203a6f798b44147b0c0bf993207187c", + "m_Id": 2, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": false, + "m_DefaultValue": false +} + { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot", @@ -2112,23 +2515,6 @@ "m_Labels": [] } -{ - "m_SGVersion": 0, - "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", - "m_ObjectId": "84e0d824ec844493ad99fb4e05267c5e", - "m_Id": 4, - "m_DisplayName": "R", - "m_SlotType": 1, - "m_Hidden": false, - "m_ShaderOutputName": "R", - "m_StageCapability": 2, - "m_Value": 0.0, - "m_DefaultValue": 0.0, - "m_Labels": [ - "X" - ] -} - { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", @@ -2169,27 +2555,33 @@ { "m_SGVersion": 0, - "m_Type": "UnityEditor.ShaderGraph.Texture2DInputMaterialSlot", - "m_ObjectId": "8782bfd5631a4f4ea13ed637dd1b22bc", - "m_Id": 1, - "m_DisplayName": "Texture", - "m_SlotType": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "89ed71d7fc264759a9b9a5147408fd23", + "m_Id": 3, + "m_DisplayName": "Out", + "m_SlotType": 1, "m_Hidden": false, - "m_ShaderOutputName": "Texture", + "m_ShaderOutputName": "Out", "m_StageCapability": 3, - "m_BareResource": false, - "m_Texture": { - "m_SerializedTexture": "{\"texture\":{\"instanceID\":0}}", - "m_Guid": "" + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 }, - "m_DefaultType": 3 + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + } } { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", - "m_ObjectId": "89ed71d7fc264759a9b9a5147408fd23", - "m_Id": 3, + "m_ObjectId": "8b05b08875db4904912d204ac0bdc798", + "m_Id": 2, "m_DisplayName": "Out", "m_SlotType": 1, "m_Hidden": false, @@ -2212,8 +2604,8 @@ { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", - "m_ObjectId": "8b05b08875db4904912d204ac0bdc798", - "m_Id": 2, + "m_ObjectId": "8bc91dfcda5b4b418a9266622cb89e39", + "m_Id": 3, "m_DisplayName": "Out", "m_SlotType": 1, "m_Hidden": false, @@ -2381,6 +2773,47 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DotProductNode", + "m_ObjectId": "940efe1fbe1c4282b6ef117cac6dae02", + "m_Group": { + "m_Id": "d58da93c92c248cba0b083045eaaccbb" + }, + "m_Name": "Dot Product", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -976.0001220703125, + "y": -652.0000610351563, + "width": 128.00006103515626, + "height": 117.5999755859375 + } + }, + "m_Slots": [ + { + "m_Id": "2ce6f03f33974059b1f202ac4d03486a" + }, + { + "m_Id": "cd867930068842e5a475e43848bbb44a" + }, + { + "m_Id": "36936a75dfec44debc15803e7c625e58" + } + ], + "synonyms": [ + "scalar product" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", @@ -2432,6 +2865,23 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "98aba4059e5b409ba88cc955334b8afd", + "m_Id": 6, + "m_DisplayName": "B", + "m_SlotType": 1, + "m_Hidden": false, + "m_ShaderOutputName": "B", + "m_StageCapability": 2, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [ + "X" + ] +} + { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.BooleanMaterialSlot", @@ -2454,11 +2904,126 @@ "m_DisplayName": "B", "m_SlotType": 1, "m_Hidden": false, - "m_ShaderOutputName": "B", + "m_ShaderOutputName": "B", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3Node", + "m_ObjectId": "a3a614da9af04ec39f1170d7b782558e", + "m_Group": { + "m_Id": "d58da93c92c248cba0b083045eaaccbb" + }, + "m_Name": "Vector 3", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1125.60009765625, + "y": -551.2000732421875, + "width": 128.00006103515626, + "height": 124.80001831054688 + } + }, + "m_Slots": [ + { + "m_Id": "5471c6aca1ff43609297d27872bd2cbb" + }, + { + "m_Id": "b9eafeeabe584b5eb53b026d75af6c46" + }, + { + "m_Id": "a5f446c654c944eca8037d8a394132ac" + }, + { + "m_Id": "7e00fe8dea22473781700594fe0bc78e" + } + ], + "synonyms": [ + "3", + "v3", + "vec3", + "float3" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "a5f446c654c944eca8037d8a394132ac", + "m_Id": 3, + "m_DisplayName": "Z", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Z", "m_StageCapability": 3, "m_Value": 0.0, "m_DefaultValue": 0.0, - "m_Labels": [] + "m_Labels": [ + "Z" + ] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BranchNode", + "m_ObjectId": "a6957c55b3b54f4d9e52907f1ec73825", + "m_Group": { + "m_Id": "d58da93c92c248cba0b083045eaaccbb" + }, + "m_Name": "Branch", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -657.6000366210938, + "y": -520.0000610351563, + "width": 172.00003051757813, + "height": 141.60000610351563 + } + }, + "m_Slots": [ + { + "m_Id": "e34e18b82636427abcb19eeb42b542b7" + }, + { + "m_Id": "e2d5da32ff504ac1a6f46f28b87a68c7" + }, + { + "m_Id": "1006650ac09b43d689f0193e9caecf04" + }, + { + "m_Id": "8bc91dfcda5b4b418a9266622cb89e39" + } + ], + "synonyms": [ + "switch", + "if", + "else" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } } { @@ -2514,6 +3079,21 @@ "m_DefaultValue": false } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "ac1eef4d63c4466790c7ef9b25b07cd6", + "m_Id": 0, + "m_DisplayName": "A", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "A", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [] +} + { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.BranchNode", @@ -2703,6 +3283,23 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "b9eafeeabe584b5eb53b026d75af6c46", + "m_Id": 2, + "m_DisplayName": "Y", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Y", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [ + "Y" + ] +} + { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.BooleanMaterialSlot", @@ -2717,42 +3314,6 @@ "m_DefaultValue": false } -{ - "m_SGVersion": 0, - "m_Type": "UnityEditor.ShaderGraph.PropertyNode", - "m_ObjectId": "bc90282dda9f4917a7bae0c6aeb470d3", - "m_Group": { - "m_Id": "" - }, - "m_Name": "Property", - "m_DrawState": { - "m_Expanded": true, - "m_Position": { - "serializedVersion": "2", - "x": -796.6666870117188, - "y": -371.9999694824219, - "width": 150.66668701171876, - "height": 34.0 - } - }, - "m_Slots": [ - { - "m_Id": "0acc6e49c6294c598efc84ee69e9c9dd" - } - ], - "synonyms": [], - "m_Precision": 0, - "m_PreviewExpanded": true, - "m_DismissedVersion": 0, - "m_PreviewMode": 0, - "m_CustomColors": { - "m_SerializableColors": [] - }, - "m_Property": { - "m_Id": "5b808e0093204fd897a601b2c2a41aa1" - } -} - { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", @@ -2903,19 +3464,26 @@ { "m_SGVersion": 0, - "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", - "m_ObjectId": "cecd7886bb03424eb179cdcd9d68ae49", - "m_Id": 7, - "m_DisplayName": "A", - "m_SlotType": 1, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "cd867930068842e5a475e43848bbb44a", + "m_Id": 1, + "m_DisplayName": "B", + "m_SlotType": 0, "m_Hidden": false, - "m_ShaderOutputName": "A", - "m_StageCapability": 2, - "m_Value": 0.0, - "m_DefaultValue": 0.0, - "m_Labels": [ - "X" - ] + "m_ShaderOutputName": "B", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 1.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + } } { @@ -3000,64 +3568,6 @@ "IsFirstSlotValid": true } -{ - "m_SGVersion": 0, - "m_Type": "UnityEditor.ShaderGraph.SampleTexture2DNode", - "m_ObjectId": "d4a1cb334c16407da0eb7a4d243196cb", - "m_Group": { - "m_Id": "" - }, - "m_Name": "Sample Texture 2D", - "m_DrawState": { - "m_Expanded": true, - "m_Position": { - "serializedVersion": "2", - "x": -639.3331298828125, - "y": -411.5, - "width": 186.66661071777345, - "height": 251.3333282470703 - } - }, - "m_Slots": [ - { - "m_Id": "7b931cc4e0804b6eafdadab298002052" - }, - { - "m_Id": "84e0d824ec844493ad99fb4e05267c5e" - }, - { - "m_Id": "603de1984c174d249bc0c7e2a71011d8" - }, - { - "m_Id": "002f7a37543b4846b92fd8afb6311f3f" - }, - { - "m_Id": "cecd7886bb03424eb179cdcd9d68ae49" - }, - { - "m_Id": "8782bfd5631a4f4ea13ed637dd1b22bc" - }, - { - "m_Id": "e825d5d78e7e41fc8ce09bf1b1701776" - }, - { - "m_Id": "322a98a3b4d14d99a9f0730bb0893ba1" - } - ], - "synonyms": [], - "m_Precision": 0, - "m_PreviewExpanded": false, - "m_DismissedVersion": 0, - "m_PreviewMode": 0, - "m_CustomColors": { - "m_SerializableColors": [] - }, - "m_TextureType": 1, - "m_NormalMapSpace": 0, - "m_EnableGlobalMipBias": true, - "m_MipSamplingMode": 0 -} - { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot", @@ -3106,6 +3616,17 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.GroupData", + "m_ObjectId": "d58da93c92c248cba0b083045eaaccbb", + "m_Title": "Handle Normal Map (0,0,0) samples due to compression and downsampling", + "m_Position": { + "x": -1151.2000732421875, + "y": -712.0 + } +} + { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.IsFrontFaceNode", @@ -3139,6 +3660,24 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Texture2DInputMaterialSlot", + "m_ObjectId": "dfacbd9183e04017a3e4e1aa6ff41ee3", + "m_Id": 1, + "m_DisplayName": "Texture", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Texture", + "m_StageCapability": 3, + "m_BareResource": false, + "m_Texture": { + "m_SerializedTexture": "", + "m_Guid": "" + }, + "m_DefaultType": 3 +} + { "m_SGVersion": 0, "m_Type": "UnityEditor.ShaderGraph.PropertyNode", @@ -3330,27 +3869,40 @@ { "m_SGVersion": 0, - "m_Type": "UnityEditor.ShaderGraph.UVMaterialSlot", - "m_ObjectId": "e825d5d78e7e41fc8ce09bf1b1701776", - "m_Id": 2, - "m_DisplayName": "UV", + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "e2d5da32ff504ac1a6f46f28b87a68c7", + "m_Id": 1, + "m_DisplayName": "True", "m_SlotType": 0, "m_Hidden": false, - "m_ShaderOutputName": "UV", + "m_ShaderOutputName": "True", "m_StageCapability": 3, "m_Value": { "x": 0.0, - "y": 0.0 + "y": 0.0, + "z": 1.0, + "w": 1.0 }, "m_DefaultValue": { "x": 0.0, - "y": 0.0 - }, - "m_Labels": [ - "X", - "Y" - ], - "m_Channel": 0 + "y": 0.0, + "z": 0.0, + "w": 0.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BooleanMaterialSlot", + "m_ObjectId": "e34e18b82636427abcb19eeb42b542b7", + "m_Id": 0, + "m_DisplayName": "Predicate", + "m_SlotType": 0, + "m_Hidden": false, + "m_ShaderOutputName": "Predicate", + "m_StageCapability": 3, + "m_Value": false, + "m_DefaultValue": false } { @@ -3596,3 +4148,39 @@ } } +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PropertyNode", + "m_ObjectId": "fbdf75d73fab4ab19d741189db36eefb", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Property", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1524.0001220703125, + "y": -549.6000366210938, + "width": 147.199951171875, + "height": 33.5999755859375 + } + }, + "m_Slots": [ + { + "m_Id": "81561763e93e4eb9a95c5229e88246dd" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Property": { + "m_Id": "5b808e0093204fd897a601b2c2a41aa1" + } +} + diff --git a/Packages/com.unity.shadergraph/package.json b/Packages/com.unity.shadergraph/package.json index dd6928a7..51d35748 100644 --- a/Packages/com.unity.shadergraph/package.json +++ b/Packages/com.unity.shadergraph/package.json @@ -1,11 +1,11 @@ { "name": "com.unity.shadergraph", "description": "The Shader Graph package adds a visual Shader editing tool to Unity. You can use this tool to create Shaders in a visual way instead of writing code. Specific render pipelines can implement specific graph features. Currently, both the High Definition Rendering Pipeline and the Universal Rendering Pipeline support Shader Graph.", - "version": "17.0.4", - "unity": "6000.0", + "version": "17.1.0", + "unity": "6000.1", "displayName": "Shader Graph", "dependencies": { - "com.unity.render-pipelines.core": "17.0.4", + "com.unity.render-pipelines.core": "17.1.0", "com.unity.searcher": "4.9.3" }, "samples": [ @@ -43,5 +43,5 @@ "path": "Samples~/UGUIShaders" } ], - "_fingerprint": "425e21ee5890a7be1fc569c29e55bc023ce57d08" + "_fingerprint": "eb9759d45cf8efe237ec67f5c7c6880261fd59c4" } diff --git a/Packages/com.unity.ugui/Editor/TMP/TMP_InputFieldEditor.cs b/Packages/com.unity.ugui/Editor/TMP/TMP_InputFieldEditor.cs index 6f572241..f2278310 100644 --- a/Packages/com.unity.ugui/Editor/TMP/TMP_InputFieldEditor.cs +++ b/Packages/com.unity.ugui/Editor/TMP/TMP_InputFieldEditor.cs @@ -260,11 +260,11 @@ namespace TMPro.EditorUtilities EditorGUI.indentLevel++; EditorGUILayout.PropertyField(m_OnFocusSelectAll, new GUIContent("OnFocus - Select All", "Should all the text be selected when the Input Field is selected?")); - EditorGUILayout.PropertyField(m_ResetOnDeActivation, new GUIContent("Reset On Deactivation", "Should the Text and Caret position be reset when Input Field looses focus and is Deactivated?")); + EditorGUILayout.PropertyField(m_ResetOnDeActivation, new GUIContent("Reset On Deactivation", "Should the Text and Caret position be reset when Input Field loses focus and is Deactivated?")); EditorGUI.indentLevel++; GUI.enabled = !m_ResetOnDeActivation.boolValue; - EditorGUILayout.PropertyField(m_KeepTextSelectionVisible, new GUIContent("Keep Text Selection Visible", "Should the text selection remain visible when the input field looses focus and is deactivated?")); + EditorGUILayout.PropertyField(m_KeepTextSelectionVisible, new GUIContent("Keep Text Selection Visible", "Should the text selection remain visible when the input field loses focus and is deactivated?")); GUI.enabled = true; EditorGUI.indentLevel--; diff --git a/Packages/com.unity.ugui/Editor/TMP/TMPro_FontAssetCreatorWindow.cs b/Packages/com.unity.ugui/Editor/TMP/TMPro_FontAssetCreatorWindow.cs index 001203e7..441d14cb 100644 --- a/Packages/com.unity.ugui/Editor/TMP/TMPro_FontAssetCreatorWindow.cs +++ b/Packages/com.unity.ugui/Editor/TMP/TMPro_FontAssetCreatorWindow.cs @@ -720,7 +720,7 @@ namespace TMPro.EditorUtilities if (errorCode != FontEngineError.Success) { - Debug.Log("Font Asset Creator - Error Code [" + errorCode + "] has occurred trying to load the [" + m_SourceFont.name + "] font file. This typically results from the use of an incompatible or corrupted font file.", m_SourceFont); + Debug.LogWarning("Unable to load font face for [" + m_SourceFont.name + "]. Make sure \"Include Font Data\" is enabled in the Font Import Settings. You may disable it after creating the static Font Asset.", m_SourceFont); } } diff --git a/Packages/com.unity.ugui/Editor/TMP/Unity.TextMeshPro.Editor.asmdef b/Packages/com.unity.ugui/Editor/TMP/Unity.TextMeshPro.Editor.asmdef index 9f2e2561..73cf18fb 100644 --- a/Packages/com.unity.ugui/Editor/TMP/Unity.TextMeshPro.Editor.asmdef +++ b/Packages/com.unity.ugui/Editor/TMP/Unity.TextMeshPro.Editor.asmdef @@ -39,4 +39,4 @@ } ], "noEngineReferences": false -} \ No newline at end of file +} diff --git a/Packages/com.unity.ugui/Package Resources/TMP Examples & Extras.unitypackage b/Packages/com.unity.ugui/Package Resources/TMP Examples & Extras.unitypackage index f0fa3eb3..99f25793 100644 --- a/Packages/com.unity.ugui/Package Resources/TMP Examples & Extras.unitypackage +++ b/Packages/com.unity.ugui/Package Resources/TMP Examples & Extras.unitypackage @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7a963b3b2fdc78bd96b04b9a2e31b28f463bbbb38fd3963667a964746fe18fb8 -size 2120925 +oid sha256:d4091e271f4e93f1cf42bad0ad92d9d347f4cb603200daafdcd484a83f6c2df0 +size 2108788 diff --git a/Packages/com.unity.ugui/Runtime/TMP/TMP_FontAssetUtilities.cs b/Packages/com.unity.ugui/Runtime/TMP/TMP_FontAssetUtilities.cs index 544b1b9a..ffe5244b 100644 --- a/Packages/com.unity.ugui/Runtime/TMP/TMP_FontAssetUtilities.cs +++ b/Packages/com.unity.ugui/Runtime/TMP/TMP_FontAssetUtilities.cs @@ -73,25 +73,14 @@ namespace TMPro if (isItalic || fontWeight != FontWeight.Regular) { - // Check if character is already cached using the composite unicode value the takes into consideration the font style and weight + // Check if character is already cached using the composite Unicode value the takes into consideration the font style and weight uint compositeUnicodeLookupKey = ((0x80u | ((uint)fontStyle << 4) | ((uint)fontWeight / 100)) << 24) | unicode; if (sourceFontAsset.characterLookupTable.TryGetValue(compositeUnicodeLookupKey, out character)) { // Set isAlternativeTypeface isAlternativeTypeface = true; - if (character.textAsset is not null) - return character; - - // Remove character from lookup table - sourceFontAsset.characterLookupTable.Remove(unicode); - } - else if (sourceFontAsset.characterLookupTable.TryGetValue(compositeUnicodeLookupKey & 0x7FFFFFFF, out character)) - { - // Set isAlternativeTypeface - isAlternativeTypeface = false; - - if (character.textAsset is not null) + if (character.textAsset != null) return character; // Remove character from lookup table @@ -139,7 +128,7 @@ namespace TMPro { if (temp.characterLookupTable.TryGetValue(unicode, out character)) { - if (character.textAsset is not null) + if (character.textAsset != null) { isAlternativeTypeface = true; return character; @@ -171,7 +160,7 @@ namespace TMPro // Search the source font asset for the requested character if (sourceFontAsset.characterLookupTable.TryGetValue(unicode, out character)) { - if (character.textAsset is not null) + if (character.textAsset != null) return character; // Remove character from lookup table diff --git a/Packages/com.unity.ugui/Runtime/TMP/TMP_InputField.cs b/Packages/com.unity.ugui/Runtime/TMP/TMP_InputField.cs index 4dffdd31..6a8abaaf 100644 --- a/Packages/com.unity.ugui/Runtime/TMP/TMP_InputField.cs +++ b/Packages/com.unity.ugui/Runtime/TMP/TMP_InputField.cs @@ -1538,6 +1538,7 @@ namespace TMPro switch (platform) { case RuntimePlatform.Android: + case RuntimePlatform.WebGLPlayer: if (s_IsQuestDevice) return TouchScreenKeyboard.isSupported; @@ -3347,7 +3348,7 @@ namespace TMPro // Can't go past the character limit if (characterLimit > 0 && text.Length >= characterLimit) return; - + m_Text = text.Insert(m_StringPosition, replaceString); if (!char.IsHighSurrogate(c)) @@ -4191,6 +4192,9 @@ namespace TMPro var separator = Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator; if (ch == Convert.ToChar(separator) && characterValidation == CharacterValidation.Decimal && !text.Contains(separator)) return ch; + + //Some keyboards including Samsung require double tapping a . to get a - this allows these keyboards to input negative integers + if (characterValidation == CharacterValidation.Integer && ch == '.' && (pos == 0 || selectionAtStart)) return '-'; } } else if (characterValidation == CharacterValidation.Digit) @@ -4523,7 +4527,7 @@ namespace TMPro { m_LineType = LineType.SingleLine; m_InputType = InputType.Standard; - m_KeyboardType = TouchScreenKeyboardType.NumberPad; + m_KeyboardType = TouchScreenKeyboardType.NumbersAndPunctuation; m_CharacterValidation = CharacterValidation.Integer; break; } diff --git a/Packages/com.unity.ugui/Runtime/TMP/TMP_InputValidator.cs b/Packages/com.unity.ugui/Runtime/TMP/TMP_InputValidator.cs index 026766a2..2fff19f8 100644 --- a/Packages/com.unity.ugui/Runtime/TMP/TMP_InputValidator.cs +++ b/Packages/com.unity.ugui/Runtime/TMP/TMP_InputValidator.cs @@ -10,6 +10,13 @@ namespace TMPro [System.Serializable] public abstract class TMP_InputValidator : ScriptableObject { + /// + /// Customs text input validation function. + /// + /// The original text + /// The position in the string to add the caharcter + /// The character to add + /// The character added public abstract char Validate(ref string text, ref int pos, char ch); } } diff --git a/Packages/com.unity.ugui/Runtime/TMP/TMP_Text.cs b/Packages/com.unity.ugui/Runtime/TMP/TMP_Text.cs index 6b0b1f35..80294a56 100644 --- a/Packages/com.unity.ugui/Runtime/TMP/TMP_Text.cs +++ b/Packages/com.unity.ugui/Runtime/TMP/TMP_Text.cs @@ -2977,7 +2977,13 @@ namespace TMPro if (ReplaceOpeningStyleTag(ref styleDefinition, i, out int offset, ref charBuffer, ref writeIndex)) { + int remainChar = styleLength - offset; i = offset; + + //Increase the buffer if the buffer might overflow after processing styles. + if ( writeIndex + remainChar >= charBuffer.Length) + ResizeInternalArray(ref charBuffer, writeIndex + remainChar); + continue; } break; @@ -6180,7 +6186,7 @@ namespace TMPro if (character != null) { // Add character to font asset lookup cache - fontAsset.AddCharacterToLookupCache(unicode, character, fontStyle, fontWeight, isUsingAlternativeTypeface); + fontAsset.AddCharacterToLookupCache(unicode, character, FontStyles.Normal, FontWeight.Regular, isUsingAlternativeTypeface); return character; } @@ -6192,7 +6198,7 @@ namespace TMPro if (character != null) { // Add character to font asset lookup cache - fontAsset.AddCharacterToLookupCache(unicode, character, fontStyle, fontWeight, isUsingAlternativeTypeface); + fontAsset.AddCharacterToLookupCache(unicode, character, FontStyles.Normal, FontWeight.Regular, isUsingAlternativeTypeface); return character; } @@ -6204,7 +6210,7 @@ namespace TMPro if (character != null) { // Add character to font asset lookup cache - fontAsset.AddCharacterToLookupCache(unicode, character, fontStyle, fontWeight, isUsingAlternativeTypeface); + fontAsset.AddCharacterToLookupCache(unicode, character, FontStyles.Normal, FontWeight.Regular, isUsingAlternativeTypeface); return character; } @@ -7132,6 +7138,7 @@ namespace TMPro case MarkupTag.SUBSCRIPT: m_fontScaleMultiplier *= m_currentFontAsset.faceInfo.subscriptSize > 0 ? m_currentFontAsset.faceInfo.subscriptSize : 1; m_baselineOffsetStack.Push(m_baselineOffset); + m_materialReferenceStack.Push(m_materialReferences[m_currentMaterialIndex]); fontScale = (m_currentFontSize / m_currentFontAsset.faceInfo.pointSize * m_currentFontAsset.faceInfo.scale * (m_isOrthographic ? 1 : 0.1f)); m_baselineOffset += m_currentFontAsset.faceInfo.subscriptOffset * fontScale * m_fontScaleMultiplier; @@ -7141,10 +7148,11 @@ namespace TMPro case MarkupTag.SLASH_SUBSCRIPT: if ((m_FontStyleInternal & FontStyles.Subscript) == FontStyles.Subscript) { + var previousFontAsset = m_materialReferenceStack.Pop().fontAsset; if (m_fontScaleMultiplier < 1) { m_baselineOffset = m_baselineOffsetStack.Pop(); - m_fontScaleMultiplier /= m_currentFontAsset.faceInfo.subscriptSize > 0 ? m_currentFontAsset.faceInfo.subscriptSize : 1; + m_fontScaleMultiplier /= previousFontAsset.faceInfo.subscriptSize > 0 ? previousFontAsset.faceInfo.subscriptSize : 1; } if (m_fontStyleStack.Remove(FontStyles.Subscript) == 0) @@ -7154,6 +7162,7 @@ namespace TMPro case MarkupTag.SUPERSCRIPT: m_fontScaleMultiplier *= m_currentFontAsset.faceInfo.superscriptSize > 0 ? m_currentFontAsset.faceInfo.superscriptSize : 1; m_baselineOffsetStack.Push(m_baselineOffset); + m_materialReferenceStack.Push(m_materialReferences[m_currentMaterialIndex]); fontScale = (m_currentFontSize / m_currentFontAsset.faceInfo.pointSize * m_currentFontAsset.faceInfo.scale * (m_isOrthographic ? 1 : 0.1f)); m_baselineOffset += m_currentFontAsset.faceInfo.superscriptOffset * fontScale * m_fontScaleMultiplier; @@ -7163,10 +7172,11 @@ namespace TMPro case MarkupTag.SLASH_SUPERSCRIPT: if ((m_FontStyleInternal & FontStyles.Superscript) == FontStyles.Superscript) { + var previousFontAsset = m_materialReferenceStack.Pop().fontAsset; if (m_fontScaleMultiplier < 1) { m_baselineOffset = m_baselineOffsetStack.Pop(); - m_fontScaleMultiplier /= m_currentFontAsset.faceInfo.superscriptSize > 0 ? m_currentFontAsset.faceInfo.superscriptSize : 1; + m_fontScaleMultiplier /= previousFontAsset.faceInfo.superscriptSize > 0 ? previousFontAsset.faceInfo.superscriptSize : 1; } if (m_fontStyleStack.Remove(FontStyles.Superscript) == 0) diff --git a/Packages/com.unity.ugui/Runtime/TMP/TMP_TextUtilities.cs b/Packages/com.unity.ugui/Runtime/TMP/TMP_TextUtilities.cs index 843f9900..f9e76e49 100644 --- a/Packages/com.unity.ugui/Runtime/TMP/TMP_TextUtilities.cs +++ b/Packages/com.unity.ugui/Runtime/TMP/TMP_TextUtilities.cs @@ -321,6 +321,7 @@ namespace TMPro /// /// Function returning the index of the character at the given position (if any). + /// Returns @@-1@@ if no character is found at the specified position. /// /// A reference to the TextMeshPro component. /// Position to check for intersection. diff --git a/Packages/com.unity.ugui/Runtime/TMP/TextMeshPro.cs b/Packages/com.unity.ugui/Runtime/TMP/TextMeshPro.cs index 05abff22..85a84cdc 100644 --- a/Packages/com.unity.ugui/Runtime/TMP/TextMeshPro.cs +++ b/Packages/com.unity.ugui/Runtime/TMP/TextMeshPro.cs @@ -477,6 +477,9 @@ namespace TMPro } } + /// + /// Loads either the default font or a newly assigned font asset, and assigns the appropriate material to the renderer. + /// public void UpdateFontAsset() { LoadFontAsset(); @@ -1700,7 +1703,7 @@ namespace TMPro { isUsingFallbackOrAlternativeTypeface = true; m_currentFontAsset = character.textAsset as TMP_FontAsset; - m_currentMaterialIndex = MaterialReference.AddMaterialReference(m_currentFontAsset.material, m_currentFontAsset, ref m_materialReferences, m_materialReferenceIndexLookup); + //m_currentMaterialIndex = MaterialReference.AddMaterialReference(m_currentFontAsset.material, m_currentFontAsset, ref m_materialReferences, m_materialReferenceIndexLookup); } #region VARIATION SELECTOR diff --git a/Packages/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs b/Packages/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs index 1bfb4740..a007e907 100644 --- a/Packages/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs +++ b/Packages/com.unity.ugui/Runtime/TMP/TextMeshProUGUI.cs @@ -2015,7 +2015,7 @@ namespace TMPro { isUsingFallbackOrAlternativeTypeface = true; m_currentFontAsset = character.textAsset as TMP_FontAsset; - m_currentMaterialIndex = MaterialReference.AddMaterialReference(m_currentFontAsset.material, m_currentFontAsset, ref m_materialReferences, m_materialReferenceIndexLookup); + //m_currentMaterialIndex = MaterialReference.AddMaterialReference(m_currentFontAsset.material, m_currentFontAsset, ref m_materialReferences, m_materialReferenceIndexLookup); } #region VARIATION SELECTOR @@ -2379,7 +2379,7 @@ namespace TMPro // Check if Canvas scale factor has changed as this requires an update of the SDF Scale. bool hasCanvasScaleFactorChanged = false; - if (m_canvas != null && m_CanvasScaleFactor != m_canvas.scaleFactor) + if (m_canvas != null && !Mathf.Approximately(m_CanvasScaleFactor, m_canvas.scaleFactor)) { m_CanvasScaleFactor = m_canvas.scaleFactor; hasCanvasScaleFactorChanged = true; diff --git a/Packages/com.unity.ugui/Runtime/UGUI/EventSystem/EventData/PointerEventData.cs b/Packages/com.unity.ugui/Runtime/UGUI/EventSystem/EventData/PointerEventData.cs index 84f052f6..38f2c64f 100644 --- a/Packages/com.unity.ugui/Runtime/UGUI/EventSystem/EventData/PointerEventData.cs +++ b/Packages/com.unity.ugui/Runtime/UGUI/EventSystem/EventData/PointerEventData.cs @@ -229,7 +229,7 @@ namespace UnityEngine.EventSystems /// public float twist { get; set; } /// - /// Specifies the angle of the pen relative to the X & Y axis, in radians. + /// Specifies the angle of the pen relative to the X & Y axis, in radians. /// /// public Vector2 tilt { get; set; } diff --git a/Packages/com.unity.ugui/Runtime/UGUI/EventSystem/InputModules/BaseInputModule.cs b/Packages/com.unity.ugui/Runtime/UGUI/EventSystem/InputModules/BaseInputModule.cs index 9d877562..cfcdf03a 100644 --- a/Packages/com.unity.ugui/Runtime/UGUI/EventSystem/InputModules/BaseInputModule.cs +++ b/Packages/com.unity.ugui/Runtime/UGUI/EventSystem/InputModules/BaseInputModule.cs @@ -406,5 +406,59 @@ namespace UnityEngine.EventSystems { return scrollDelta / input.mouseScrollDeltaPerTick; } + + /// + /// Returns the type of device that generated this event. + /// + /// + /// This method is used by UI Toolkit's TextField to allow navigation in and out + /// of the TextField when using a device other than a keyboard. + /// + /// If we don't know what the source of the event is, this method should return Unknown. + /// Input Modules with more information on the event source should override this method + /// to reflect that information. + /// + /// This method's behavior is undefined for events other than Move, Submit, or Cancel. + /// + /// An event generated by this input module. + /// The type of device that generated this event. + public virtual NavigationDeviceType GetNavigationEventDeviceType(BaseEventData eventData) + { + return NavigationDeviceType.Unknown; + } + } + + /// + /// The type of device that generated a navigation event. + /// + /// + /// This can help avoid duplicated treatment of events when some controls react to keyboard input + /// and navigation events at the same time. + /// + public enum NavigationDeviceType + { + /// + /// Indicates that no specific information is known about this device. + /// + /// + /// Controls reacting to navigation events from an unknown device should react conservatively. + /// For example, if there is a conflict between a keyboard event and a subsequent navigation event, + /// a control could assume that the device type is a keyboard and conservatively block the navigation event. + /// + Unknown = 0, + /// + /// Indicates that this device is known to be a keyboard. + /// + /// + /// This device sends keyboard events along with any navigation event it generates. + /// + Keyboard, + /// + /// Indicates that this device is anything else than a keyboard (it could be a Gamepad, for example). + /// + /// + /// This device never sends keyboard events along with any navigation event it generates. + /// + NonKeyboard } } diff --git a/Packages/com.unity.ugui/Runtime/UGUI/EventSystem/UIElements/PanelEventHandler.cs b/Packages/com.unity.ugui/Runtime/UGUI/EventSystem/UIElements/PanelEventHandler.cs index daf7de38..62b1f796 100644 --- a/Packages/com.unity.ugui/Runtime/UGUI/EventSystem/UIElements/PanelEventHandler.cs +++ b/Packages/com.unity.ugui/Runtime/UGUI/EventSystem/UIElements/PanelEventHandler.cs @@ -205,7 +205,7 @@ namespace UnityEngine.UIElements var target = currentFocusedElement ?? m_Panel.visualTree; ProcessImguiEvents(target); - using (var e = NavigationSubmitEvent.GetPooled(s_Modifiers)) + using (var e = NavigationSubmitEvent.GetPooled(GetDeviceType(eventData), s_Modifiers)) { e.target = target; SendEvent(e, eventData); @@ -221,7 +221,7 @@ namespace UnityEngine.UIElements var target = currentFocusedElement ?? m_Panel.visualTree; ProcessImguiEvents(target); - using (var e = NavigationCancelEvent.GetPooled(s_Modifiers)) + using (var e = NavigationCancelEvent.GetPooled(GetDeviceType(eventData), s_Modifiers)) { e.target = target; SendEvent(e, eventData); @@ -237,7 +237,7 @@ namespace UnityEngine.UIElements var target = currentFocusedElement ?? m_Panel.visualTree; ProcessImguiEvents(target); - using (var e = NavigationMoveEvent.GetPooled(eventData.moveVector, s_Modifiers)) + using (var e = NavigationMoveEvent.GetPooled(eventData.moveVector, GetDeviceType(eventData), s_Modifiers)) { e.target = target; SendEvent(e, eventData); @@ -388,6 +388,14 @@ namespace UnityEngine.UIElements return true; } + private UIElements.NavigationDeviceType GetDeviceType(BaseEventData eventData) + { + if (eventSystem == null || eventSystem.currentInputModule == null) + return NavigationDeviceType.Unknown; + return (UIElements.NavigationDeviceType)eventSystem.currentInputModule.GetNavigationEventDeviceType( + eventData); + } + enum PointerEventType { Default, Down, Up @@ -448,7 +456,14 @@ namespace UnityEngine.UIElements int eventDisplayIndex = (int)eventPosition.z; if (eventDisplayIndex > 0 && eventDisplayIndex < Display.displays.Length) + { +#if UNITY_ANDROID + // Changed for UITK to be coherent for Android which passes display-relative rendering coordinates + h = Display.displays[eventDisplayIndex].renderingHeight; +#else h = Display.displays[eventDisplayIndex].systemHeight; +#endif + } var delta = eventData.delta; eventPosition.y = h - eventPosition.y; diff --git a/Packages/com.unity.ugui/Runtime/UGUI/EventSystem/UIElements/PanelRaycaster.cs b/Packages/com.unity.ugui/Runtime/UGUI/EventSystem/UIElements/PanelRaycaster.cs index 4d3c2b7c..5c8436f4 100644 --- a/Packages/com.unity.ugui/Runtime/UGUI/EventSystem/UIElements/PanelRaycaster.cs +++ b/Packages/com.unity.ugui/Runtime/UGUI/EventSystem/UIElements/PanelRaycaster.cs @@ -81,7 +81,12 @@ namespace UnityEngine.UIElements float h = Screen.height; if (displayIndex > 0 && displayIndex < Display.displays.Length) { - h = Display.displays[displayIndex].systemHeight; +#if UNITY_ANDROID + // Changed for UITK to be coherent for Android which passes display-relative rendering coordinates + h = Display.displays[displayIndex].renderingHeight; +#else + h = Display.displays[displayIndex].systemHeight; +#endif } position.y = h - position.y; @@ -105,7 +110,7 @@ namespace UnityEngine.UIElements if (!m_Panel.ScreenToPanel(position, delta, out var panelPosition, out _)) return; - var pick = m_Panel.Pick(panelPosition); + var pick = m_Panel.Pick(panelPosition, pointerId); if (pick == null) return; } diff --git a/Packages/com.unity.ugui/Runtime/UGUI/UI/Core/GraphicRaycaster.cs b/Packages/com.unity.ugui/Runtime/UGUI/UI/Core/GraphicRaycaster.cs index d591c2e7..91269435 100644 --- a/Packages/com.unity.ugui/Runtime/UGUI/UI/Core/GraphicRaycaster.cs +++ b/Packages/com.unity.ugui/Runtime/UGUI/UI/Core/GraphicRaycaster.cs @@ -157,8 +157,14 @@ namespace UnityEngine.UI float h = Screen.height; if (displayIndex > 0 && displayIndex < Display.displays.Length) { +#if UNITY_ANDROID + // Changed to be coherent for Android which passes display-relative rendering coordinates + w = Display.displays[displayIndex].renderingWidth; + h = Display.displays[displayIndex].renderingHeight; +#else w = Display.displays[displayIndex].systemWidth; h = Display.displays[displayIndex].systemHeight; +#endif } pos = new Vector2(eventPosition.x / w, eventPosition.y / h); } diff --git a/Packages/com.unity.ugui/Runtime/UGUI/UI/Core/Image.cs b/Packages/com.unity.ugui/Runtime/UGUI/UI/Core/Image.cs index 79d04ca9..abdb7060 100644 --- a/Packages/com.unity.ugui/Runtime/UGUI/UI/Core/Image.cs +++ b/Packages/com.unity.ugui/Runtime/UGUI/UI/Core/Image.cs @@ -285,7 +285,7 @@ namespace UnityEngine.UI if (m_Sprite != value) { m_SkipLayoutUpdate = m_Sprite.rect.size.Equals(value ? value.rect.size : Vector2.zero); - m_SkipMaterialUpdate = m_Sprite.texture == (value ? value.texture : null); + m_SkipMaterialUpdate = (m_Sprite.texture == (value ? value.texture : null)) && !CheckSecondaryTexturesChanged(value); m_Sprite = value; ResetAlphaHitThresholdIfNeeded(); @@ -296,7 +296,7 @@ namespace UnityEngine.UI else if (value != null) { m_SkipLayoutUpdate = value.rect.size == Vector2.zero; - m_SkipMaterialUpdate = value.texture == null; + m_SkipMaterialUpdate = (value.texture == null) && (value.GetSecondaryTextureCount() == 0); m_Sprite = value; ResetAlphaHitThresholdIfNeeded(); @@ -930,6 +930,96 @@ namespace UnityEngine.UI UnTrackImage(this); } + static SecondarySpriteTexture[] s_TempNewSecondaryTextures = {}; + SecondarySpriteTexture [] m_SecondaryTextures; + + internal SecondarySpriteTexture [] secondaryTextures => m_SecondaryTextures; // Internal for testing only + + static void ClearArray(SecondarySpriteTexture[] array) + { + Array.Resize(ref array, 0); + } + + bool CheckSecondaryTexturesChanged(Sprite sprite) + { + var changed = CheckSecondaryTexturesChanged(sprite, ref s_TempNewSecondaryTextures); + ClearArray(s_TempNewSecondaryTextures); + return changed; + } + + bool CheckSecondaryTexturesChanged(Sprite sprite, ref SecondarySpriteTexture [] newSecondaryTextures) + { + newSecondaryTextures ??= new SecondarySpriteTexture[0]; + + bool Compare(SecondarySpriteTexture[] array1, SecondarySpriteTexture[] array2) + { + if (array1.Length != array2.Length) + return false; + + for (var i = 0; i < array1.Length; ++i) + { + if (array1[i] != array2[i]) + return false; + } + + return true; + } + + var oldSecondaryTexCount = m_SecondaryTextures == null ? 0 : m_SecondaryTextures.Length; + var newSecondaryTexCount = sprite != null ? sprite.GetSecondaryTextureCount() : 0; + + // If the secondary texture count remained 0 then return + if (oldSecondaryTexCount == 0 && newSecondaryTexCount == 0) + return false; + + if (sprite != null) + { + Array.Resize(ref newSecondaryTextures, newSecondaryTexCount); + sprite.GetSecondaryTextures(newSecondaryTextures); + } + else + { + ClearArray(newSecondaryTextures); + } + + // If the list of secondary textures has not changed then return + if (m_SecondaryTextures != null && Compare(m_SecondaryTextures, newSecondaryTextures)) + return false; + + return true; + } + + internal void SetSecondaryTextures(CanvasRenderer renderer) + { + if (CheckSecondaryTexturesChanged(activeSprite, ref s_TempNewSecondaryTextures)) + { + if (s_TempNewSecondaryTextures.Length == 0) + m_SecondaryTextures = null; + else + { + if (m_SecondaryTextures == null) + m_SecondaryTextures = new SecondarySpriteTexture[s_TempNewSecondaryTextures.Length]; + else + Array.Resize(ref m_SecondaryTextures, s_TempNewSecondaryTextures.Length); + Array.Copy(s_TempNewSecondaryTextures, m_SecondaryTextures, s_TempNewSecondaryTextures.Length); + } + } + + renderer.SetSecondaryTextureCount(m_SecondaryTextures?.Length ?? 0); + + if (m_SecondaryTextures != null) + { + for (var i = 0; i < m_SecondaryTextures.Length; ++i) + { + var secondaryTex = m_SecondaryTextures[i]; + + renderer.SetSecondaryTexture(i, secondaryTex.name, secondaryTex.texture); + } + } + + ClearArray(s_TempNewSecondaryTextures); + } + /// /// Update the renderer's material. /// @@ -952,6 +1042,8 @@ namespace UnityEngine.UI { canvasRenderer.SetAlphaTexture(alphaTex); } + + SetSecondaryTextures(canvasRenderer); } protected override void OnCanvasHierarchyChanged() @@ -1926,7 +2018,6 @@ namespace UnityEngine.UI base.OnValidate(); m_PixelsPerUnitMultiplier = Mathf.Max(0.01f, m_PixelsPerUnitMultiplier); } - #endif } } diff --git a/Packages/com.unity.ugui/Runtime/UGUI/UI/Core/InputField.cs b/Packages/com.unity.ugui/Runtime/UGUI/UI/Core/InputField.cs index 7372559b..827e0e2a 100644 --- a/Packages/com.unity.ugui/Runtime/UGUI/UI/Core/InputField.cs +++ b/Packages/com.unity.ugui/Runtime/UGUI/UI/Core/InputField.cs @@ -3011,6 +3011,8 @@ namespace UnityEngine.UI if (ch >= '0' && ch <= '9') return ch; if (ch == '-' && (pos == 0 || selectionAtStart)) return ch; if ((ch == '.' || ch == ',') && characterValidation == CharacterValidation.Decimal && text.IndexOfAny(new[] { '.', ',' }) == -1) return ch; + //Some keyboards including Samsung require double tapping a . to get a - this allows these keyboards to input negative integers + if (characterValidation == CharacterValidation.Integer && ch == '.' && (pos == 0 || selectionAtStart)) return '-'; } } else if (characterValidation == CharacterValidation.Alphanumeric) @@ -3309,7 +3311,7 @@ namespace UnityEngine.UI { m_LineType = LineType.SingleLine; m_InputType = InputType.Standard; - m_KeyboardType = TouchScreenKeyboardType.NumberPad; + m_KeyboardType = TouchScreenKeyboardType.NumbersAndPunctuation; m_CharacterValidation = CharacterValidation.Integer; break; } diff --git a/Packages/com.unity.ugui/Runtime/UGUI/UI/Core/MultipleDisplayUtilities.cs b/Packages/com.unity.ugui/Runtime/UGUI/UI/Core/MultipleDisplayUtilities.cs index 2db6b880..24b75ead 100644 --- a/Packages/com.unity.ugui/Runtime/UGUI/UI/Core/MultipleDisplayUtilities.cs +++ b/Packages/com.unity.ugui/Runtime/UGUI/UI/Core/MultipleDisplayUtilities.cs @@ -66,30 +66,44 @@ namespace UnityEngine.UI public static Vector3 RelativeMouseAtScaled(Vector2 position, int displayIndex) { #if !UNITY_EDITOR && !UNITY_WSA - // If the main display is now the same resolution as the system then we need to scale the mouse position. (case 1141732) - if (Display.main.renderingWidth != Display.main.systemWidth || Display.main.renderingHeight != Display.main.systemHeight) + // For most platforms, if the main display is not the same resolution as the system then we will have to scale the mouse position. (case 1141732) + var display = Display.main; +#if ENABLE_INPUT_SYSTEM && PACKAGE_INPUTSYSTEM + if (displayIndex >= Display.displays.Length) + displayIndex = 0; + + // With the new input system, passed positions are always relative to a surface and scaled accordingly to the rendering resolution. + display = Display.displays[displayIndex]; + // So, if not in fullscreen, assume UaaL multi-view multi-screen multi-touch scenario, where the position is already in the correct scaled coordinates for the displayIndex + if (!Screen.fullScreen) + { + return new Vector3(position.x, position.y, displayIndex); + } + // Otherwise, in full screen, we add some padding if rendering and system resolution differs, as for other platforms' main display. (So behavior is unchanged for Android main display, untested for non-main displays) +#endif + if (display.renderingWidth != display.systemWidth || display.renderingHeight != display.systemHeight) { // The system will add padding when in full-screen and using a non-native aspect ratio. (case UUM-7893) // For example Rendering 1920x1080 with a systeem resolution of 3440x1440 would create black bars on each side that are 330 pixels wide. // we need to account for this or it will offset our coordinates when we are not on the main display. - var systemAspectRatio = Display.main.systemWidth / (float)Display.main.systemHeight; + var systemAspectRatio = display.systemWidth / (float)display.systemHeight; - var sizePlusPadding = new Vector2(Display.main.renderingWidth, Display.main.renderingHeight); + var sizePlusPadding = new Vector2(display.renderingWidth, display.renderingHeight); var padding = Vector2.zero; if (Screen.fullScreen) { - var aspectRatio = Screen.width / (float)Screen.height; - if (Display.main.systemHeight * aspectRatio < Display.main.systemWidth) + var aspectRatio = Screen.width / (float)Screen.height; // This assumes aspectRatio is the same for all displays + if (display.systemHeight * aspectRatio < display.systemWidth) { // Horizontal padding - sizePlusPadding.x = Display.main.renderingHeight * systemAspectRatio; - padding.x = (sizePlusPadding.x - Display.main.renderingWidth) * 0.5f; + sizePlusPadding.x = display.renderingHeight * systemAspectRatio; + padding.x = (sizePlusPadding.x - display.renderingWidth) * 0.5f; } else { // Vertical padding - sizePlusPadding.y = Display.main.renderingWidth / systemAspectRatio; - padding.y = (sizePlusPadding.y - Display.main.renderingHeight) * 0.5f; + sizePlusPadding.y = display.renderingWidth / systemAspectRatio; + padding.y = (sizePlusPadding.y - display.renderingHeight) * 0.5f; } } @@ -105,20 +119,20 @@ namespace UnityEngine.UI if (!Screen.fullScreen) { // When in windowed mode, the window will be centered with the 0,0 coordinate at the top left, we need to adjust so it is relative to the screen instead. - adjustedPosition.x -= (Display.main.renderingWidth - Display.main.systemWidth) * 0.5f; - adjustedPosition.y -= (Display.main.renderingHeight - Display.main.systemHeight) * 0.5f; + adjustedPosition.x -= (display.renderingWidth - display.systemWidth) * 0.5f; + adjustedPosition.y -= (display.renderingHeight - display.systemHeight) * 0.5f; } else { // Scale the mouse position to account for the black bars when in a non-native aspect ratio. adjustedPosition += padding; - adjustedPosition.x *= Display.main.systemWidth / sizePlusPadding.x; - adjustedPosition.y *= Display.main.systemHeight / sizePlusPadding.y; + adjustedPosition.x *= display.systemWidth / sizePlusPadding.x; + adjustedPosition.y *= display.systemHeight / sizePlusPadding.y; } - // fix for UUM-63551: Use the display index provided to this method. Display.RelativeMouseAt( ) no longer works starting with 2021 LTS and new input system - // as the Pointer position is reported in Window coordinates rather than relative to the primary window as Display.RelativeMouseAt( ) expects. -#if ENABLE_INPUT_SYSTEM && PACKAGE_INPUTSYSTEM && (UNITY_STANDALONE_WIN || UNITY_STANDALONE_LINUX) + // fix for UUM-63551: Use the display index provided to this method. Display.RelativeMouseAt( ) no longer works starting with 2021 LTS and new input system + // as the Pointer position is reported in Window coordinates rather than relative to the primary window as Display.RelativeMouseAt( ) expects. +#if ENABLE_INPUT_SYSTEM && PACKAGE_INPUTSYSTEM && (UNITY_STANDALONE_WIN || UNITY_STANDALONE_LINUX || UNITY_ANDROID) var relativePos = new Vector3(adjustedPosition.x, adjustedPosition.y, displayIndex); #else var relativePos = Display.RelativeMouseAt(adjustedPosition); @@ -130,13 +144,18 @@ namespace UnityEngine.UI } // We are using the main display. +#if ENABLE_INPUT_SYSTEM && PACKAGE_INPUTSYSTEM && UNITY_ANDROID + // On Android, in all cases, it is a surface associated to a given displayIndex, so we need to use the display index + return new Vector3(position.x, position.y, displayIndex); +#else return new Vector3(position.x, position.y, 0); +#endif } #endif - // fix for UUM-63551: Use the display index provided to this method. Display.RelativeMouseAt( ) no longer works starting with 2021 LTS and new input system - // as the Pointer position is reported in Window coordinates rather than relative to the primary window as Display.RelativeMouseAt( ) expects. -#if ENABLE_INPUT_SYSTEM && PACKAGE_INPUTSYSTEM && (UNITY_STANDALONE_WIN || UNITY_STANDALONE_LINUX) + // fix for UUM-63551: Use the display index provided to this method. Display.RelativeMouseAt( ) no longer works starting with 2021 LTS and new input system + // as the Pointer position is reported in Window coordinates rather than relative to the primary window as Display.RelativeMouseAt( ) expects. +#if ENABLE_INPUT_SYSTEM && PACKAGE_INPUTSYSTEM && (UNITY_STANDALONE_WIN || UNITY_STANDALONE_LINUX || UNITY_ANDROID) return new Vector3(position.x, position.y, displayIndex); #else return Display.RelativeMouseAt(position); diff --git a/Packages/com.unity.ugui/Tests/Runtime/UGUI/CanvasRenderer.meta b/Packages/com.unity.ugui/Tests/Runtime/UGUI/CanvasRenderer.meta new file mode 100644 index 00000000..5a4067bb --- /dev/null +++ b/Packages/com.unity.ugui/Tests/Runtime/UGUI/CanvasRenderer.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a69b08936f9f74179ae333a4bebe7c54 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.ugui/Tests/Runtime/UGUI/CanvasRenderer/CanvasRendererTests.cs b/Packages/com.unity.ugui/Tests/Runtime/UGUI/CanvasRenderer/CanvasRendererTests.cs new file mode 100644 index 00000000..6712b3c5 --- /dev/null +++ b/Packages/com.unity.ugui/Tests/Runtime/UGUI/CanvasRenderer/CanvasRendererTests.cs @@ -0,0 +1,119 @@ +using UnityEngine; +using NUnit.Framework; + +public class CanvasRendererTests +{ + private const int Width = 32; + private const int Height = 32; + GameObject m_GraphicObj; + CanvasRenderer m_CanvasRenderer; + private Texture2D m_DefaultTexture; + static readonly string k_MaskTexPropName = "_MaskTex"; + static readonly string k_GlowTexPropName = "_GlowTex"; + Texture2D m_MaskTex; + Texture2D m_GlowTex; + + [SetUp] + public void SetUp() + { + m_GraphicObj = new GameObject("Graphic"); + m_CanvasRenderer = m_GraphicObj.AddComponent(); + m_MaskTex = CreateTexture(Color.red); + m_GlowTex = CreateTexture(Color.yellow); + } + + Texture2D CreateTexture(Color color) + { + var tex = new Texture2D(Width, Height); + Color[] colors = new Color[Width * Height]; + for (int i = 0; i < Width * Height; i++) + colors[i] = color; + tex.SetPixels(colors); + tex.Apply(); + return tex; + } + + [Test] + public void InitialData() + { + Assert.AreEqual(0, m_CanvasRenderer.GetSecondaryTextureCount()); + } + + [Test] + public void AddSecondaryTextures() + { + m_CanvasRenderer.SetSecondaryTextureCount(2); + + Assert.AreEqual(2, m_CanvasRenderer.GetSecondaryTextureCount()); + Assert.True(string.IsNullOrEmpty(m_CanvasRenderer.GetSecondaryTextureName(0))); + Assert.Null(m_CanvasRenderer.GetSecondaryTexture(0)); + Assert.True(string.IsNullOrEmpty(m_CanvasRenderer.GetSecondaryTextureName(1))); + Assert.Null(m_CanvasRenderer.GetSecondaryTexture(1)); + + m_CanvasRenderer.SetSecondaryTexture(0, k_MaskTexPropName, m_MaskTex); + m_CanvasRenderer.SetSecondaryTexture(1, k_GlowTexPropName, m_GlowTex); + + Assert.AreEqual(k_MaskTexPropName, m_CanvasRenderer.GetSecondaryTextureName(0)); + Assert.AreEqual(m_MaskTex, m_CanvasRenderer.GetSecondaryTexture(0)); + Assert.AreEqual(k_GlowTexPropName, m_CanvasRenderer.GetSecondaryTextureName(1)); + Assert.AreEqual(m_GlowTex, m_CanvasRenderer.GetSecondaryTexture(1)); + } + + [Test] + public void RemoveSecondaryTextures() + { + m_CanvasRenderer.SetSecondaryTextureCount(2); + m_CanvasRenderer.SetSecondaryTexture(0, k_MaskTexPropName, m_MaskTex); + m_CanvasRenderer.SetSecondaryTexture(1, k_GlowTexPropName, m_GlowTex); + + // The last secondary texture + m_CanvasRenderer.SetSecondaryTextureCount(1); + + Assert.AreEqual(1, m_CanvasRenderer.GetSecondaryTextureCount()); + Assert.AreEqual(k_MaskTexPropName, m_CanvasRenderer.GetSecondaryTextureName(0)); + Assert.AreEqual(m_MaskTex, m_CanvasRenderer.GetSecondaryTexture(0)); + } + + [Test] + public void SetSecondaryTextureCount() + { + m_CanvasRenderer.SetSecondaryTextureCount(2); + m_CanvasRenderer.SetSecondaryTexture(0, k_MaskTexPropName, m_MaskTex); + m_CanvasRenderer.SetSecondaryTexture(1, k_GlowTexPropName, m_GlowTex); + + m_CanvasRenderer.SetSecondaryTextureCount(1); + + Assert.AreEqual(1, m_CanvasRenderer.GetSecondaryTextureCount()); + Assert.AreEqual(k_MaskTexPropName, m_CanvasRenderer.GetSecondaryTextureName(0)); + Assert.AreEqual(m_MaskTex, m_CanvasRenderer.GetSecondaryTexture(0)); + + // Increase the number of secondary textures and verify that the new entries are empty + m_CanvasRenderer.SetSecondaryTextureCount(3); + + Assert.AreEqual(3, m_CanvasRenderer.GetSecondaryTextureCount()); + Assert.AreEqual(k_MaskTexPropName, m_CanvasRenderer.GetSecondaryTextureName(0)); + Assert.AreEqual(m_MaskTex, m_CanvasRenderer.GetSecondaryTexture(0)); + Assert.True(string.IsNullOrEmpty(m_CanvasRenderer.GetSecondaryTextureName(1))); + Assert.Null(m_CanvasRenderer.GetSecondaryTexture(1)); + Assert.True(string.IsNullOrEmpty(m_CanvasRenderer.GetSecondaryTextureName(2))); + Assert.Null(m_CanvasRenderer.GetSecondaryTexture(2)); + + // Clear all the secondary textures + m_CanvasRenderer.SetSecondaryTextureCount(0); + + Assert.AreEqual(0, m_CanvasRenderer.GetSecondaryTextureCount()); + + // Add an element again and verify that it is empty + m_CanvasRenderer.SetSecondaryTextureCount(1); + + Assert.True(string.IsNullOrEmpty(m_CanvasRenderer.GetSecondaryTextureName(0))); + Assert.Null(m_CanvasRenderer.GetSecondaryTexture(0)); + } + + [TearDown] + public void TearDown() + { + GameObject.DestroyImmediate(m_GraphicObj); + } +} + diff --git a/Packages/com.unity.ugui/Tests/Runtime/UGUI/CanvasRenderer/CanvasRendererTests.cs.meta b/Packages/com.unity.ugui/Tests/Runtime/UGUI/CanvasRenderer/CanvasRendererTests.cs.meta new file mode 100644 index 00000000..558f8221 --- /dev/null +++ b/Packages/com.unity.ugui/Tests/Runtime/UGUI/CanvasRenderer/CanvasRendererTests.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 6fac6d65d2fb7472d94e95ddb8b8798c \ No newline at end of file diff --git a/Packages/com.unity.ugui/Tests/Runtime/UGUI/Image/ImageTests.cs b/Packages/com.unity.ugui/Tests/Runtime/UGUI/Image/ImageTests.cs index 95b48d13..2fdd1bac 100644 --- a/Packages/com.unity.ugui/Tests/Runtime/UGUI/Image/ImageTests.cs +++ b/Packages/com.unity.ugui/Tests/Runtime/UGUI/Image/ImageTests.cs @@ -12,7 +12,8 @@ public class ImageTests GameObject m_CanvasGO; TestableImage m_Image; - private Texture2D m_defaultTexture; + private Texture2D m_DefaultTexture; + private static SecondarySpriteTexture [] s_EmptySecondaryTexArray = {}; private bool m_dirtyLayout; private bool m_dirtyMaterial; @@ -27,11 +28,18 @@ public class ImageTests m_Image.RegisterDirtyLayoutCallback(() => m_dirtyLayout = true); m_Image.RegisterDirtyMaterialCallback(() => m_dirtyMaterial = true); - m_defaultTexture = new Texture2D(Width, Height); + m_DefaultTexture = CreateTexture(Color.magenta); + } + + Texture2D CreateTexture(Color color) + { + var tex = new Texture2D(Width, Height); Color[] colors = new Color[Width * Height]; for (int i = 0; i < Width * Height; i++) - colors[i] = Color.magenta; - m_defaultTexture.Apply(); + colors[i] = color; + tex.SetPixels(colors); + tex.Apply(); + return tex; } [Test] @@ -83,7 +91,7 @@ public class ImageTests [UnityTest] public IEnumerator Sprite_Layout() { - m_Image.sprite = Sprite.Create(m_defaultTexture, new Rect(0, 0, Width, Height), Vector2.zero); + m_Image.sprite = Sprite.Create(m_DefaultTexture, new Rect(0, 0, Width, Height), Vector2.zero); yield return null; m_Image.isGeometryUpdated = false; @@ -108,12 +116,12 @@ public class ImageTests [UnityTest] public IEnumerator Sprite_Material() { - m_Image.sprite = Sprite.Create(m_defaultTexture, new Rect(0, 0, Width, Height), Vector2.zero); + m_Image.sprite = Sprite.Create(m_DefaultTexture, new Rect(0, 0, Width, Height), Vector2.zero); yield return null; m_Image.isGeometryUpdated = false; m_dirtyMaterial = false; - m_Image.sprite = Sprite.Create(m_defaultTexture, new Rect(0, 0, Width / 2, Height / 2), Vector2.zero); + m_Image.sprite = Sprite.Create(m_DefaultTexture, new Rect(0, 0, Width / 2, Height / 2), Vector2.zero); yield return new WaitUntil(() => m_Image.isGeometryUpdated); // validate that material change rebuild is not called @@ -129,10 +137,134 @@ public class ImageTests Assert.IsTrue(m_dirtyMaterial); } + IEnumerator ValidateSecondaryTextures(SecondarySpriteTexture[] expectedSecondaryTextures) + { + yield return new WaitUntil(() => m_Image.isMaterialUpdated); + + if (expectedSecondaryTextures.Length == 0) + Assert.Null(m_Image.secondaryTextures); + else + { + Assert.NotNull(m_Image.secondaryTextures); + Assert.AreEqual(expectedSecondaryTextures.Length, m_Image.secondaryTextures.Length); + } + Assert.AreEqual(expectedSecondaryTextures.Length, m_Image.canvasRenderer.GetSecondaryTextureCount()); + + for (int i = 0; i < expectedSecondaryTextures.Length; ++i) + { + Assert.AreEqual(expectedSecondaryTextures[i].name, m_Image.secondaryTextures[i].name); + Assert.AreEqual(expectedSecondaryTextures[i].texture, m_Image.secondaryTextures[i].texture); + + // Canvas Renderer + Assert.AreEqual(expectedSecondaryTextures[i].name, m_Image.canvasRenderer.GetSecondaryTextureName(i)); + Assert.AreEqual(expectedSecondaryTextures[i].texture, m_Image.canvasRenderer.GetSecondaryTexture(i)); + } + } + + [UnityTest] + public IEnumerator Sprite_NoSecondaryTextures() + { + var sprite = Sprite.Create(m_DefaultTexture, new Rect(0, 0, Width, Height), Vector2.zero); + + m_dirtyMaterial = false; + m_Image.isMaterialUpdated = false; + m_Image.sprite = sprite; + Assert.IsTrue(m_dirtyMaterial); + + yield return ValidateSecondaryTextures(s_EmptySecondaryTexArray); + } + + [UnityTest] + public IEnumerator Sprite_SecondaryTextures() + { + var secondaryTextures = new[] + { + new SecondarySpriteTexture() + { + name = "_MaskTex", + texture = CreateTexture(Color.red) + }, + new SecondarySpriteTexture() + { + name = "_GlowTex", + texture = CreateTexture(Color.yellow) + } + }; + + var sprite = Sprite.Create(m_DefaultTexture, new Rect(0, 0, Width, Height), Vector2.zero, 100, 0, SpriteMeshType.FullRect, Vector4.zero, false, secondaryTextures); + + m_dirtyMaterial = false; + m_Image.isMaterialUpdated = false; + m_Image.sprite = sprite; + Assert.IsTrue(m_dirtyMaterial); + + yield return ValidateSecondaryTextures(secondaryTextures); + } + + [UnityTest] + public IEnumerator Sprite_SecondaryTexturesUpdatedAfterSpriteChanged() + { + var spriteWithNoSecTex = Sprite.Create(m_DefaultTexture, new Rect(0, 0, Width, Height), Vector2.zero); + + m_dirtyMaterial = false; + m_Image.isMaterialUpdated = false; + m_Image.sprite = spriteWithNoSecTex; + Assert.IsTrue(m_dirtyMaterial); + + yield return ValidateSecondaryTextures(s_EmptySecondaryTexArray); + + var twoSecondaryTextures = new[] + { + new SecondarySpriteTexture() + { + name = "_MaskTex", + texture = CreateTexture(Color.red) + }, + new SecondarySpriteTexture() + { + name = "_GlowTex", + texture = CreateTexture(Color.yellow) + } + }; + + var spriteWithTwoSecTexs = Sprite.Create(m_DefaultTexture, new Rect(0, 0, Width, Height), Vector2.zero, 100, 0, SpriteMeshType.FullRect, Vector4.zero, false, twoSecondaryTextures); + + m_dirtyMaterial = false; + m_Image.isMaterialUpdated = false; + m_Image.sprite = spriteWithTwoSecTexs; + Assert.IsTrue(m_dirtyMaterial); + + yield return ValidateSecondaryTextures(twoSecondaryTextures); + + var oneSecondaryTexture = new[] + { + new SecondarySpriteTexture() + { + name = "_MaskTex", + texture = CreateTexture(Color.red) + } + }; + var spriteWithOneSecTex = Sprite.Create(m_DefaultTexture, new Rect(0, 0, Width, Height), Vector2.zero, 100, 0, + SpriteMeshType.FullRect, Vector4.zero, false, oneSecondaryTexture); + + m_dirtyMaterial = false; + m_Image.isMaterialUpdated = false; + m_Image.sprite = spriteWithOneSecTex; + Assert.IsTrue(m_dirtyMaterial); + + yield return ValidateSecondaryTextures(oneSecondaryTexture); + + m_Image.isMaterialUpdated = false; + m_Image.sprite = spriteWithNoSecTex; + Assert.IsTrue(m_dirtyMaterial); + + yield return ValidateSecondaryTextures(s_EmptySecondaryTexArray); + } + [TearDown] public void TearDown() { GameObject.DestroyImmediate(m_CanvasGO); - GameObject.DestroyImmediate(m_defaultTexture); + GameObject.DestroyImmediate(m_DefaultTexture); } } diff --git a/Packages/com.unity.ugui/Tests/Runtime/UGUI/Image/TestableImage.cs b/Packages/com.unity.ugui/Tests/Runtime/UGUI/Image/TestableImage.cs index 21180798..acaff3c3 100644 --- a/Packages/com.unity.ugui/Tests/Runtime/UGUI/Image/TestableImage.cs +++ b/Packages/com.unity.ugui/Tests/Runtime/UGUI/Image/TestableImage.cs @@ -6,6 +6,7 @@ public class TestableImage : Image { public bool isOnPopulateMeshCalled = false; public bool isGeometryUpdated = false; + public bool isMaterialUpdated = false; // Hook into the mesh generation so we can do our check. protected override void OnPopulateMesh(VertexHelper toFill) @@ -21,6 +22,12 @@ public class TestableImage : Image isGeometryUpdated = true; } + protected override void UpdateMaterial() + { + base.UpdateMaterial(); + isMaterialUpdated = true; + } + public void GenerateImageData(VertexHelper vh) { OnPopulateMesh(vh); diff --git a/Packages/com.unity.ugui/Tests/Runtime/UGUI/InputField/GenericInputFieldTests.cs b/Packages/com.unity.ugui/Tests/Runtime/UGUI/InputField/GenericInputFieldTests.cs index 636c436e..c0304b27 100644 --- a/Packages/com.unity.ugui/Tests/Runtime/UGUI/InputField/GenericInputFieldTests.cs +++ b/Packages/com.unity.ugui/Tests/Runtime/UGUI/InputField/GenericInputFieldTests.cs @@ -195,7 +195,7 @@ namespace InputfieldTests inputField.contentType = InputField.ContentType.IntegerNumber; Assert.AreEqual(InputField.LineType.SingleLine, inputField.lineType); Assert.AreEqual(InputField.InputType.Standard, inputField.inputType); - Assert.AreEqual(TouchScreenKeyboardType.NumberPad, inputField.keyboardType); + Assert.AreEqual(TouchScreenKeyboardType.NumbersAndPunctuation, inputField.keyboardType); Assert.AreEqual(InputField.CharacterValidation.Integer, inputField.characterValidation); inputField.contentType = InputField.ContentType.DecimalNumber; diff --git a/Packages/com.unity.ugui/package.json b/Packages/com.unity.ugui/package.json index ed6919c2..d7b501b6 100644 --- a/Packages/com.unity.ugui/package.json +++ b/Packages/com.unity.ugui/package.json @@ -19,5 +19,5 @@ "com.unity.modules.ui": "1.0.0", "com.unity.modules.imgui": "1.0.0" }, - "_fingerprint": "03407c6d875144b0a8ffdc0af3e0d5cccfa5a4ae" + "_fingerprint": "77ab6c14086a78be39959c143506f2d27f70c4e3" } diff --git a/Packages/com.unity.visualeffectgraph/CHANGELOG.md b/Packages/com.unity.visualeffectgraph/CHANGELOG.md index 121da2c2..88fd3051 100644 --- a/Packages/com.unity.visualeffectgraph/CHANGELOG.md +++ b/Packages/com.unity.visualeffectgraph/CHANGELOG.md @@ -12,12 +12,57 @@ The version number for this package has increased due to a version update of a r ## [17.0.3] - 2025-02-13 -This version is compatible with Unity 6000.0.39f1. +This version is compatible with Unity 6000.2.0a1. ### Changed +- Improved shader source generation performance. +- Improved VFX compilation time by avoiding redundant instanciation of implicit blocks. +- Added a missing button in the VFX template window to quickly install learning templates. +- Optimized the particle attribute layout for a smaller memory footprint. +- Reduced the main thread cost of `VFX.Update` by moving some transform-related operations to other threads. +- Performance optimization on the attributes manager. +- Enable threaded `RenderQueue` extraction for VFX renderers. +- Modified the code generation process to skip creating DXR-related code when ray tracing is not enabled in the output. +- Improved shader generation time by implementing a local include template cache. +- Enabled instancing support for VFX using GPU events. - Added a missing button in the VFX template window to quickly install learning templates. ### Fixed +- Incorrect sanitization of SetCustomAttribute when Random was different than Random.Off +- Missing delayed field for Sample Water Surface Operator. +- Unexpected log "Expression graph was marked as dirty after compiling context for UI" while using Custom HLSL based operators. +- Using the same name as a built-in attribute in a custom HLSL function's parameter would lead to a compilation error. +- Creating a Custom HLSL operator with two outputs could prevent the generated shader from compiling +- Fixed VFX particles GBuffer pass with URP Render Graph. +- Particle outputs connected to particle strip systems don't render last particle. +- Fixed an issue when importing old VFX asset in Unity6 using custom attribute with same name as built-in attribute. +- Fixed an issue subgraph blocks did not accept correct types of block based on their suitable context. +- Fixed an issue where CustomRenderTexture could not be used in VFX Graph object fields. +- Fixed a small cursor offset when drawing a rectangle selection. +- Fixed usage of FogNode always returning 1.0 in URP. +- Fixed an argument exception that used Arc Transform in blackboard. +- Fixed arc Shape properties in blackboard not applied in VFXGraph. +- Fixed an issue where reordering properties inside a category were not possible. Also reordering a category could not work if there was properties at the root (with no category) +- Fixed port's label was not be visible when node is collapsed. +- Fixed an exception that could prevent opening a VFX in one specific case. +- Fixed a potential crash that could occur when adding the render node of sleeping systems. +- Fixed an issue where CustomHLSL was incorrectly marking parent assets as dirty. +- Fixed emissive decal when using color attribute for emissive. +- Fixed sprites in Texture Sheet Animation module in HDRP. +- Fixed an issue where direct material modification in VFXRenderer could lead to crashes. +- Fixed a potential memory-intensive strip buffer initialization by moving it to a compute dispatch. + +- Fixed `NullReferenceExpection` happening with disconnected output contexts. +- Fix VFX ray tracing shader errors when using flipbook or when not using the color attribute. +- This PR fix resolves minor issues related to VFX graph content sample package. +- This PR fix resolves minor issues related to VFX graph content sample package. +- This PR fix resolves minor issues related to VFX graph content sample package. +- This PR fix resolves minor issues related to VFX graph content sample package. +- This PR fix resolves minor issues related to VFX graph content sample package. +- This PR fix resolves minor issues related to VFX graph content sample package. +- Fixed an issue where the VFX Graph template window appeared empty when the Terrain Tools package was installed. +- Fixed occasional crashes when modifying exposed properties when in paused play mode. +- Fixed errors that occurred when deleting Integration Update Rotation and Trigger blocks in the VFX Graph. - Fixed HLSL blocks so that they accept parameters that don't have an `in` attribute. - Fixed incorrect error message on Custom HLSL. - Improved CustomHLSL to consider custom HLSL and includes workflow. diff --git a/Packages/com.unity.visualeffectgraph/Editor/Compiler/VFXCodeGenerator.cs b/Packages/com.unity.visualeffectgraph/Editor/Compiler/VFXCodeGenerator.cs index 3301eac7..bce915bf 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/Compiler/VFXCodeGenerator.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/Compiler/VFXCodeGenerator.cs @@ -21,74 +21,20 @@ namespace UnityEditor.VFX { public const uint nbThreadsPerGroup = 64u; - private static string GetIndent(string src, int index) + internal static VFXShaderWriter GenerateLoadAttribute(string matching, VFXContext context, VFXTaskCompiledData taskData) { - var indent = ""; - index--; - while (index > 0 && (src[index] == ' ' || src[index] == '\t')) - { - indent = src[index] + indent; - index--; - } - return indent; - } + var r = new VFXShaderWriter(); - //This function insure to keep padding while replacing a specific string - public static void ReplaceMultiline(StringBuilder target, string targetQuery, StringBuilder value) - { - Profiler.BeginSample("ReplaceMultiline"); - - string[] delim = { System.Environment.NewLine, "\n" }; - var valueLines = value.ToString().Split(delim, System.StringSplitOptions.None); - // For some reasons, just calling Replace(...) without any index data is orders of magnitude - // slower than searching a copy of the string to get the index first. So both codepaths do - // exactly that. - if (valueLines.Length <= 1) + VFXAttributeInfo[] attributesFromContext; + if (matching != null) { - var replacement = value.ToString(); - int startIndex = 0; - while (true) - { - var targetCopy = target.ToString(); - var index = targetCopy.IndexOf(targetQuery, startIndex, StringComparison.Ordinal); - if (index == -1) - break; - target.Replace(targetQuery, replacement, index, targetQuery.Length); - startIndex = index; - } + var regex = new Regex(matching); + attributesFromContext = context.GetData().GetAttributes().Where(o => regex.IsMatch(o.attrib.name)).ToArray(); } else { - int startIndex = 0; - while (true) - { - var targetCopy = target.ToString(); - var index = targetCopy.IndexOf(targetQuery, startIndex, StringComparison.Ordinal); - if (index == -1) - break; - var indent = GetIndent(targetCopy, index); - var currentValue = new StringBuilder(); - foreach (var line in valueLines) - { - currentValue.Append(indent + line + '\n'); - } - var currentValueString = currentValue.ToString(); - var toReplace = indent + targetQuery; - index -= indent.Length; - target.Replace(toReplace, currentValueString, index, toReplace.Length); - startIndex = index; - } + attributesFromContext = context.GetData().GetAttributes().ToArray(); } - - Profiler.EndSample(); - } - - internal static VFXShaderWriter GenerateLoadAttribute(string matching, VFXContext context, VFXTaskCompiledData taskData) - { - var r = new VFXShaderWriter(); - - var regex = new Regex(matching); - var attributesFromContext = context.GetData().GetAttributes().Where(o => regex.IsMatch(o.attrib.name)).ToArray(); var attributesSource = attributesFromContext.Where(a => context.GetData().IsSourceAttributeUsed(a.attrib, context)).ToArray(); var attributesCurrent = attributesFromContext.Where(a => context.GetData().IsCurrentAttributeUsed(a.attrib, context) || (context.contextType == VFXContextType.Init && context.GetData().IsAttributeStored(a.attrib))).ToArray(); @@ -148,7 +94,42 @@ namespace UnityEditor.VFX private const string eventListOutName = "eventListOut"; - static private VFXShaderWriter GenerateStoreAttribute(string matching, VFXContext context, uint linkedOutCount) + internal class Cache + { + private Dictionary m_SnippetsMap = new Dictionary(); + private Dictionary m_TemplateIncludeCache = new Dictionary(); + + internal void ClearSnippets() + { + m_SnippetsMap.Clear(); + } + internal bool TryAddSnippet(string key, StringBuilder value) + { + return m_SnippetsMap.TryAdd(key, value); + } + + internal void SetSnippet(string key, StringBuilder value) + { + m_SnippetsMap[key] = value; + } + + internal bool TryGetSnippet(string key, out StringBuilder value) + { + return m_SnippetsMap.TryGetValue(key, out value); + } + + internal void AddTemplateCache(string key, string value) + { + m_TemplateIncludeCache.Add(key, value); + } + + internal bool TryGetTemplateCache(string key, out string value) + { + return m_TemplateIncludeCache.TryGetValue(key, out value); + } + } + + internal static VFXShaderWriter GenerateStoreAttribute(string matching, VFXContext context, uint linkedOutCount) { var r = new VFXShaderWriter(); var regex = new Regex(matching); @@ -180,7 +161,7 @@ AppendEventTotalCount({2}_{0}, min({1}_{0}, {1}_{0}_Capacity), instanceIndex); } return r; } - static internal VFXShaderWriter GenerateSetInstancingIndices(VFXContext context) + static internal VFXShaderWriter GenerateSetInstancingIndices() { var r = new VFXShaderWriter(); @@ -193,11 +174,11 @@ AppendEventTotalCount({2}_{0}, min({1}_{0}, {1}_{0}_Capacity), instanceIndex); static internal VFXShaderWriter GenerateLoadParameter(string matching, VFXNamedExpression[] namedExpressions, Dictionary expressionToName) { - var r = new VFXShaderWriter(); - var regex = new Regex(matching); - - var filteredNamedExpressions = namedExpressions.Where(o => regex.IsMatch(o.name) && - !(expressionToName.ContainsKey(o.exp) && expressionToName[o.exp] == o.name)); // if parameter already in the global scope, there's nothing to do + VFXShaderWriter r = new VFXShaderWriter(); + var filteredNamedExpressions = namedExpressions.Where(o => o.name == matching && + !(expressionToName.ContainsKey(o.exp) && expressionToName[o.exp] == o.name)).ToArray(); // if parameter already in the global scope, there's nothing to do + if (filteredNamedExpressions.Length == 0) + return r; bool needScope = false; foreach (var namedExpression in filteredNamedExpressions) @@ -234,6 +215,7 @@ AppendEventTotalCount({2}_{0}, min({1}_{0}, {1}_{0}_Capacity), instanceIndex); VFXTaskCompiledData taskData, HashSet dependencies, bool forceShadeDebugSymbols, + Cache codeGeneratorCache, out List errors) { string templatePath = null; @@ -243,7 +225,7 @@ AppendEventTotalCount({2}_{0}, min({1}_{0}, {1}_{0}_Capacity), instanceIndex); dependencies.Add(AssetDatabase.AssetPathToGUID(templatePath)); } - return Build(context, task, templatePath, compilationMode, taskData, dependencies, forceShadeDebugSymbols, out errors); + return Build(context, task, templatePath, compilationMode, taskData, dependencies, forceShadeDebugSymbols, codeGeneratorCache, out errors); } private static void GetFunctionName(VFXBlock block, out string functionName, out string comment) @@ -271,123 +253,6 @@ AppendEventTotalCount({2}_{0}, min({1}_{0}, {1}_{0}_Capacity), instanceIndex); } } - static private string FormatPath(string path) - { - return Path.GetFullPath(path) - .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar) -#if !UNITY_EDITOR_LINUX - .ToLowerInvariant() -#endif - ; - } - - static IEnumerable GetUniqueMatches(string regexStr, string src) - { - var regex = new Regex(regexStr); - var matches = regex.Matches(src); - return matches.Cast().GroupBy(m => m.Groups[0].Value).Select(g => g.First()); - } - - static private StringBuilder GetFlattenedTemplateContent(string path, List includes, IEnumerable defines, HashSet dependencies) - { - var formattedPath = FormatPath(path); - - if (includes.Contains(formattedPath)) - { - var includeHierarchy = new StringBuilder(string.Format("Cyclic VFXInclude dependency detected: {0}\n", formattedPath)); - foreach (var str in Enumerable.Reverse(includes)) - includeHierarchy.Append(str + '\n'); - throw new InvalidOperationException(includeHierarchy.ToString()); - } - - includes.Add(formattedPath); - var templateContent = new StringBuilder(System.IO.File.ReadAllText(formattedPath)); - - foreach (var match in GetUniqueMatches("\\${VFXInclude(RP|)\\(\\\"(.*?)\\\"\\)(,.*)?}", templateContent.ToString())) - { - var groups = match.Groups; - var renderPipelineInclude = groups[1].Value == "RP"; - var includePath = groups[2].Value; - - - if (groups.Count > 3 && !String.IsNullOrEmpty(groups[2].Value)) - { - var allDefines = groups[3].Value.Split(new char[] { ',', ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); - var neededDefines = allDefines.Where(d => d[0] != '!'); - var forbiddenDefines = allDefines.Except(neededDefines).Select(d => d.Substring(1)); - if (!neededDefines.All(d => defines.Contains(d)) || forbiddenDefines.Any(d => defines.Contains(d))) - { - ReplaceMultiline(templateContent, groups[0].Value, new StringBuilder()); - continue; - } - } - - string absolutePath; - if (renderPipelineInclude) - absolutePath = VFXLibrary.currentSRPBinder.templatePath + "/" + includePath; - else - absolutePath = VisualEffectGraphPackageInfo.assetPackagePath + "/" + includePath; - dependencies.Add(AssetDatabase.AssetPathToGUID(absolutePath)); - - var includeBuilder = GetFlattenedTemplateContent(absolutePath, includes, defines, dependencies); - ReplaceMultiline(templateContent, groups[0].Value, includeBuilder); - } - - includes.Remove(formattedPath); - return templateContent; - } - - static private void SubstituteMacros(StringBuilder builder) - { - var definesToCode = new Dictionary(); - var source = builder.ToString(); - Regex beginRegex = new Regex("\\${VFXBegin:(.*)}"); - - int currentPos = -1; - int builderOffset = 0; - while ((currentPos = source.IndexOf("${", StringComparison.Ordinal)) != -1) - { - int endPos = source.IndexOf('}', currentPos); - if (endPos == -1) - throw new FormatException("Ill-formed VFX tag (Missing closing brace"); - - var tag = source.Substring(currentPos, endPos - currentPos + 1); - // Replace any tag found - string macro; - if (definesToCode.TryGetValue(tag, out macro)) - { - builder.Remove(currentPos + builderOffset, tag.Length); - var indentedMacro = macro.Replace("\n", "\n" + GetIndent(source, currentPos)); - builder.Insert(currentPos + builderOffset, indentedMacro); - } - else - { - const string endStr = "${VFXEnd}"; - var match = beginRegex.Match(source, currentPos, tag.Length); - if (match.Success) - { - var macroStartPos = match.Index + match.Length; - var macroEndCodePos = source.IndexOf(endStr, macroStartPos); - if (macroEndCodePos == -1) - throw new FormatException("${VFXBegin} found without ${VFXEnd}"); - - var defineStr = "${" + match.Groups[1].Value + "}"; - definesToCode[defineStr] = source.Substring(macroStartPos, macroEndCodePos - macroStartPos); - - // Remove the define in builder - builder.Remove(match.Index + builderOffset, macroEndCodePos - match.Index + endStr.Length); - } - else if (tag == endStr) - throw new FormatException("${VFXEnd} found without ${VFXBegin}"); - else // Remove undefined tag - builder.Remove(currentPos + builderOffset, tag.Length); - } - - builderOffset += currentPos; - source = builder.ToString(builderOffset, builder.Length - builderOffset); - } - } - internal static Dictionary BuildExpressionToName(VFXContext context, VFXTaskCompiledData taskData) { var expressionToName = new Dictionary(taskData.uniformMapper.expressionToCode); @@ -469,11 +334,11 @@ AppendEventTotalCount({2}_{0}, min({1}_{0}, {1}_{0}_Capacity), instanceIndex); var parameterBuffer = new VFXShaderWriter(); needsGraphValueStruct = parameterBuffer.WriteGraphValuesStruct(taskData.uniformMapper); parameterBuffer.WriteLine(); - parameterBuffer.WriteBufferTypeDeclaration(taskData.bufferUsage.Values); + parameterBuffer.WriteBufferTypeDeclaration(taskData.bufferTypeUsage.Values); parameterBuffer.WriteLine(); - parameterBuffer.WriteBuffer(taskData.uniformMapper, taskData.bufferUsage); + parameterBuffer.WriteBuffer(taskData.uniformMapper, taskData.bufferTypeUsage); parameterBuffer.WriteLine(); - parameterBuffer.WriteTexture(taskData.uniformMapper, filteredOutTextures); + parameterBuffer.WriteTexture(taskData.uniformMapper, taskData.bufferTypeUsage, filteredOutTextures); parameterBufferContent = parameterBuffer.ToString(); } @@ -648,7 +513,7 @@ AppendEventTotalCount({2}_{0}, min({1}_{0}, {1}_{0}_Capacity), instanceIndex); loadContextData = loadContextDataShaderWriter.ToString(); } - static private StringBuilder Build( + private static StringBuilder Build( VFXContext context, VFXTask task, string templatePath, @@ -656,6 +521,7 @@ AppendEventTotalCount({2}_{0}, min({1}_{0}, {1}_{0}_Capacity), instanceIndex); VFXTaskCompiledData taskData, HashSet dependencies, bool enableShaderDebugSymbols, + Cache codeGeneratorCache, out List errors) { errors = null; @@ -690,8 +556,10 @@ AppendEventTotalCount({2}_{0}, min({1}_{0}, {1}_{0}_Capacity), instanceIndex); } } - var allAdditionalDefines = context.additionalDefines.Concat(task.additionalDefines ?? Enumerable.Empty()); - var stringBuilder = GetFlattenedTemplateContent(templatePath, new List(), allAdditionalDefines, dependencies); + VFXShaderSnippets.ShaderGenerationData shaderGenerationData = new VFXShaderSnippets.ShaderGenerationData(); + codeGeneratorCache.ClearSnippets(); + + var allAdditionalDefines = context.additionalDefines.Concat(task.additionalDefines ?? Enumerable.Empty()).ToHashSet(); var allCurrentAttributes = contextData.GetAttributes().Where(a => (contextData.IsCurrentAttributeUsed(a.attrib, context)) || @@ -700,7 +568,7 @@ AppendEventTotalCount({2}_{0}, min({1}_{0}, {1}_{0}_Capacity), instanceIndex); var allSourceAttributes = contextData.GetAttributes().Where(a => (contextData.IsSourceAttributeUsed(a.attrib, context))); var globalDeclaration = new VFXShaderWriter(); - globalDeclaration.WriteBufferTypeDeclaration(taskData.bufferUsage.Values); + globalDeclaration.WriteBufferTypeDeclaration(taskData.bufferTypeUsage.Values); globalDeclaration.WriteLine(); var particleData = (contextData as VFXDataParticle); var systemUniformMapper = particleData.systemUniformMapper; @@ -708,9 +576,9 @@ AppendEventTotalCount({2}_{0}, min({1}_{0}, {1}_{0}_Capacity), instanceIndex); var needsGraphValueStruct = globalDeclaration.WriteGraphValuesStruct(taskData.uniformMapper); globalDeclaration.WriteLine(); - globalDeclaration.WriteBuffer(taskData.uniformMapper, taskData.bufferUsage); + globalDeclaration.WriteBuffer(taskData.uniformMapper, taskData.bufferTypeUsage); globalDeclaration.WriteLine(); - globalDeclaration.WriteTexture(taskData.uniformMapper); + globalDeclaration.WriteTexture(taskData.uniformMapper, taskData.bufferTypeUsage); globalDeclaration.WriteAttributeStruct(allCurrentAttributes.Select(a => a.attrib), "VFXAttributes"); globalDeclaration.WriteLine(); globalDeclaration.WriteAttributeStruct(allSourceAttributes.Select(a => a.attrib), "VFXSourceAttributes"); @@ -719,7 +587,12 @@ AppendEventTotalCount({2}_{0}, min({1}_{0}, {1}_{0}_Capacity), instanceIndex); globalDeclaration.WriteEventBuffers(eventListOutName, taskData.linkedEventOut.Length); var expressionToName = BuildExpressionToName(context, taskData); - BuildContextBlocks(context, taskData, expressionToName, out var blockFunction, out var blockCallFunction, out var blockIncludes, out var blockDefines); + shaderGenerationData.m_ExpressionToName = BuildExpressionToName(context, taskData); + BuildContextBlocks(context, taskData, expressionToName, + out var blockFunction, + out var blockCallFunction, + out var blockIncludes, + out var blockDefines); //< Final composition var globalIncludeContent = new VFXShaderWriter(); @@ -727,7 +600,6 @@ AppendEventTotalCount({2}_{0}, min({1}_{0}, {1}_{0}_Capacity), instanceIndex); if (enableShaderDebugSymbols) { globalIncludeContent.WriteLine("#pragma enable_d3d11_debug_symbols"); - globalIncludeContent.WriteLine(); } globalIncludeContent.WriteLine("#define NB_THREADS_PER_GROUP " + nbThreadsPerGroup); @@ -752,13 +624,7 @@ AppendEventTotalCount({2}_{0}, min({1}_{0}, {1}_{0}_Capacity), instanceIndex); // We consider that tasks are always generating a compute shader. bool generateComputes = task.shaderType == VFXTaskShaderType.ComputeShader; - var renderTemplatePipePath = VFXLibrary.currentSRPBinder.templatePath; var renderRuntimePipePath = VFXLibrary.currentSRPBinder.runtimePath; - if (!generateComputes && !string.IsNullOrEmpty(renderTemplatePipePath)) - { - string renderPipePasses = renderTemplatePipePath + "/VFXPasses.template"; - globalIncludeContent.Write(GetFlattenedTemplateContent(renderPipePasses, new List(), allAdditionalDefines, dependencies)); - } if (contextData is ISpaceable) { @@ -781,90 +647,68 @@ AppendEventTotalCount({2}_{0}, min({1}_{0}, {1}_{0}_Capacity), instanceIndex); { perPassIncludeContent.WriteLine("#include \"Packages/com.unity.visualeffectgraph/Shaders/VFXCommonOutput.hlsl\""); } + if (taskData.linkedEventOut.Length > 0 || context.contextType == VFXContextType.Init) + perPassIncludeContent.WriteLine("#include \"Packages/com.unity.visualeffectgraph/Shaders/VFXGPUEvent.hlsl\""); + globalIncludeContent.Write(blockDefines.builder.ToString()); perPassIncludeContent.Write(blockIncludes.builder.ToString()); - ReplaceMultiline(stringBuilder, "${VFXGlobalInclude}", globalIncludeContent.builder); - ReplaceMultiline(stringBuilder, "${VFXGlobalDeclaration}", globalDeclaration.builder); - ReplaceMultiline(stringBuilder, "${VFXPerPassInclude}", perPassIncludeContent.builder); - ReplaceMultiline(stringBuilder, "${VFXGeneratedBlockFunction}", blockFunction.builder); - ReplaceMultiline(stringBuilder, "${VFXProcessBlocks}", blockCallFunction.builder); + codeGeneratorCache.TryAddSnippet("${VFXGlobalInclude}",globalIncludeContent.builder); + codeGeneratorCache.TryAddSnippet("${VFXGlobalDeclaration}", globalDeclaration.builder); + codeGeneratorCache.TryAddSnippet("${VFXPerPassInclude}", perPassIncludeContent.builder); + codeGeneratorCache.TryAddSnippet("${VFXGeneratedBlockFunction}", blockFunction.builder); + codeGeneratorCache.TryAddSnippet("${VFXProcessBlocks}", blockCallFunction.builder); VFXShaderWriter fillGraphValueStruct = new VFXShaderWriter(); fillGraphValueStruct.GenerateFillGraphValuesStruct(taskData.uniformMapper, particleData.graphValuesLayout); - ReplaceMultiline(stringBuilder, "${VFXLoadGraphValues}", fillGraphValueStruct.builder); + codeGeneratorCache.TryAddSnippet("${VFXLoadGraphValues}", fillGraphValueStruct.builder); VFXShaderWriter loadContextData = new VFXShaderWriter(); loadContextData.GenerateLoadContextData(particleData.graphValuesLayout); - ReplaceMultiline(stringBuilder, "${VFXLoadContextData}", loadContextData.builder); - - var mainParameters = taskData.gpuMapper.CollectExpression(-1).ToArray(); - foreach (var match in GetUniqueMatches("\\${VFXLoadParameter:{(.*?)}}", stringBuilder.ToString())) - { - var str = match.Groups[0].Value; - var pattern = match.Groups[1].Value; - var loadParameters = GenerateLoadParameter(pattern, mainParameters, expressionToName); - ReplaceMultiline(stringBuilder, str, loadParameters.builder); - } + codeGeneratorCache.TryAddSnippet("${VFXLoadContextData}", loadContextData.builder); + shaderGenerationData.m_MainParameters = taskData.gpuMapper.CollectExpression(-1).ToArray(); // Old SG integration - VFXOldShaderGraphHelpers.ReplaceShaderGraphTag(stringBuilder, context, mainParameters, expressionToName); + VFXOldShaderGraphHelpers.ReplaceShaderGraphTag(context, shaderGenerationData.m_MainParameters, expressionToName, codeGeneratorCache); //< Load Attribute - if (stringBuilder.ToString().Contains("${VFXLoadAttributes}")) - { - var loadAttributes = GenerateLoadAttribute(".*", context, taskData); - ReplaceMultiline(stringBuilder, "${VFXLoadAttributes}", loadAttributes.builder); - } - - foreach (var match in GetUniqueMatches("\\${VFXLoadAttributes:{(.*?)}}", stringBuilder.ToString())) - { - var str = match.Groups[0].Value; - var pattern = match.Groups[1].Value; - var loadAttributes = GenerateLoadAttribute(pattern, context, taskData); - ReplaceMultiline(stringBuilder, str, loadAttributes.builder); - } + var loadAttributes = GenerateLoadAttribute(null, context, taskData); + codeGeneratorCache.TryAddSnippet("${VFXLoadAttributes}", loadAttributes.builder); //< Store Attribute - if (stringBuilder.ToString().Contains("${VFXStoreAttributes}")) - { - var storeAttribute = GenerateStoreAttribute(".*", context, (uint)taskData.linkedEventOut.Length); - ReplaceMultiline(stringBuilder, "${VFXStoreAttributes}", storeAttribute.builder); - } - - foreach (var match in GetUniqueMatches("\\${VFXStoreAttributes:{(.*?)}}", stringBuilder.ToString())) - { - var str = match.Groups[0].Value; - var pattern = match.Groups[1].Value; - var storeAttributes = GenerateStoreAttribute(pattern, context, (uint)taskData.linkedEventOut.Length); - ReplaceMultiline(stringBuilder, str, storeAttributes.builder); - } + var storeAttribute = GenerateStoreAttribute(".*", context, (uint)taskData.linkedEventOut.Length); + codeGeneratorCache.TryAddSnippet("${VFXStoreAttributes}", storeAttribute.builder); //< Detect needed pragma require var useCubeArray = taskData.uniformMapper.textures.Any(o => o.valueType == VFXValueType.TextureCubeArray); var pragmaRequire = useCubeArray ? new StringBuilder("#pragma require cubearray") : new StringBuilder(); - ReplaceMultiline(stringBuilder, "${VFXPragmaRequire}", pragmaRequire); + codeGeneratorCache.TryAddSnippet("${VFXPragmaRequire}", pragmaRequire); + if (VFXLibrary.currentSRPBinder != null) { var allowedRenderers = new StringBuilder("#pragma only_renderers "); allowedRenderers.Append(String.Join(" ", VFXLibrary.currentSRPBinder.GetSupportedGraphicDevices().Select(d => DeviceTypeToShaderString(d)))); - ReplaceMultiline(stringBuilder, "${VFXPragmaOnlyRenderers}", allowedRenderers); + codeGeneratorCache.TryAddSnippet("${VFXPragmaOnlyRenderers}", allowedRenderers); } - foreach (var addionalReplacement in context.additionalReplacements) - { - ReplaceMultiline(stringBuilder, addionalReplacement.Key, addionalReplacement.Value.builder); - } + foreach (var additionalReplacement in context.additionalReplacements) + codeGeneratorCache.TryAddSnippet(additionalReplacement.Key, additionalReplacement.Value.builder); + + shaderGenerationData.m_Context = context; + shaderGenerationData.m_TaskData = taskData; + shaderGenerationData.m_Defines = allAdditionalDefines; + shaderGenerationData.m_Dependencies = dependencies; + shaderGenerationData.m_CodeGeneratorCache = codeGeneratorCache; + shaderGenerationData.m_HumanReadable = true; - // Replace defines - SubstituteMacros(stringBuilder); + StringBuilder shaderStringSb = VFXShaderSnippets.GenerateShaderCode(templatePath, shaderGenerationData); if (VFXViewPreference.advancedLogs) - Debug.LogFormat("GENERATED_OUTPUT_FILE_FOR : {0}\n{1}", context.ToString(), stringBuilder.ToString()); + Debug.LogFormat("GENERATED_OUTPUT_FILE_FOR : {0}\n{1}", context.ToString(), shaderStringSb.ToString()); context.EndCompilation(); Profiler.EndSample(); - return stringBuilder; + return shaderStringSb; } static string DeviceTypeToShaderString(GraphicsDeviceType deviceType) => deviceType switch @@ -1031,7 +875,8 @@ AppendEventTotalCount({2}_{0}, min({1}_{0}, {1}_{0}_Capacity), instanceIndex); blockCallFunction.WriteCallFunction(methodName, parameters, taskData.gpuMapper, - expressionToNameLocal); + expressionToNameLocal, + taskData.bufferTypeUsage); if (indexEventCount != -1) { diff --git a/Packages/com.unity.visualeffectgraph/Editor/Compiler/VFXExpressionGraph.cs b/Packages/com.unity.visualeffectgraph/Editor/Compiler/VFXExpressionGraph.cs index a7b0ac65..99ee206d 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/Compiler/VFXExpressionGraph.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/Compiler/VFXExpressionGraph.cs @@ -289,14 +289,14 @@ namespace UnityEditor.VFX public IEnumerable GlobalEventAttributes => m_GlobalEventAttributes; - public ReadOnlyDictionary GetBufferTypeUsage(VFXContext context) + public ReadOnlyDictionary GetBufferUsage(VFXContext context) { if (m_BufferTypeUsagePerContext.TryGetValue(context, out var bufferTypeUsage)) { - return new ReadOnlyDictionary(bufferTypeUsage); + return new ReadOnlyDictionary(bufferTypeUsage); } - return new ReadOnlyDictionary(new Dictionary()); + return new ReadOnlyDictionary(new Dictionary()); } public IHLSLCodeHolder[] GetCustomHLSLExpressions(VFXContext context) @@ -309,7 +309,7 @@ namespace UnityEditor.VFX } private Dictionary> m_CustomHLSLExpressionsPerContext = new(); - private Dictionary> m_BufferTypeUsagePerContext = new(); + private Dictionary> m_BufferTypeUsagePerContext = new(); private HashSet m_Expressions = new HashSet(); private Dictionary m_CPUExpressionsToReduced = new Dictionary(); private Dictionary m_GPUExpressionsToReduced = new Dictionary(); diff --git a/Packages/com.unity.visualeffectgraph/Editor/Compiler/VFXGraphCompiledData.cs b/Packages/com.unity.visualeffectgraph/Editor/Compiler/VFXGraphCompiledData.cs index 1206be92..bc98eb3d 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/Compiler/VFXGraphCompiledData.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/Compiler/VFXGraphCompiledData.cs @@ -66,7 +66,7 @@ namespace UnityEditor.VFX public VFXUniformMapper uniformMapper; public VFXSGInputs SGInputs; public List instancingSplitValues; - public ReadOnlyDictionary bufferUsage; + public ReadOnlyDictionary bufferTypeUsage; public VFXMapping[] parameters; public (VFXSlot slot, VFXData data)[] linkedEventOut; public IHLSLCodeHolder[] hlslCodeHolders; @@ -826,6 +826,7 @@ namespace UnityEditor.VFX Profiler.BeginSample("VFXEditor.GenerateShaders"); try { + var codeGeneratorCache = new VFXCodeGenerator.Cache(); var errorMessage = new StringBuilder(); foreach (var context in contexts) { @@ -842,11 +843,11 @@ namespace UnityEditor.VFX var contextData = compiledData.taskToCompiledData[task]; contextData.gpuMapper = gpuMapper; contextData.uniformMapper = uniformMapper; - contextData.bufferUsage = graph.GetBufferTypeUsage(context); + contextData.bufferTypeUsage = graph.GetBufferUsage(context); if (task.doesGenerateShader) { - var generatedContent = VFXCodeGenerator.Build(context, task, compilationMode, contextData, dependencies, enableShaderDebugSymbols, out var errors); + var generatedContent = VFXCodeGenerator.Build(context, task, compilationMode, contextData, dependencies, enableShaderDebugSymbols, codeGeneratorCache, out var errors); if (generatedContent != null && generatedContent.Length > 0) { contextData.indexInShaderSource = outGeneratedCodeData.Count; @@ -993,7 +994,8 @@ namespace UnityEditor.VFX if (capacity > 0) { eventBufferIndex = bufferDescs.Count; - bufferDescs.Add(new VFXGPUBufferDesc() { target = GraphicsBuffer.Target.Structured, size = capacity + 2, stride = 4 }); + // event count (1) + total event count (1) + event prefix sum (1) + source index (capacity) + bufferDescs.Add(new VFXGPUBufferDesc() { target = GraphicsBuffer.Target.Structured, size = 3 + capacity, stride = 4 }); } buffers.eventBuffers.Add(data, eventBufferIndex); } @@ -1410,11 +1412,6 @@ namespace UnityEditor.VFX reason |= VFXInstancingDisabledReason.OutputEvent; } - if (model is VFXBasicGPUEvent) - { - reason |= VFXInstancingDisabledReason.GPUEvent; - } - if (model is VFXStaticMeshOutput) { reason |= VFXInstancingDisabledReason.MeshOutput; @@ -1424,7 +1421,6 @@ namespace UnityEditor.VFX return reason; } - public VisualEffectResource visualEffectResource { get diff --git a/Packages/com.unity.visualeffectgraph/Editor/Compiler/VFXShaderSnippets.cs b/Packages/com.unity.visualeffectgraph/Editor/Compiler/VFXShaderSnippets.cs new file mode 100644 index 00000000..acfb379c --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Editor/Compiler/VFXShaderSnippets.cs @@ -0,0 +1,373 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace UnityEditor.VFX +{ + internal class VFXShaderSnippets + { + internal static StringBuilder GenerateShaderCode(string templatePath, ShaderGenerationData shaderGenerationData) + { + VFXSnippetNodeInclude rootNode = new VFXSnippetNodeInclude(templatePath, shaderGenerationData, ""); + StringBuilder shaderStringSb = new StringBuilder(); + rootNode.CollectChildren(); + rootNode.AppendContent(shaderStringSb); + return shaderStringSb; + } + + //This function insure to keep padding while replacing a specific string + private static string GetIndent(string src, int index) + { + int indentLength = 0; + index--; + while (index > 0 && (src[index] == ' ' || src[index] == '\t')) + { + index--; + indentLength++; + } + + if (indentLength > 0) + return src.Substring(index + 1, indentLength); + return string.Empty; + } + + private static string FormatPath(string path) + { + return Path.GetFullPath(path) + .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar) +#if !UNITY_EDITOR_LINUX + .ToLowerInvariant() +#endif + ; + } + + internal class ShaderGenerationData + { + internal Dictionary m_ExpressionToName; + internal VFXNamedExpression[] m_MainParameters; + internal VFXContext m_Context; + internal VFXTaskCompiledData m_TaskData; + internal HashSet m_Defines; + internal HashSet m_Dependencies; + internal VFXCodeGenerator.Cache m_CodeGeneratorCache; + internal bool m_HumanReadable; + } + + internal class VFXSnippetNode + { + private static readonly char[] kDefineSeparator = { ',', ' ', '\t' }; + private const string kVFXBeginStr = "${VFXBegin"; + private const string kVFXEndStr = "${VFXEnd"; + private const string kVFXIncludeStr = "${VFXInclude"; + private const string kVFXLoadParameterStr = "${VFXLoadParameter"; + private const string kVFXLoadAttributesStr = "${VFXLoadAttributes"; + private const string kVFXStoreAttributesStr = "${VFXStoreAttributes"; + protected const string kEndLineStr = "\n"; + + private List m_Children; + protected string m_CurrentIndent; + protected ShaderGenerationData m_ShaderGenerationData; + + public VFXSnippetNode(ShaderGenerationData shaderGenerationData, string indent) + { + this.m_ShaderGenerationData = shaderGenerationData; + this.m_CurrentIndent = indent; + } + + public virtual void AppendContent(StringBuilder sb) + { + if (m_Children != null) + { + foreach (var snippet in m_Children) + { + snippet.AppendContent(sb); + } + } + } + + //Returns endIndex + protected int CollectChildrenFromString(string templateContent, int startIndex) + { + int index; + while (true) + { + index = -1; + if (startIndex <= templateContent.Length) + index = templateContent.IndexOf("${", startIndex, StringComparison.Ordinal); + if (index == -1) + { + AddRawContent(templateContent, startIndex, templateContent.Length); + break; + } + + AddRawContent(templateContent, startIndex, index); + + ExtractSnippet(templateContent, index, out string snippetWithDecoration, out string snippetIndent); + + if (m_ShaderGenerationData.m_CodeGeneratorCache.TryGetSnippet(snippetWithDecoration, out StringBuilder snippetContent)) + { + VFXSnippetNodeLeaf snippetLeaf = new VFXSnippetNodeLeaf(snippetContent, m_ShaderGenerationData, m_CurrentIndent + snippetIndent); + AddChildNode(snippetLeaf); + startIndex = index + snippetWithDecoration.Length; + } + else if (snippetWithDecoration.StartsWith(kVFXLoadParameterStr, StringComparison.Ordinal)) + startIndex = HandleLoadParameter(templateContent, index, snippetIndent); + else if (snippetWithDecoration.StartsWith(kVFXLoadAttributesStr, StringComparison.Ordinal)) + startIndex = HandleLoadAttribute(templateContent, index, snippetIndent); + else if (snippetWithDecoration.StartsWith(kVFXStoreAttributesStr, StringComparison.Ordinal)) + startIndex = HandleStoreAttribute(templateContent, index, snippetIndent); + else if (snippetWithDecoration.StartsWith(kVFXBeginStr, StringComparison.Ordinal)) + startIndex = HandleBeginTag(templateContent, snippetWithDecoration, index); + else if (snippetWithDecoration.StartsWith(kVFXEndStr, StringComparison.Ordinal)) + return index + snippetWithDecoration.Length + 1; + else if (snippetWithDecoration.StartsWith(kVFXIncludeStr, StringComparison.Ordinal)) + startIndex = + HandleTemplateInclude(templateContent, index, snippetIndent, snippetWithDecoration); + else + startIndex = index + snippetWithDecoration.Length + 1; + } + + return index; + } + private void AddChildNode(VFXSnippetNode node) + { + if (m_Children == null) + m_Children = new List(); + m_Children.Add(node); + } + + private void ExtractSnippet(string templateContent, int startIndex, out string snippetWithDecoration, out string snippetIndent) + { + int endIndex = templateContent.IndexOf("}", startIndex, StringComparison.Ordinal); + snippetWithDecoration = templateContent.Substring(startIndex, endIndex - startIndex + 1); + snippetIndent = GetIndent(templateContent, startIndex); + } + + private void AddRawContent(string templateContent, int startIndex, int index) + { + string leafContent = templateContent.Substring(startIndex, index - startIndex); + if (!string.IsNullOrEmpty(leafContent)) + { + VFXSnippetNodeLeaf leaf = new VFXSnippetNodeLeaf(leafContent, m_ShaderGenerationData, m_CurrentIndent); + AddChildNode(leaf); + } + } + private void MatchTemplateIncludePattern(string templateContent, int index, out string includePath, out string includeDefinesRaw, out bool renderPipelineInclude) + { + int includeNameBeginIndex = templateContent.IndexOf("\"", index, StringComparison.Ordinal) + 1; + int includeNameEndIndex = templateContent.IndexOf("\"", includeNameBeginIndex + 1, StringComparison.Ordinal); + includePath = + templateContent.Substring(includeNameBeginIndex, includeNameEndIndex - includeNameBeginIndex); + + renderPipelineInclude = templateContent.IndexOf("RP", index, includeNameBeginIndex - index, StringComparison.Ordinal) != -1; + + int definesBeginIndex = includeNameEndIndex + 2; + int definesEndIndex = templateContent.IndexOf("}", definesBeginIndex, StringComparison.Ordinal); + includeDefinesRaw = templateContent.Substring(definesBeginIndex, definesEndIndex - definesBeginIndex); + } + + private int HandleTemplateInclude(string templateContent, int index, string snippetIndent, string snippetWithDecoration) + { + bool AcceptInclude(string includeDefinesFused) + { + var includeDefines = includeDefinesFused.Split(kDefineSeparator, StringSplitOptions.RemoveEmptyEntries); + foreach(var define in includeDefines) + { + if (define[0] != '!') + { + if (!m_ShaderGenerationData.m_Defines.Contains(define)) + return false; + } + else if (m_ShaderGenerationData.m_Defines.Contains(define.Substring(1))) + return false; + } + + return true; + } + + MatchTemplateIncludePattern(templateContent, index, out string includePath, + out string includeDefinesRaw, out bool renderPipelineInclude); + + if(string.IsNullOrEmpty(includeDefinesRaw) || AcceptInclude(includeDefinesRaw)) + { + string absolutePath = $"{(renderPipelineInclude ? VFXLibrary.currentSRPBinder.templatePath : VisualEffectGraphPackageInfo.assetPackagePath)}/{includePath}"; + VFXSnippetNodeInclude includeSnippetNode = new VFXSnippetNodeInclude(absolutePath, m_ShaderGenerationData, m_CurrentIndent + snippetIndent); + includeSnippetNode.CollectChildren(); + AddChildNode(includeSnippetNode); + } + + var startIndex = index + snippetWithDecoration.Length; + return startIndex; + } + + private int HandleBeginTag(string templateContent, string snippetWithDecoration, int index) + { + string macroName = snippetWithDecoration.Substring(kVFXBeginStr.Length + 1, + snippetWithDecoration.Length - kVFXBeginStr.Length - 2); + int startIndex = index + snippetWithDecoration.Length; + if (templateContent[startIndex] == '\n') + startIndex += 1; + VFXSnippetNodeMacroDefinition macroDefinitionNode = + new VFXSnippetNodeMacroDefinition(macroName, m_ShaderGenerationData, ""); + startIndex = macroDefinitionNode.CollectChildrenFromString(templateContent, startIndex); + macroDefinitionNode.ExpandMacroAndStore(); + AddChildNode(macroDefinitionNode); + return startIndex; + } + + private void MatchSnippetPattern(string templateContent, int index, out string key, out string pattern) + { + int endIndex = templateContent.IndexOf("}}", index, StringComparison.Ordinal) + 2; + int patternIndex = templateContent.IndexOf(":{", index, StringComparison.Ordinal) + 2; + key = templateContent.Substring(index, endIndex - index); + pattern = templateContent.Substring(patternIndex, endIndex - patternIndex - 2); + } + + private void AddLeafNodeFromShaderWriter(string snippetIndent, VFXShaderWriter shaderWriter, string str) + { + VFXSnippetNodeLeaf snippetNodeLeaf = new VFXSnippetNodeLeaf(shaderWriter.builder, + m_ShaderGenerationData, m_CurrentIndent + snippetIndent); + AddChildNode(snippetNodeLeaf); + m_ShaderGenerationData.m_CodeGeneratorCache.TryAddSnippet(str, shaderWriter.builder); + } + + private int HandleStoreAttribute(string templateContent, int index, string snippetIndent) + { + MatchSnippetPattern(templateContent, index, out string key, out string pattern); + var storeAttribute = VFXCodeGenerator.GenerateStoreAttribute(pattern, m_ShaderGenerationData.m_Context, + (uint)m_ShaderGenerationData.m_TaskData.linkedEventOut.Length); + AddLeafNodeFromShaderWriter(snippetIndent, storeAttribute, key); + int startIndex = index + key.Length + 1; + return startIndex; + } + + private int HandleLoadAttribute(string templateContent, int index, string snippetIndent) + { + MatchSnippetPattern(templateContent, index, out string key, out string pattern); + var loadAttribute = VFXCodeGenerator.GenerateLoadAttribute(pattern, m_ShaderGenerationData.m_Context, + m_ShaderGenerationData.m_TaskData); + AddLeafNodeFromShaderWriter(snippetIndent, loadAttribute, key); + int startIndex = index + key.Length + 1; + return startIndex; + } + + private int HandleLoadParameter(string templateContent, int index, string snippetIndent) + { + MatchSnippetPattern(templateContent, index, out string key, out string pattern); + var loadParameters = VFXCodeGenerator.GenerateLoadParameter(pattern, + m_ShaderGenerationData.m_MainParameters, m_ShaderGenerationData.m_ExpressionToName); + if (string.IsNullOrEmpty(loadParameters.ToString())) + loadParameters.builder.AppendLine(); + + AddLeafNodeFromShaderWriter(snippetIndent, loadParameters, key); + int startIndex = index + key.Length; + return startIndex; + } + } + + class VFXSnippetNodeLeaf : VFXSnippetNode + { + private StringBuilder m_LeafContentSb; + private string m_LeafContentStr; + + internal VFXSnippetNodeLeaf(StringBuilder leafContentSb, ShaderGenerationData shaderGenerationData, string indent) : base(shaderGenerationData, indent) + { + //Copy to not accumulate indent + this.m_LeafContentSb = new StringBuilder(); + this.m_LeafContentSb.Append(leafContentSb); + } + + internal VFXSnippetNodeLeaf(string leafContentStr, ShaderGenerationData shaderGenerationData, string indent) : base(shaderGenerationData, indent) + { + this.m_LeafContentStr = leafContentStr; + } + + public override void AppendContent(StringBuilder sb) + { + if (m_ShaderGenerationData.m_HumanReadable && m_CurrentIndent.Length > 0) + { + if (m_LeafContentSb != null) + { + m_LeafContentSb.Replace(kEndLineStr, kEndLineStr + m_CurrentIndent); + sb.Append(m_LeafContentSb); + } + else + { + var lines = m_LeafContentStr.Split(kEndLineStr, StringSplitOptions.None); + int i = 0; + foreach (var line in lines) + { + if (i > 0) + sb.Append(kEndLineStr + m_CurrentIndent); + sb.Append(line); + i++; + } + } + } + else + { + if (m_LeafContentSb != null) + sb.Append(m_LeafContentSb); + else + sb.Append(m_LeafContentStr); + } + } + } + + internal class VFXSnippetNodeInclude : VFXSnippetNode + { + private string m_IncludePath; + + internal VFXSnippetNodeInclude(string includePath, ShaderGenerationData shaderGenerationData, string indent) : base(shaderGenerationData, indent) + { + this.m_IncludePath = includePath; + } + + public void CollectChildren() + { + if (!m_ShaderGenerationData.m_CodeGeneratorCache.TryGetTemplateCache(m_IncludePath, out var templateContent)) + { + m_ShaderGenerationData.m_Dependencies.Add(AssetDatabase.AssetPathToGUID(m_IncludePath)); + var formattedPath = FormatPath(m_IncludePath); + templateContent = File.ReadAllText(formattedPath); + m_ShaderGenerationData.m_CodeGeneratorCache.AddTemplateCache(m_IncludePath, templateContent); + } + CollectChildrenFromString(templateContent, 0); + } + } + + class VFXSnippetNodeMacroDefinition : VFXSnippetNode + { + private string m_MacroName; + private StringBuilder m_ExpandedMacro; + private bool m_Expanded; + + internal VFXSnippetNodeMacroDefinition(string macroName, ShaderGenerationData shaderGenerationData, + string indent) : base(shaderGenerationData, indent) + { + this.m_MacroName = macroName; + } + + public void ExpandMacroAndStore() + { + StringBuilder sb = new StringBuilder(); + AppendContent(sb); + m_ExpandedMacro = sb; + string snippetizedMacroName = $"${{{m_MacroName}}}"; + if (!m_ShaderGenerationData.m_CodeGeneratorCache.TryAddSnippet(snippetizedMacroName, m_ExpandedMacro)) + { + m_ShaderGenerationData.m_CodeGeneratorCache.SetSnippet(snippetizedMacroName,m_ExpandedMacro); + } + + m_Expanded = true; + } + + public override void AppendContent(StringBuilder sb) + { + if (!m_Expanded) + base.AppendContent(sb); + } + } + } +} diff --git a/Packages/com.unity.visualeffectgraph/Editor/Compiler/VFXShaderSnippets.cs.meta b/Packages/com.unity.visualeffectgraph/Editor/Compiler/VFXShaderSnippets.cs.meta new file mode 100644 index 00000000..516c437a --- /dev/null +++ b/Packages/com.unity.visualeffectgraph/Editor/Compiler/VFXShaderSnippets.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7245be2bea814067bbd30db1d94c2cb4 +timeCreated: 1720614463 \ No newline at end of file diff --git a/Packages/com.unity.visualeffectgraph/Editor/Compiler/VFXShaderWriter.cs b/Packages/com.unity.visualeffectgraph/Editor/Compiler/VFXShaderWriter.cs index 11118af2..90dd7922 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/Compiler/VFXShaderWriter.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/Compiler/VFXShaderWriter.cs @@ -303,9 +303,9 @@ namespace UnityEditor.VFX } } - public void WriteBufferTypeDeclaration(IEnumerable usages) + public void WriteBufferTypeDeclaration(IEnumerable bufferTypeUsage) { - var types = usages.Select(usage => + var types = bufferTypeUsage.Select(usage => { var type = usage.actualType; if (IsBufferBuiltinType(type)) @@ -327,7 +327,7 @@ namespace UnityEditor.VFX } } - public void WriteBuffer(VFXUniformMapper mapper, ReadOnlyDictionary usageBuffer) + public void WriteBuffer(VFXUniformMapper mapper, ReadOnlyDictionary usageBuffer) { foreach (var buffer in mapper.buffers) { @@ -346,7 +346,7 @@ namespace UnityEditor.VFX } } - public void WriteTexture(VFXUniformMapper mapper, IEnumerable skipNames = null) + public void WriteTexture(VFXUniformMapper mapper, ReadOnlyDictionary bufferTypeUsage, IEnumerable skipNames = null) { foreach (var texture in mapper.textures) { @@ -358,7 +358,15 @@ namespace UnityEditor.VFX if (skipNames != null && skipNames.Contains(name)) continue; - WriteLineFormat("{0} {1};", VFXExpression.TypeToCode(texture.valueType), name); + if (bufferTypeUsage.TryGetValue(texture, out var usage)) + { + WriteLineFormat("{0} {1};", GetBufferDeclaration(usage), name); + } + else + { + WriteLineFormat("{0} {1};", VFXExpression.TypeToCode(texture.valueType), name); + } + if (VFXExpression.IsTexture(texture.valueType)) //Mesh doesn't require a sampler or texel helper { WriteLineFormat("SamplerState sampler{0};", name); @@ -494,20 +502,23 @@ namespace UnityEditor.VFX return parameters.Count == 0 ? "" : parameters.Aggregate((a, b) => a + ", " + b); } - private static string GetBufferDeclaration(BufferUsage bufferUsage) + private static string GetBufferDeclaration(BufferType bufferType) { - if (string.IsNullOrEmpty(bufferUsage.verbatimType)) - return bufferUsage.container.ToString(); + if (string.IsNullOrEmpty(bufferType.verbatimType)) + return bufferType.container.ToString(); - var verbatimType = IsBufferBuiltinType(bufferUsage.actualType) - ? VFXExpression.TypeToCode(VFXExpression.GetVFXValueTypeFromType(bufferUsage.actualType)) - : bufferUsage.verbatimType; + var verbatimType = IsBufferBuiltinType(bufferType.actualType) + ? VFXExpression.TypeToCode(VFXExpression.GetVFXValueTypeFromType(bufferType.actualType)) + : bufferType.verbatimType; - return $"{bufferUsage.container}<{verbatimType}>"; + return $"{bufferType.container}<{verbatimType}>"; } - private static string GetFunctionParameterType(VFXExpression exp, ReadOnlyDictionary usages) + private static string GetFunctionParameterType(VFXExpression exp, ReadOnlyDictionary usages) { + if (usages.TryGetValue(exp, out var usage)) + return GetBufferDeclaration(usage); + switch (exp.valueType) { case VFXValueType.Texture2D: return "VFXSampler2D"; @@ -517,15 +528,13 @@ namespace UnityEditor.VFX case VFXValueType.TextureCubeArray: return "VFXSamplerCubeArray"; case VFXValueType.CameraBuffer: return "VFXSamplerCameraBuffer"; case VFXValueType.Buffer: - if (!usages.TryGetValue(exp, out var usage)) - throw new KeyNotFoundException("Cannot find appropriate usage for " + exp); - return GetBufferDeclaration(usage); + throw new KeyNotFoundException("Cannot find appropriate usage for " + exp); default: return VFXExpression.TypeToCode(exp.valueType); } } - private static string GetFunctionParameterName(VFXExpression expression, Dictionary names) + private static string GetFunctionParameterName(VFXExpression expression, Dictionary names, ReadOnlyDictionary textureBufferUsages) { var expressionName = names[expression]; switch (expression.valueType) @@ -534,7 +543,10 @@ namespace UnityEditor.VFX case VFXValueType.Texture2DArray: case VFXValueType.Texture3D: case VFXValueType.TextureCube: - case VFXValueType.TextureCubeArray: return string.Format("GetVFXSampler({0}, {1})", expressionName, ("sampler" + expressionName)); + case VFXValueType.TextureCubeArray: + if (textureBufferUsages.TryGetValue(expression, out var textureUsage)) + return expressionName; + return string.Format("GetVFXSampler({0}, {1})", expressionName, ("sampler" + expressionName)); case VFXValueType.CameraBuffer: return string.Format("GetVFXSampler({0}, {1})", expressionName, ("sampler" + expressionName)); default: @@ -563,7 +575,7 @@ namespace UnityEditor.VFX foreach (var parameter in parameters) { var inputModifier = GetInputModifier(parameter.mode); - var parameterType = GetFunctionParameterType(parameter.expression, taskData.bufferUsage); + var parameterType = GetFunctionParameterType(parameter.expression, taskData.bufferTypeUsage); parametersCode.Add(string.Format("{0}{1} {2}", inputModifier, parameterType, parameter.name)); } @@ -579,13 +591,13 @@ namespace UnityEditor.VFX ExitScope(); } - public void WriteCallFunction(string functionName, IEnumerable parameters, VFXExpressionMapper mapper, Dictionary variableNames) + public void WriteCallFunction(string functionName, IEnumerable parameters, VFXExpressionMapper mapper, Dictionary variableNames, ReadOnlyDictionary textureBufferUsages) { var parametersCode = new List(); foreach (var parameter in parameters) { var inputModifier = GetInputModifier(parameter.mode); - parametersCode.Add(string.Format("{1}{0}", GetFunctionParameterName(parameter.expression, variableNames), string.IsNullOrEmpty(inputModifier) ? string.Empty : string.Format(" /*{0}*/", inputModifier))); + parametersCode.Add(string.Format("{1}{0}", GetFunctionParameterName(parameter.expression, variableNames, textureBufferUsages), string.IsNullOrEmpty(inputModifier) ? string.Empty : string.Format(" /*{0}*/", inputModifier))); } WriteLineFormat("{0}({1});", functionName, AggregateParameters(parametersCode)); diff --git a/Packages/com.unity.visualeffectgraph/Editor/Controls/VFXSliderField.cs b/Packages/com.unity.visualeffectgraph/Editor/Controls/VFXSliderField.cs index 23f003d8..8d90de87 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/Controls/VFXSliderField.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/Controls/VFXSliderField.cs @@ -76,7 +76,7 @@ namespace UnityEditor.VFX.UI } } - abstract class VFXBaseSliderField : VisualElement, INotifyValueChanged + abstract class VFXBaseSliderField : VisualElement, IVFXNotifyValueChanged { protected readonly Slider m_Slider; protected readonly TextValueField m_Field; @@ -160,6 +160,11 @@ namespace UnityEditor.VFX.UI SetValueWithoutNotify(ValueToFloat(newValue), newValue); } + public void SetValueWithoutNotify(T newValue, bool force) + { + SetValueWithoutNotify(ValueToFloat(newValue), newValue, force); + } + public T value { get => m_Value; diff --git a/Packages/com.unity.visualeffectgraph/Editor/Core/VFXLibrary.cs b/Packages/com.unity.visualeffectgraph/Editor/Core/VFXLibrary.cs index c5148cbb..0fcf1e7e 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/Core/VFXLibrary.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/Core/VFXLibrary.cs @@ -35,7 +35,11 @@ namespace UnityEditor.VFX this.synonyms = synonyms ?? Array.Empty(); } - public virtual string GetDocumentationLink() => VFXHelpURLAttribute.GetHelpUrl(modelType); + public virtual string GetDocumentationLink() + { + DocumentationUtils.TryGetHelpURL(modelType, out var url); + return url; + } public virtual VFXModel CreateInstance() { diff --git a/Packages/com.unity.visualeffectgraph/Editor/Data/VFXDataParticle.cs b/Packages/com.unity.visualeffectgraph/Editor/Data/VFXDataParticle.cs index 917f9d5d..b13bf2e7 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/Data/VFXDataParticle.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/Data/VFXDataParticle.cs @@ -11,7 +11,7 @@ namespace UnityEditor.VFX { interface ILayoutProvider { - void GenerateAttributeLayout(uint capacity, Dictionary storedAttribute); + void GenerateAttributeLayout(uint capacity, Dictionary storedAttribute, bool splitBuckets); string GetCodeOffset(VFXAttribute attrib, uint capacity, string index, string instanceIndex); uint GetBufferSize(uint capacity); @@ -32,8 +32,14 @@ namespace UnityEditor.VFX } } - // return size - private int GenerateBucketLayout(List attributes, int bucketId) + private void AddBucket(int capacity, int bucketId, int currentOffset) + { + int bucketOffset = bucketId == 0 ? 0 : m_BucketOffsets[bucketId - 1] + capacity * m_BucketSizes[bucketId - 1]; + m_BucketOffsets.Add((bucketOffset + 3) & ~3); // align on dword; + m_BucketSizes.Add(currentOffset); + } + + private void AddAttributeBuckets(List attributes, int capacity, ref int bucketId, bool splitBuckets) { var sortedAttrib = attributes.OrderByDescending(a => VFXValue.TypeToSize(a.type)); @@ -48,52 +54,55 @@ namespace UnityEditor.VFX } int currentOffset = 0; - int minAlignment = 0; foreach (var block in attribBlocks) { + if (splitBuckets) + currentOffset = 0; + foreach (var attrib in block) { int size = VFXValue.TypeToSize(attrib.type); - int alignment = size > 2 ? 4 : size; - minAlignment = Math.Max(alignment, minAlignment); - // align offset - currentOffset = (currentOffset + alignment - 1) & ~(alignment - 1); m_AttributeLayout.Add(attrib, new AttributeLayout(bucketId, currentOffset)); currentOffset += size; } + if (splitBuckets) + { + AddBucket(capacity, bucketId, currentOffset); + bucketId++; + } + } + if (!splitBuckets) + { + AddBucket(capacity, bucketId, currentOffset); + bucketId++; } - - return (currentOffset + minAlignment - 1) & ~(minAlignment - 1); } - public void GenerateAttributeLayout(uint capacity, Dictionary storedAttribute) + public void GenerateAttributeLayout(uint capacity, Dictionary storedAttribute, bool splitBuckets = true) { m_BucketSizes.Clear(); m_AttributeLayout.Clear(); m_BucketOffsets.Clear(); - var attributeBuckets = new Dictionary>(); + var attributeGroups = new Dictionary>(); foreach (var kvp in storedAttribute) { List attributes; - if (!attributeBuckets.ContainsKey(kvp.Value)) + if (!attributeGroups.ContainsKey(kvp.Value)) { attributes = new List(); - attributeBuckets[kvp.Value] = attributes; + attributeGroups[kvp.Value] = attributes; } else - attributes = attributeBuckets[kvp.Value]; + attributes = attributeGroups[kvp.Value]; attributes.Add(kvp.Key); } int bucketId = 0; - foreach (var bucket in attributeBuckets) + foreach (var group in attributeGroups) { - int bucketOffset = bucketId == 0 ? 0 : m_BucketOffsets[bucketId - 1] + (int)capacity * m_BucketSizes[bucketId - 1]; - m_BucketOffsets.Add((bucketOffset + 3) & ~3); // align on dword; - m_BucketSizes.Add(GenerateBucketLayout(bucket.Value, bucketId)); - ++bucketId; + AddAttributeBuckets(group.Value, (int)capacity, ref bucketId, splitBuckets); } // Debug log @@ -252,7 +261,9 @@ namespace UnityEditor.VFX SerializeField] public BoundsSettingMode boundsMode = BoundsSettingMode.Recorded; - public bool hasStrip { get { return dataType == DataType.ParticleStrip; } } + public bool hasStrip => dataType == DataType.ParticleStrip; + public bool hasAttachedStrip => IsAttributeStored(VFXAttribute.StripAlive); + public VFXDataParticle attachedStripData => (VFXDataParticle)dependenciesOut.FirstOrDefault(d => ((VFXDataParticle)d).hasStrip); // TODO Handle several strip attached public override void OnSettingModified(VFXSetting setting) { @@ -333,6 +344,12 @@ namespace UnityEditor.VFX yield return "#define STRIP_COUNT " + stripCapacity + "u"; yield return "#define PARTICLE_PER_STRIP_COUNT " + particlePerStripCount + "u"; } + if (hasAttachedStrip) + { + var stripData = attachedStripData; + yield return "#define ATTACHED_STRIP_COUNT " + stripData.stripCapacity + "u"; + } + yield return "#define RAW_CAPACITY " + capacity + "u"; } } @@ -485,7 +502,7 @@ namespace UnityEditor.VFX else { var readSourceAttribute = m_ReadSourceAttributes.ToDictionary(o => o, _ => (int)VFXAttributeMode.ReadSource); - m_layoutAttributeSource.GenerateAttributeLayout(m_SourceCount, readSourceAttribute); + m_layoutAttributeSource.GenerateAttributeLayout(m_SourceCount, readSourceAttribute, false); m_ownAttributeSourceBuffer = true; } } @@ -520,27 +537,30 @@ namespace UnityEditor.VFX public override string GetLoadAttributeCode(VFXAttribute attrib, VFXAttributeLocation location) { - var attributeStore = location == VFXAttributeLocation.Current ? m_layoutAttributeCurrent : m_layoutAttributeSource; - var attributeBuffer = location == VFXAttributeLocation.Current ? "attributeBuffer" : "sourceAttributeBuffer"; - var parent = m_DependenciesIn.OfType().FirstOrDefault(); + bool attribFound = false; + string attributeBuffer = null; + string codeOffset = null; - uint attributeCapacity; if (location == VFXAttributeLocation.Current) - attributeCapacity = alignedCapacity; - else - attributeCapacity = (parent != null) ? parent.capacity : staticSourceCount; - - var index = location == VFXAttributeLocation.Current ? "index" : "sourceIndex"; - - if (location == VFXAttributeLocation.Current && !m_StoredCurrentAttributes.ContainsKey(attrib)) - throw new ArgumentException(string.Format("Attribute {0} does not exist in data layout", attrib.name)); + { + attribFound = m_StoredCurrentAttributes.ContainsKey(attrib); + attributeBuffer = "attributeBuffer"; + codeOffset = m_layoutAttributeCurrent.GetCodeOffset(attrib, alignedCapacity, "index", "instanceIndex"); + } + else // source attributes + { + attribFound = m_ReadSourceAttributes.Any(a => a.name == attrib.name); + attributeBuffer = "sourceAttributeBuffer"; + var parent = m_DependenciesIn.OfType().FirstOrDefault(); + if (parent != null) + codeOffset = m_layoutAttributeSource.GetCodeOffset(attrib, parent.alignedCapacity, "sourceIndex", "instanceIndex"); + else + codeOffset = m_layoutAttributeSource.GetCodeOffset(attrib, "sourceIndex", "startEventIndex"); + } - if (location == VFXAttributeLocation.Source && !m_ReadSourceAttributes.Any(a => a.name == attrib.name)) + if (!attribFound) throw new ArgumentException(string.Format("Attribute {0} does not exist in data layout", attrib.name)); - string codeOffset = location == VFXAttributeLocation.Current - ? attributeStore.GetCodeOffset(attrib, attributeCapacity, index, "instanceIndex") - : attributeStore.GetCodeOffset(attrib, index, "startEventIndex"); return string.Format("{0}({3}.Load{1}({2}))", GetCastAttributePrefix(attrib), GetByteAddressBufferMethodSuffix(attrib), codeOffset, attributeBuffer); } @@ -1113,9 +1133,17 @@ namespace UnityEditor.VFX { FillGraphValuesBuffers(outBufferDescs, systemBufferMappings, m_GraphValuesLayout, out graphValuesBufferIndex); - FillPrefixSumBuffers(outBufferDescs, systemBufferMappings, staticSourceCount, - out instancesPrefixSumBufferIndex, - out spawnBufferIndex); + if (eventGPUFrom != -1) + { + // For GPU events, take the prefix sum from the same buffer as the events + instancesPrefixSumBufferIndex = eventGPUFrom; + } + else + { + FillPrefixSumBuffers(outBufferDescs, systemBufferMappings, staticSourceCount, + out instancesPrefixSumBufferIndex, + out spawnBufferIndex); + } } // sort buffers @@ -1278,11 +1306,9 @@ namespace UnityEditor.VFX } } - bool hasAttachedStrip = IsAttributeStored(VFXAttribute.StripAlive); if (hasAttachedStrip) { - var stripData = dependenciesOut.First(d => ((VFXDataParticle)d).hasStrip); // TODO Handle several strip attached - bufferMappings.Add(new VFXMapping("attachedStripDataBuffer", dependentBuffers.stripBuffers[stripData])); + bufferMappings.Add(new VFXMapping("attachedStripDataBuffer", dependentBuffers.stripBuffers[attachedStripData])); } if (needsIndirectBuffer && task.needsIndirectBuffer) @@ -1449,7 +1475,11 @@ namespace UnityEditor.VFX } outBufferDescs[instancingIndirectAndActiveIndirectBufferIndex] = new VFXGPUBufferDesc() { target = GraphicsBuffer.Target.Structured, size = 1u + (uint)instanceSplitDescs.Count() , stride = 4, mode = ComputeBufferMode.Dynamic }; - outBufferDescs[instancesPrefixSumBufferIndex] = new VFXGPUBufferDesc() { target = GraphicsBuffer.Target.Structured, size = (uint)instanceSplitDescs.Count() + 1u, stride = 4, mode = ComputeBufferMode.Dynamic }; + + if (instancesPrefixSumBufferIndex != -1 && eventGPUFrom == -1) // only if we have a prefix sum and we are not reusing the GPU event buffer + { + outBufferDescs[instancesPrefixSumBufferIndex] = new VFXGPUBufferDesc() { target = GraphicsBuffer.Target.Structured, size = (uint)instanceSplitDescs.Count() + 1u, stride = 4, mode = ComputeBufferMode.Dynamic }; + } if (hasStrip && hasKill) { diff --git a/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionContext.cs b/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionContext.cs index 0a9f2d59..bef95faf 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionContext.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionContext.cs @@ -181,7 +181,7 @@ namespace UnityEditor.VFX m_GraphicsBufferTypeUsagePerContext.Add(context, usages); } - var usage = expressionBufferWithTypeCollection.Key.usage; + var usage = expressionBufferWithTypeCollection.Key.Type; var buffer = expressionBufferWithTypeCollection.Key.parents[0]; if (!usages.TryAdd(buffer, usage) && usages[buffer] != usage) { @@ -209,14 +209,14 @@ namespace UnityEditor.VFX using (s_CompileExpressionContext.Auto()) { - bool needToPatch = HasAny(VFXExpressionContextOption.GPUDataTransformation | VFXExpressionContextOption.PatchReadToEventAttribute); - var gpuTransformation = needToPatch && Has(VFXExpressionContextOption.GPUDataTransformation); - var spawnEventPath = needToPatch && Has(VFXExpressionContextOption.PatchReadToEventAttribute); - foreach (var exp in m_EndExpressions) - { Compile(exp.Key); - if (needToPatch) + + if (HasAny(VFXExpressionContextOption.GPUDataTransformation | VFXExpressionContextOption.PatchReadToEventAttribute)) + { + var gpuTransformation = Has(VFXExpressionContextOption.GPUDataTransformation); + var spawnEventPath = Has(VFXExpressionContextOption.PatchReadToEventAttribute); + foreach (var exp in m_EndExpressions) m_ReducedCache[exp.Key] = PatchVFXExpression(GetReduced(exp.Key), null /* no source in end expression */, gpuTransformation, spawnEventPath, m_GlobalEventAttribute); } } @@ -321,7 +321,7 @@ namespace UnityEditor.VFX } } - if (input.valueType == VFXValueType.Buffer && input is VFXExpressionBufferWithType bufferWithType) + if (input is VFXExpressionBufferWithType bufferWithType) { input = input.parents[0]; //Explicitly skip NoOp expression } @@ -426,14 +426,13 @@ namespace UnityEditor.VFX } public IEnumerable RegisteredExpressions => m_EndExpressions.Keys; - - public Dictionary> GraphicsBufferTypeUsagePerContext => m_GraphicsBufferTypeUsagePerContext; + public Dictionary> GraphicsBufferTypeUsagePerContext => m_GraphicsBufferTypeUsagePerContext; public Dictionary> hlslCodeHoldersPerContext => m_HLSLCollectionPerContext; - private Dictionary m_ReducedCache = new (); + private Dictionary m_ReducedCache = new(); private Dictionary> m_EndExpressions = new (); - private Dictionary> m_GraphicsBufferTypeUsagePerContext = new (); + private Dictionary> m_GraphicsBufferTypeUsagePerContext = new (); private IEnumerable m_GlobalEventAttribute; private VFXExpressionContextOption m_ReductionOptions; diff --git a/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionHLSL.cs b/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionHLSL.cs index 1ad158e7..9014df2a 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionHLSL.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionHLSL.cs @@ -11,29 +11,42 @@ namespace UnityEditor.VFX string m_FunctionName; VFXValueType m_ValueType; string m_HlslCode; - List m_TextureParentExpressionIndex; + int[] m_TextureSamplerParentExpressionIndex; string[] m_Includes; public VFXExpressionHLSL() : this(string.Empty, string.Empty, VFXValueType.None, new [] { VFXValue.Default }, Array.Empty()) { } - public VFXExpressionHLSL(string functionName, string hlslCode, VFXValueType returnType, VFXExpression[] parents, string[] includes) : base(Flags.InvalidOnCPU, parents) + public VFXExpressionHLSL(string functionName, string hlslCode, System.Type returnType, VFXExpression[] parents, string[] includes) : this(functionName, hlslCode, GetVFXValueTypeFromType(returnType), parents, includes) { - this.m_TextureParentExpressionIndex = new List(); - this.m_FunctionName = functionName; - this.m_ValueType = returnType; - this.m_HlslCode = hlslCode; - this.m_Includes = includes; } - public VFXExpressionHLSL(string functionName, string hlslCode, System.Type returnType, VFXExpression[] parents, string[] includes) : base(Flags.InvalidOnCPU, parents) + public VFXExpressionHLSL(string functionName, string hlslCode, VFXValueType returnType, VFXExpression[] parents, string[] includes) : base(Flags.InvalidOnCPU, parents) { - this.m_TextureParentExpressionIndex = new List(); this.m_FunctionName = functionName; - this.m_ValueType = GetVFXValueTypeFromType(returnType); + this.m_ValueType = returnType; this.m_HlslCode = hlslCode; this.m_Includes = includes; + + List samplerExpression = null; + for (int i = 0; i < parents.Length; i++) + { + if (parents[i] is not VFXExpressionBufferWithType && IsTexture(parents[i].valueType)) + { + samplerExpression ??= new List(); + samplerExpression.Add(i); + } + } + + if (samplerExpression != null) + { + this.m_TextureSamplerParentExpressionIndex = samplerExpression.ToArray(); + } + else + { + this.m_TextureSamplerParentExpressionIndex = Array.Empty(); + } } public override VFXValueType valueType => m_ValueType; @@ -84,27 +97,18 @@ namespace UnityEditor.VFX protected override VFXExpression Reduce(VFXExpression[] reducedParents) { - m_TextureParentExpressionIndex.Clear(); - for (int i = 0; i < reducedParents.Length; i++) - { - if (IsTexture(reducedParents[i].valueType)) - { - m_TextureParentExpressionIndex.Add(i); - } - } - var newExpression = (VFXExpressionHLSL)base.Reduce(reducedParents); newExpression.m_FunctionName = m_FunctionName; newExpression.m_ValueType = m_ValueType; newExpression.m_HlslCode = m_HlslCode; - newExpression.m_TextureParentExpressionIndex = new List(m_TextureParentExpressionIndex); + newExpression.m_TextureSamplerParentExpressionIndex = (int[])m_TextureSamplerParentExpressionIndex.Clone(); newExpression.m_Includes = (string[])m_Includes.Clone(); return newExpression; } public sealed override string GetCodeString(string[] parentsExpressions) { - foreach (var index in m_TextureParentExpressionIndex) + foreach (var index in m_TextureSamplerParentExpressionIndex) { var expression = parentsExpressions[index]; parentsExpressions[index] = $"VFX_SAMPLER({expression})"; diff --git a/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionTextureValues.cs b/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionTextureValues.cs index 1192714e..40f80751 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionTextureValues.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionTextureValues.cs @@ -152,7 +152,7 @@ namespace UnityEditor.VFX } } - struct BufferUsage : IEquatable + struct BufferType : IEquatable { public enum Container { @@ -163,9 +163,22 @@ namespace UnityEditor.VFX Buffer, RWBuffer, AppendStructuredBuffer, - ConsumeStructuredBuffer - - //Can be extended to integrate RWTexture2D here + ConsumeStructuredBuffer, + + Texture1D, + Texture2D, + Texture3D, + TextureCube, + Texture1DArray, + Texture2DArray, + TextureCubeArray, + RWTexture1D, + RWTexture2D, + RWTexture3D, + RWTextureCube, + RWTexture1DArray, + RWTexture2DArray, + RWTextureCubeArray, } public Container container { get; private set; } @@ -173,21 +186,21 @@ namespace UnityEditor.VFX public string verbatimType { get; private set; } public bool valid => actualType != null; - public BufferUsage(Container container, string verbatimType, Type actualType) + public BufferType(Container container, string verbatimType, Type actualType) { this.container = container; this.actualType = actualType; this.verbatimType = verbatimType; } - public bool Equals(BufferUsage other) + public bool Equals(BufferType other) { return container == other.container && actualType == other.actualType && verbatimType == other.verbatimType; } public override bool Equals(object obj) { - return obj is BufferUsage other && Equals(other); + return obj is BufferType other && Equals(other); } public override int GetHashCode() @@ -195,20 +208,20 @@ namespace UnityEditor.VFX return HashCode.Combine(container, actualType, verbatimType); } - public static bool operator ==(BufferUsage lhs, BufferUsage rhs) => lhs.Equals(rhs); - public static bool operator !=(BufferUsage lhs, BufferUsage rhs) => !(lhs == rhs); + public static bool operator ==(BufferType lhs, BufferType rhs) => lhs.Equals(rhs); + public static bool operator !=(BufferType lhs, BufferType rhs) => !(lhs == rhs); } #pragma warning disable 0659 sealed class VFXExpressionBufferWithType : VFXExpression { - public VFXExpressionBufferWithType() : this(new BufferUsage(), VFXValue.Default) + public VFXExpressionBufferWithType() : this(new BufferType(), VFXValue.Default) { } - public VFXExpressionBufferWithType(BufferUsage usage, VFXExpression graphicsBuffer) : base(Flags.None, new[] { graphicsBuffer }) + public VFXExpressionBufferWithType(BufferType type, VFXExpression buffer) : base(Flags.None, new[] { buffer }) { - this.usage = usage; + this.Type = type; } public override VFXExpressionOperation operation => VFXExpressionOperation.None; @@ -218,7 +231,7 @@ namespace UnityEditor.VFX protected override VFXExpression Reduce(VFXExpression[] reducedParents) { var reduced = (VFXExpressionBufferWithType)base.Reduce(reducedParents); - reduced.usage = usage; + reduced.Type = Type; return reduced; } @@ -230,7 +243,7 @@ namespace UnityEditor.VFX protected override int GetInnerHashCode() { - return HashCode.Combine(base.GetInnerHashCode(), usage.GetHashCode()); + return HashCode.Combine(base.GetInnerHashCode(), Type.GetHashCode()); } public override bool Equals(object obj) @@ -242,10 +255,10 @@ namespace UnityEditor.VFX if (other == null) return false; - return other.usage == usage; + return other.Type == Type; } - public BufferUsage usage { get; private set; } + public BufferType Type { get; private set; } } #pragma warning restore 0659 } diff --git a/Packages/com.unity.visualeffectgraph/Editor/FilterPopup/VFXFilterWindow.cs b/Packages/com.unity.visualeffectgraph/Editor/FilterPopup/VFXFilterWindow.cs index 51cff4fc..bb1b84d4 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/FilterPopup/VFXFilterWindow.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/FilterPopup/VFXFilterWindow.cs @@ -7,6 +7,7 @@ using Unity.Profiling; using Unity.UI.Builder; using UnityEditor.UIElements; using UnityEngine; +using UnityEngine.Rendering; using UnityEngine.UIElements; namespace UnityEditor.VFX.UI @@ -492,7 +493,7 @@ namespace UnityEditor.VFX.UI var docLink = descriptor.GetDocumentationLink(); if (!string.IsNullOrEmpty(docLink)) { - Help.BrowseURL(string.Format(docLink, VFXHelpURLAttribute.version)); + Help.BrowseURL(string.Format(docLink, Documentation.version)); } } } diff --git a/Packages/com.unity.visualeffectgraph/Editor/GraphView/Blackboard/VFXBlackboard.cs b/Packages/com.unity.visualeffectgraph/Editor/GraphView/Blackboard/VFXBlackboard.cs index 6314210c..f51cb0f8 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/GraphView/Blackboard/VFXBlackboard.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/GraphView/Blackboard/VFXBlackboard.cs @@ -1225,6 +1225,11 @@ namespace UnityEditor.VFX.UI return m_Treeview.Query().Where(x => attributeNames.Any(y => VFXAttributeHelper.IsMatching(y, x.attribute.title, true))).ToList(); } + public void ClearAllAttributesHighlights() + { + m_Treeview.Query().ForEach(r => r.RemoveFromClassList("hovered")); + } + public void OnControllerChanged(ref ControllerChangedEvent e) { switch (e.change) diff --git a/Packages/com.unity.visualeffectgraph/Editor/GraphView/Blackboard/VFXBlackboardFieldBase.cs b/Packages/com.unity.visualeffectgraph/Editor/GraphView/Blackboard/VFXBlackboardFieldBase.cs index dc3a4c6a..c71c0eb9 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/GraphView/Blackboard/VFXBlackboardFieldBase.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/GraphView/Blackboard/VFXBlackboardFieldBase.cs @@ -39,6 +39,11 @@ namespace UnityEditor.VFX.UI m_View.blackboard.UpdateSelection(); } + public override void OnUnselected() + { + m_View.blackboard.UpdateSelection(); + } + protected virtual void OnMouseDown(MouseDownEvent evt) { if (evt.clickCount == 2 && evt.button == (int)MouseButton.LeftMouse) diff --git a/Packages/com.unity.visualeffectgraph/Editor/GraphView/Elements/Controllers/VFXParameterController.cs b/Packages/com.unity.visualeffectgraph/Editor/GraphView/Elements/Controllers/VFXParameterController.cs index d0fe3cde..52f94a45 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/GraphView/Elements/Controllers/VFXParameterController.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/GraphView/Elements/Controllers/VFXParameterController.cs @@ -159,15 +159,15 @@ namespace UnityEditor.VFX.UI } set { + object rootValue = m_Parameter.value; object val = m_Parameter.value; - List objectStack = new List(); foreach (var fieldInfo in m_FieldInfos.Take(m_FieldInfos.Length - 1)) { - objectStack.Add(fieldInfo.GetValue(val)); + val = fieldInfo.GetValue(val); + objectStack.Add(val); } - object targetValue = value; for (int i = objectStack.Count - 1; i >= 0; --i) { @@ -175,9 +175,8 @@ namespace UnityEditor.VFX.UI targetValue = objectStack[i]; } - m_FieldInfos[0].SetValue(val, targetValue); - - m_Parameter.value = val; + m_FieldInfos[0].SetValue(rootValue, targetValue); + m_Parameter.value = rootValue; } } } @@ -498,6 +497,7 @@ namespace UnityEditor.VFX.UI } } + members.Reverse(); foreach (var member in members) { subParameterController = subParameterController.children.FirstOrDefault(t => t.name == member); diff --git a/Packages/com.unity.visualeffectgraph/Editor/GraphView/Elements/VFXBlockUI.cs b/Packages/com.unity.visualeffectgraph/Editor/GraphView/Elements/VFXBlockUI.cs index 6766e4c4..827bbc47 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/GraphView/Elements/VFXBlockUI.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/GraphView/Elements/VFXBlockUI.cs @@ -67,10 +67,7 @@ namespace UnityEditor.VFX.UI private void OnDetachFromPanel(DetachFromPanelEvent evt) { var view = evt.originPanel.visualTree.Q(); - if (view != null) - { - UpdateHover(view, false); - } + view?.blackboard?.ClearAllAttributesHighlights(); } private void OnMouseHover(EventBase evt) @@ -93,7 +90,7 @@ namespace UnityEditor.VFX.UI private void UpdateHover(VFXView view, bool isHovered) { var blackboard = view.blackboard; - if (blackboard == null) + if (blackboard == null || controller.model == null) return; var attributes = controller.model is IVFXAttributeUsage attributeUsage diff --git a/Packages/com.unity.visualeffectgraph/Editor/GraphView/Views/Controller/VFXViewController.cs b/Packages/com.unity.visualeffectgraph/Editor/GraphView/Views/Controller/VFXViewController.cs index 93ff5de4..cbed3df2 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/GraphView/Views/Controller/VFXViewController.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/GraphView/Views/Controller/VFXViewController.cs @@ -682,11 +682,20 @@ namespace UnityEditor.VFX.UI public void RemoveElement(Controller element, bool explicitDelete = false) { + bool HasCustomAttributes(VFXModel model) + { + return model is IVFXAttributeUsage attributeUsage && + attributeUsage.usedAttributes.Any(x => graph.attributesManager.IsCustom(x.name)); + } + VFXModel removedModel = null; + bool needSyncCustomAttributes = false; + if (element is VFXContextController contextController) { VFXContext context = contextController.model; removedModel = context; + needSyncCustomAttributes = HasCustomAttributes(removedModel); contextController.NodeGoingToBeRemoved(); // Remove connections from context @@ -716,6 +725,7 @@ namespace UnityEditor.VFX.UI else if (element is VFXBlockController block) { removedModel = block.model; + needSyncCustomAttributes = HasCustomAttributes(removedModel); block.NodeGoingToBeRemoved(); block.contextController.RemoveBlock(block.model); @@ -724,6 +734,7 @@ namespace UnityEditor.VFX.UI else if (element is VFXParameterNodeController parameter) { removedModel = parameter.model; + needSyncCustomAttributes = HasCustomAttributes(removedModel); parameter.NodeGoingToBeRemoved(); parameter.parentController.model.RemoveNode(parameter.infos); RemoveFromGroupNodes(parameter); @@ -736,6 +747,7 @@ namespace UnityEditor.VFX.UI if (element is VFXNodeController nodeController) { removedModel = nodeController.model; + needSyncCustomAttributes = HasCustomAttributes(removedModel); container = removedModel as IVFXSlotContainer; nodeController.NodeGoingToBeRemoved(); RemoveFromGroupNodes(nodeController); @@ -743,6 +755,7 @@ namespace UnityEditor.VFX.UI else { removedModel = ((VFXParameterController)element).model; + needSyncCustomAttributes = HasCustomAttributes(removedModel); container = (IVFXSlotContainer)removedModel; foreach (var parameterNode in m_SyncedModels[removedModel]) { @@ -814,7 +827,7 @@ namespace UnityEditor.VFX.UI Debug.LogErrorFormat("Unexpected type : {0}", element.GetType().FullName); } - if (removedModel is IVFXAttributeUsage attributeUsage && attributeUsage.usedAttributes.Any(x => graph.attributesManager.IsCustom(x.name))) + if (needSyncCustomAttributes) { graph.SyncCustomAttributes(); } diff --git a/Packages/com.unity.visualeffectgraph/Editor/GraphView/Views/Properties/PropertyRM.cs b/Packages/com.unity.visualeffectgraph/Editor/GraphView/Views/Properties/PropertyRM.cs index 33c133ac..5564ff69 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/GraphView/Views/Properties/PropertyRM.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/GraphView/Views/Properties/PropertyRM.cs @@ -36,6 +36,10 @@ namespace UnityEditor.VFX.UI void EndLiveModification(); } + interface IVFXNotifyValueChanged : INotifyValueChanged + { + void SetValueWithoutNotify(T typedNewValue, bool force = false); + } class SimplePropertyRMProvider : IPropertyRMProvider { @@ -149,7 +153,7 @@ namespace UnityEditor.VFX.UI public float GetPreferredLabelWidth() { - if (hasLabel && this.Q